ir_to_mesa.cpp revision 2b7be12d5467096362073260911a380c64c772d0
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 * 29f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Translate GLSL IR to Mesa's gl_program representation. 3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 320161515c395c44233529c8d51f823b60050bc7baEric Anholt#include <stdio.h> 33261bbc011d11ab9e390cd5fe9f5151821eefaffaIan Romanick#include "main/compiler.h" 3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h" 3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h" 3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h" 3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h" 3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h" 39364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h" 40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h" 41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h" 42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h" 4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 44aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" { 450a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h" 46658e25987fbec3b826f500baa6d4d936b9552b13Eric Anholt#include "main/shaderapi.h" 47afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h" 48afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/uniforms.h" 49fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h" 50afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h" 51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h" 52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h" 53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h" 54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h" 55afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h" 56a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt#include "program/sampler.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 { 68caf974c5259f14b50257e8dd9b325a87378259afBrian Paul this->file = (gl_register_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 87caf974c5259f14b50257e8dd9b325a87378259afBrian Paul gl_register_file 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: 1087406898441bfec937840d575500fb6d43192310dEric Anholt /* Callers of this talloc-based new need not call delete. It's 1097406898441bfec937840d575500fb6d43192310dEric Anholt * easier to just talloc_free 'ctx' (or any of its ancestors). */ 1107406898441bfec937840d575500fb6d43192310dEric Anholt static void* operator new(size_t size, void *ctx) 1117406898441bfec937840d575500fb6d43192310dEric Anholt { 1127406898441bfec937840d575500fb6d43192310dEric Anholt void *node; 1137406898441bfec937840d575500fb6d43192310dEric Anholt 1147406898441bfec937840d575500fb6d43192310dEric Anholt node = talloc_zero_size(ctx, size); 1157406898441bfec937840d575500fb6d43192310dEric Anholt assert(node != NULL); 1167406898441bfec937840d575500fb6d43192310dEric Anholt 1177406898441bfec937840d575500fb6d43192310dEric Anholt return node; 1187406898441bfec937840d575500fb6d43192310dEric Anholt } 1197406898441bfec937840d575500fb6d43192310dEric Anholt 120554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op; 121554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst_reg; 122554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src_reg[3]; 123554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** Pointer to the ir source this tree came from for debugging */ 124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_instruction *ir; 125854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLboolean cond_update; 126ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt bool saturate; 127d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler; /**< sampler index */ 128d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int tex_target; /**< One of TEXTURE_*_INDEX */ 129b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt GLboolean tex_shadow; 1307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ 132554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 133554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 134b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node { 135554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 136caf974c5259f14b50257e8dd9b325a87378259afBrian Paul variable_storage(ir_variable *var, gl_register_file file, int index) 137554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt : file(file), index(index), var(var) 138554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt { 139554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /* empty */ 140554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt } 141554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 142caf974c5259f14b50257e8dd9b325a87378259afBrian Paul gl_register_file file; 143554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; 144554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_variable *var; /* variable that maps to this, if any */ 145554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 146554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node { 1487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic: 1497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig; 1507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * identifier of this function signature used by the program. 1537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * At the point that Mesa instructions for function calls are 1557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * generated, we don't know the address of the first instruction of 1567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * the function body. So we make the BranchTarget that is called a 1577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * small integer and rewrite them during set_branchtargets(). 1587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int sig_id; 1607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Pointer to first instruction of the function body. 1637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set during function body emits after main() is processed. 1657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *bgn_inst; 1677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Index of the first instruction of the function body in actual 1707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Mesa IR. 1717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set after convertion from ir_to_mesa_instruction to prog_instruction. 1737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int inst; 1757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** Storage for the return value. */ 1777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg return_reg; 1787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}; 1797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor { 181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_visitor(); 183fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt ~ir_to_mesa_visitor(); 184554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *current_function; 1867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 187f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx; 188364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 189aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt struct gl_shader_program *shader_program; 1906d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri struct gl_shader_compiler_options *options; 191364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 192554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int next_temp; 193a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 194b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *find_variable_storage(ir_variable *var); 195554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *get_function_signature(ir_function_signature *sig); 1977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1988364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt ir_to_mesa_src_reg get_temp(const glsl_type *type); 199f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt void reladdr_to_temp(ir_instruction *ir, 200f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr); 201554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 202554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg src_reg_for_float(float val); 203554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 205554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 212554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 213554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 215554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 216554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 217554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 218554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 219554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 220554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 222554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 223554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 224554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 225554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 22616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 227554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 228554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 229554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 230554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 231554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg result; 232554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 233b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 234b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 235554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 2377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 2387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 2397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 240554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 241554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 242554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 243021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir, 244021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op); 245021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 246554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir, 247554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 248554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 249554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 250554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 251554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir, 252554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 253554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 254554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 255554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1); 256554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 257554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir, 258554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 259554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 260554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 261554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1, 262554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src2); 263554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 264ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick /** 265ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick * Emit the correct dot-product instruction for the type of arguments 266ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick * 267ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick * \sa ir_to_mesa_emit_op2 268ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick */ 269ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick void ir_to_mesa_emit_dp(ir_instruction *ir, 270ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_dst_reg dst, 271ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_src_reg src0, 272ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_src_reg src1, 273ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick unsigned elements); 274ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 275554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt void ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 276554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 277554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 278554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 2790ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt 280904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt void ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 281904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 282904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 283904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0, 284904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1); 285904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 286f2616e56de8a48360cae8f269727b58490555f4dIan Romanick void emit_scs(ir_instruction *ir, enum prog_opcode op, 287f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_dst_reg dst, 288f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const ir_to_mesa_src_reg &src); 289f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 2903f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt GLboolean try_emit_mad(ir_expression *ir, 2913f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 292ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt GLboolean try_emit_sat(ir_expression *ir); 2933f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 29411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick void emit_swz(ir_expression *ir); 29511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 296c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool process_move_condition(ir_rvalue *ir); 297c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 29834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt void copy_propagate(void); 29934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 300364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 301554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 302554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 3039c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL); 30484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 305c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = { 306f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL, 307c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}; 308c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 3090161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = { 310f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL 3110161515c395c44233529c8d51f823b60050bc7baEric Anholt}; 3120161515c395c44233529c8d51f823b60050bc7baEric Anholt 313f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulstatic void 314f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulfail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); 315500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt 316f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulstatic void 317f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulfail_link(struct gl_shader_program *prog, const char *fmt, ...) 318f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul{ 319f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul va_list args; 320f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul va_start(args, fmt); 321f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul prog->InfoLog = talloc_vasprintf_append(prog->InfoLog, fmt, args); 322f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul va_end(args); 323500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt 324f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul prog->LinkStatus = GL_FALSE; 325f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul} 326500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt 327f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulstatic int 328f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulswizzle_for_size(int size) 3290161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 3300161515c395c44233529c8d51f823b60050bc7baEric Anholt int size_swizzles[4] = { 3310161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 3320161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 3330161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 3340161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 3350161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 3360161515c395c44233529c8d51f823b60050bc7baEric Anholt 3379fea9e5e2115bcb52435648d2ef753638733d7d9Ian Romanick assert((size >= 1) && (size <= 4)); 3380161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 3390161515c395c44233529c8d51f823b60050bc7baEric Anholt} 3400161515c395c44233529c8d51f823b60050bc7baEric Anholt 34184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3420161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir, 3430161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3440161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3450161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 3460161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1, 3470161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src2) 34884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 349364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 350f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 351f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 352f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 353f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 354f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 355f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 356f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 357f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 358f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 359f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 360f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 361f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 362f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 363f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 364f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 365f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 366f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, 367f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *dst.reladdr); 368f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 369f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 370f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 371f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 37284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 37384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 37484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->dst_reg = dst; 37584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[0] = src0; 37684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[1] = src1; 37784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[2] = src2; 378c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 37984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function = NULL; 3817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3820161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 38384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 38584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 38684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3890161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir, 3900161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3910161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3920161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 3930161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1) 39484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3950161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef); 39684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 39784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3990161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir, 4000161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 4010161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 4020161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0) 403bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 4045a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(dst.writemask != 0); 4050161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, 4060161515c395c44233529c8d51f823b60050bc7baEric Anholt src0, ir_to_mesa_undef, ir_to_mesa_undef); 407bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 408bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 409021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 410021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir, 411021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op) 412021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 413021222c6a872ca2eef770ebadb8754f659775204Eric Anholt return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst, 414021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 415021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 416021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef); 417021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 418021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 419ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanickvoid 420ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanickir_to_mesa_visitor::ir_to_mesa_emit_dp(ir_instruction *ir, 421ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_dst_reg dst, 422ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_src_reg src0, 423ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_src_reg src1, 424ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick unsigned elements) 425ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick{ 426ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick static const gl_inst_opcode dot_opcodes[] = { 427ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick OPCODE_DP2, OPCODE_DP3, OPCODE_DP4 428ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick }; 429ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 430ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_emit_op3(ir, dot_opcodes[elements - 2], 431ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick dst, src0, src1, ir_to_mesa_undef); 432ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick} 433ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 4340161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg 4350161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg) 43684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 4370161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst_reg; 43884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 4390161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.file = reg.file; 4400161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.index = reg.index; 4410161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.writemask = WRITEMASK_XYZW; 442854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt dst_reg.cond_mask = COND_TR; 443f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt dst_reg.reladdr = reg.reladdr; 4440161515c395c44233529c8d51f823b60050bc7baEric Anholt 4450161515c395c44233529c8d51f823b60050bc7baEric Anholt return dst_reg; 446bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 447bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 4482d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg 4492d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg) 4502d1789e667c4180777829f96856daf91326721b9Eric Anholt{ 4519c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt return ir_to_mesa_src_reg(reg.file, reg.index, NULL); 4522d1789e667c4180777829f96856daf91326721b9Eric Anholt} 4532d1789e667c4180777829f96856daf91326721b9Eric Anholt 45412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 45512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 45612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 45712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 45812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 45912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 46012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 46112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 46212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 463904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 4640161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 4650161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 466904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src0, 467904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src1) 46812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 46912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 470315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 47112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 47212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 47312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 47412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 47512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 47612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 477582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 47812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 479904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0 = orig_src0; 480904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1 = orig_src1; 48112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 48212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 48312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 48412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 485904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 486904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 48712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 488f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 489f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 490f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 491f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 492904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 493904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 494904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 49512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 49612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 49712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 498904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 499904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 500904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 501904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 50212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 503904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt inst = ir_to_mesa_emit_op2(ir, op, 5040161515c395c44233529c8d51f823b60050bc7baEric Anholt dst, 505904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0, 506904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1); 50712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt inst->dst_reg.writemask = this_mask; 50812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 50912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 51012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 51112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 512904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 513904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 514904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 515904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 516904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0) 517904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 51859a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt ir_to_mesa_src_reg undef = ir_to_mesa_undef; 519904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 520904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 521904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 522904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef); 523904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 524904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 525f2616e56de8a48360cae8f269727b58490555f4dIan Romanick/** 526f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Emit an OPCODE_SCS instruction 527f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 528f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * The \c SCS opcode functions a bit differently than the other Mesa (or 529f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * ARB_fragment_program) opcodes. Instead of splatting its result across all 530f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * four components of the destination, it writes one value to the \c x 531f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * component and another value to the \c y component. 532f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 533f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param ir IR instruction being processed 534f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which 535f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * value is desired. 536f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param dst Destination register 537f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param src Source register 538f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 539f2616e56de8a48360cae8f269727b58490555f4dIan Romanickvoid 540f2616e56de8a48360cae8f269727b58490555f4dIan Romanickir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op, 541f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_dst_reg dst, 542f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const ir_to_mesa_src_reg &src) 543f2616e56de8a48360cae8f269727b58490555f4dIan Romanick{ 544f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Vertex programs cannot use the SCS opcode. 545f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 546f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 547f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_emit_scalar_op1(ir, op, dst, src); 548f2616e56de8a48360cae8f269727b58490555f4dIan Romanick return; 549f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 550f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 551f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned component = (op == OPCODE_SIN) ? 0 : 1; 552f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned scs_mask = (1U << component); 553f2616e56de8a48360cae8f269727b58490555f4dIan Romanick int done_mask = ~dst.writemask; 554f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_src_reg tmp; 555f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 556f2616e56de8a48360cae8f269727b58490555f4dIan Romanick assert(op == OPCODE_SIN || op == OPCODE_COS); 557f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 558f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there are compnents in the destination that differ from the component 559f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * that will be written by the SCS instrution, we'll need a temporary. 560f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 561f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (scs_mask != unsigned(dst.writemask)) { 562f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp = get_temp(glsl_type::vec4_type); 563f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 564f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 565f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned i = 0; i < 4; i++) { 566f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned this_mask = (1U << i); 567f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_src_reg src0 = src; 568f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 569f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if ((done_mask & this_mask) != 0) 570f2616e56de8a48360cae8f269727b58490555f4dIan Romanick continue; 571f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 572f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* The source swizzle specified which component of the source generates 573f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * sine / cosine for the current component in the destination. The SCS 574f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * instruction requires that this value be swizzle to the X component. 575f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Replace the current swizzle with a swizzle that puts the source in 576f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the X component. 577f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 578f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned src0_swiz = GET_SWZ(src.swizzle, i); 579f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 580f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 581f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0_swiz, src0_swiz); 582f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned j = i + 1; j < 4; j++) { 583f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 584f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 585f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 586f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 587f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (!(done_mask & (1 << j)) && 588f2616e56de8a48360cae8f269727b58490555f4dIan Romanick GET_SWZ(src0.swizzle, j) == src0_swiz) { 589f2616e56de8a48360cae8f269727b58490555f4dIan Romanick this_mask |= (1 << j); 590f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 591f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 592f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 593f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this_mask != scs_mask) { 594f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_instruction *inst; 595f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_dst_reg tmp_dst = ir_to_mesa_dst_reg_from_src(tmp); 596f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 597f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction. 598f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 599f2616e56de8a48360cae8f269727b58490555f4dIan Romanick inst = ir_to_mesa_emit_op1(ir, OPCODE_SCS, tmp_dst, src0); 600f2616e56de8a48360cae8f269727b58490555f4dIan Romanick inst->dst_reg.writemask = scs_mask; 601f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 602f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Move the result of the SCS instruction to the desired location in 603f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the destination. 604f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 605f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp.swizzle = MAKE_SWIZZLE4(component, component, 606f2616e56de8a48360cae8f269727b58490555f4dIan Romanick component, component); 607f2616e56de8a48360cae8f269727b58490555f4dIan Romanick inst = ir_to_mesa_emit_op1(ir, OPCODE_SCS, dst, tmp); 608f2616e56de8a48360cae8f269727b58490555f4dIan Romanick inst->dst_reg.writemask = this_mask; 609f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } else { 610f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction to write directly to the destination. 611f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 612f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_instruction *inst = 613f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_emit_op1(ir, OPCODE_SCS, dst, src0); 614f2616e56de8a48360cae8f269727b58490555f4dIan Romanick inst->dst_reg.writemask = scs_mask; 615f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 616f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 617f2616e56de8a48360cae8f269727b58490555f4dIan Romanick done_mask |= this_mask; 618f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 619f2616e56de8a48360cae8f269727b58490555f4dIan Romanick} 620f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 6210161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg 6220161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 623b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 6249c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL); 6251d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 626582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 627582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt &val, 1, &src_reg.swizzle); 6281d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 6290161515c395c44233529c8d51f823b60050bc7baEric Anholt return src_reg; 6301d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 6311d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 6322c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 6332c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 6342c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 6352c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 6362c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 6372c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 6382c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 6392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 6402c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 6412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 6422c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 643a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 6449968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 645a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 646a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 647a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 648a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 649a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 650a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 651a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 652a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 6532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 6545c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick assert(type->length > 0); 6552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 6562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 6572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 6582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 6592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 6602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 6628d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt case GLSL_TYPE_SAMPLER: 6630924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Samplers take up one slot in UNIFORMS[], but they're baked in 6640924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * at link time. 6658d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt */ 6660924ba0c3496160a134d37cec800f902ae805b9cEric Anholt return 1; 6672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 6682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 66919acfa42ed47edb63f5ec3de8051a3102e62e96bJosé Fonseca return 0; 6702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 6722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 673d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 674d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 675d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 676d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 677d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 678d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 679d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg 680d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 681d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 682d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt ir_to_mesa_src_reg src_reg; 683d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int swizzle[4]; 684d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int i; 685d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 686d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.file = PROGRAM_TEMPORARY; 687d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.index = next_temp; 688f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 689d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 690d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 69120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (type->is_array() || type->is_record()) { 69220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.swizzle = SWIZZLE_NOOP; 69320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } else { 69420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < type->vector_elements; i++) 69520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[i] = i; 69620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (; i < 4; i++) 69720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[i] = type->vector_elements - 1; 69820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], 69920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[2], swizzle[3]); 70020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 701ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt src_reg.negate = 0; 702d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 703d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt return src_reg; 704d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 705d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 706b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 707a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 70884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 709a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 710b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 712b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 713b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 71484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 7150161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 716a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 71784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 71884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 719a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 720a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 72184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 72284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 72384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 72484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 7254a962170d7cf4243d6ae156fca20a6167388925dEric Anholt if (strcmp(ir->name, "gl_FragCoord") == 0) { 7264a962170d7cf4243d6ae156fca20a6167388925dEric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 7274a962170d7cf4243d6ae156fca20a6167388925dEric Anholt 7284a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->OriginUpperLeft = ir->origin_upper_left; 7294a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->PixelCenterInteger = ir->pixel_center_integer; 730a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace 731a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace } else if (strcmp(ir->name, "gl_FragDepth") == 0) { 732a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 733a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace switch (ir->depth_layout) { 734a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_none: 735a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE; 736a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 737a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_any: 738a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY; 739a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 740a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_greater: 741a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER; 742a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 743a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_less: 744a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS; 745a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 746a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_unchanged: 747a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED; 748a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 749a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace default: 750a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace assert(0); 751a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 752a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace } 7534a962170d7cf4243d6ae156fca20a6167388925dEric Anholt } 7546c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7556c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 7566c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt unsigned int i; 757daacaac3c8b91c87ab2cfc2d9f821474552b8181Eric Anholt const struct gl_builtin_uniform_desc *statevar; 7586c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 759daacaac3c8b91c87ab2cfc2d9f821474552b8181Eric Anholt for (i = 0; _mesa_builtin_uniform_desc[i].name; i++) { 760daacaac3c8b91c87ab2cfc2d9f821474552b8181Eric Anholt if (strcmp(ir->name, _mesa_builtin_uniform_desc[i].name) == 0) 7616c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt break; 7626c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7636c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 764daacaac3c8b91c87ab2cfc2d9f821474552b8181Eric Anholt if (!_mesa_builtin_uniform_desc[i].name) { 7656c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt fail_link(this->shader_program, 7666c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt "Failed to find builtin uniform `%s'\n", ir->name); 7676c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt return; 7686c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7696c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 770daacaac3c8b91c87ab2cfc2d9f821474552b8181Eric Anholt statevar = &_mesa_builtin_uniform_desc[i]; 7716c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7726c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt int array_count; 7736c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (ir->type->is_array()) { 7746c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt array_count = ir->type->length; 7756c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 7766c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt array_count = 1; 7776c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7786c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7796c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* Check if this statevar's setup in the STATE file exactly 7806c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * matches how we'll want to reference it as a 7816c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * struct/array/whatever. If not, then we need to move it into 7826c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * temporary storage and hope that it'll get copy-propagated 7836c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * out. 7846c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt */ 7856c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt for (i = 0; i < statevar->num_elements; i++) { 7866c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (statevar->elements[i].swizzle != SWIZZLE_XYZW) { 7876c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt break; 7886c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7896c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7906c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7916c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt struct variable_storage *storage; 7926c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt ir_to_mesa_dst_reg dst; 7936c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (i == statevar->num_elements) { 7946c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* We'll set the index later. */ 7956c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 7966c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 7976c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7986c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt dst = ir_to_mesa_undef_dst; 7996c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 8006c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 8016c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp); 8026c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 8036c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp += type_size(ir->type); 8046c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 8056c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt dst = ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg(PROGRAM_TEMPORARY, 8066c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage->index, 8076c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt NULL)); 8086c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 8096c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 8106c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 8116c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt for (int a = 0; a < array_count; a++) { 8126c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt for (unsigned int i = 0; i < statevar->num_elements; i++) { 813daacaac3c8b91c87ab2cfc2d9f821474552b8181Eric Anholt struct gl_builtin_uniform_element *element = &statevar->elements[i]; 8146c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt int tokens[STATE_LENGTH]; 8156c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 8166c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt memcpy(tokens, element->tokens, sizeof(element->tokens)); 8176c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (ir->type->is_array()) { 8186c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt tokens[1] = a; 8196c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 8206c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 8216c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt int index = _mesa_add_state_reference(this->prog->Parameters, 8226c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt (gl_state_index *)tokens); 8236c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 8246c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (storage->file == PROGRAM_STATE_VAR) { 8256c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (storage->index == -1) { 8266c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage->index = index; 8276c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 8287545514fb65f807fa2c888954f0ac153a918e2ceBrian Paul assert(index == 8297545514fb65f807fa2c888954f0ac153a918e2ceBrian Paul (int)(storage->index + a * statevar->num_elements + i)); 8306c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 8316c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 8326c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt ir_to_mesa_src_reg src(PROGRAM_STATE_VAR, index, NULL); 8336c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt src.swizzle = element->swizzle; 8346c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, dst, src); 8356c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* even a float takes up a whole vec4 reg in a struct/array. */ 8366c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt dst.index++; 8376c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 8386c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 8396c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 8406c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (storage->file == PROGRAM_TEMPORARY && 8416c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt dst.index != storage->index + type_size(ir->type)) { 8426c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt fail_link(this->shader_program, 8436c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", 8446c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt ir->name, dst.index - storage->index, 8456c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt type_size(ir->type)); 8466c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 8476c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 84884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 84984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 85084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 85184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 85284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 8530f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_dereference_variable *counter = NULL; 8540f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8550f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->counter != NULL) 8560f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick counter = new(ir) ir_dereference_variable(ir->counter); 8570f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8580f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->from != NULL) { 8590f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick assert(ir->counter != NULL); 8600f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8610f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); 8620f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8630f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 8640f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick delete a; 8650f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 86684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 867021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); 8680f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8690f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->to) { 8700f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 8710f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick new(ir) ir_expression(ir->cmp, glsl_type::bool_type, 8720f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick counter, ir->to); 8730f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_if *if_stmt = new(ir) ir_if(e); 8740f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8750f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); 8760f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8770f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->then_instructions.push_tail(brk); 8780f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8790f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->accept(this); 8800f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8810f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick delete if_stmt; 8820f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick delete e; 8830f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick delete brk; 8840f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 8850f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 88664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 8870f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8880f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->increment) { 8890f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 8900f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick new(ir) ir_expression(ir_binop_add, counter->type, 8910f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick counter, ir->increment); 8920f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8930f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); 8940f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8950f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 8960f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick delete a; 8970f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick delete e; 8980f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 8990f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 900021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); 90184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 90284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 90384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 90484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 90584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 90664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 90764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 908021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BRK); 90964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 91064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 911021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_CONT); 91264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 91364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 91484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 91584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 91684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 91784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 91884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 91984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 92184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 92284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 92384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 92484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 92584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 92684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 92784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 93184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 93284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 93384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 93484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 93684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 93784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 93884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 93984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 94184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 94284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 94384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9463f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean 9473f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 9483f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 9493f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 9503f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_src_reg a, b, c; 9513f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 9523f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 9533f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 9543f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 9553f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 9563f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 9573f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 9583f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 9593f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 9603f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 9613f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 9623f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 9633f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 9643f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_emit_op3(ir, OPCODE_MAD, 9653f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_dst_reg_from_src(this->result), a, b, c); 9663f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 9673f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 9683f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 9693f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 970ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric AnholtGLboolean 971ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholtir_to_mesa_visitor::try_emit_sat(ir_expression *ir) 972ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt{ 973ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt /* Saturates were only introduced to vertex programs in 974ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt * NV_vertex_program3, so don't give them to drivers in the VP. 975ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt */ 976ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 977ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 978ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 979ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 980ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (!sat_src) 981ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 982ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 983ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt sat_src->accept(this); 984ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt ir_to_mesa_src_reg src = this->result; 985ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 986ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt this->result = get_temp(ir->type); 987ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt ir_to_mesa_instruction *inst; 988ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt inst = ir_to_mesa_emit_op1(ir, OPCODE_MOV, 989ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt ir_to_mesa_dst_reg_from_src(this->result), 990ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt src); 991ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt inst->saturate = true; 992ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 993ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return true; 994ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt} 995ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 99684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 997f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 998f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr) 999f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 1000f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 1001f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 1002f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 1003f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr); 1004f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 1005f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 1006f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 1007f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 1008f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, 1009f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_dst_reg_from_src(temp), *reg); 1010f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 1011f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 1012f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 1013f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 1014f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 1015f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 1016f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 101711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickir_to_mesa_visitor::emit_swz(ir_expression *ir) 101811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick{ 101911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Assume that the vector operator is in a form compatible with OPCODE_SWZ. 102011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This means that each of the operands is either an immediate value of -1, 102111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * 0, or 1, or is a component from one source register (possibly with 102211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * negation). 102311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 102411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick uint8_t components[4] = { 0 }; 102511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick bool negate[4] = { false }; 102611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_variable *var = NULL; 102711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick for (unsigned i = 0; i < ir->type->vector_elements; i++) { 102911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_rvalue *op = ir->operands[i]; 103011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 103211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick while (op != NULL) { 103411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick switch (op->ir_type) { 103511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_constant: { 103611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 103811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick const ir_constant *const c = op->as_constant(); 104011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (c->is_one()) { 104111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 104211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_zero()) { 104311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ZERO; 104411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_negative_one()) { 104511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 104611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 104711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else { 104811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"SWZ constant must be 0.0 or 1.0."); 104911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 105011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 105211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 105311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 105411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_dereference_variable: { 105611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 105711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick (ir_dereference_variable *) op; 105811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert((var == NULL) || (deref->var == var)); 106011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_X; 106111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick var = deref->var; 106211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 106311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 106411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 106511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_expression: { 106711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_expression *const expr = (ir_expression *) op; 106811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(expr->operation == ir_unop_neg); 107011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 107111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = expr->operands[0]; 107311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 107411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 107511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_swizzle: { 107711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_swizzle *const swiz = (ir_swizzle *) op; 107811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = swiz->mask.x; 108011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = swiz->val; 108111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 108211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 108311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 108411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick default: 108511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 108611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 108711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 108811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 108911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 109011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 109111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(var != NULL); 109211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 109311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 109411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick new(mem_ctx) ir_dereference_variable(var); 109511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 109611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result.file = PROGRAM_UNDEFINED; 109711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(this); 109811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (this->result.file == PROGRAM_UNDEFINED) { 109911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_print_visitor v; 110011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick printf("Failed to get tree for expression operand:\n"); 110111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(&v); 110211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick exit(1); 110311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 110411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 110511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_to_mesa_src_reg src; 110611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 110711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src = this->result; 110811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.swizzle = MAKE_SWIZZLE4(components[0], 110911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[1], 111011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[2], 111111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[3]); 111211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.negate = ((unsigned(negate[0]) << 0) 111311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[1]) << 1) 111411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[2]) << 2) 111511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[3]) << 3)); 111611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 111711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Storage for our result. Ideally for an assignment we'd be using the 111811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * actual storage for the result here, instead. 111911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 112011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick const ir_to_mesa_src_reg result_src = get_temp(ir->type); 112111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_to_mesa_dst_reg result_dst = ir_to_mesa_dst_reg_from_src(result_src); 112211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 112311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Limit writes to the channels that will be used by result_src later. 112411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This does limit this temp's use as a temporary for multi-instruction 112511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * sequences. 112611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 112711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick result_dst.writemask = (1 << ir->type->vector_elements) - 1; 112811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 112911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_to_mesa_emit_op1(ir, OPCODE_SWZ, result_dst, src); 113011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result = result_src; 113111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick} 113211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 113311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickvoid 113484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 113584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 113684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 1137fc92e87b9757eda01caf0bb3e2c31b1dbbd73aa0Ian Romanick struct ir_to_mesa_src_reg op[Elements(ir->operands)]; 11380161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg result_src; 11390161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg result_dst; 114084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 11413f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 11423f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 11433f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 11443f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 11453f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11463f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 11473f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11483f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 1149ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (try_emit_sat(ir)) 1150ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return; 11513f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 115211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (ir->operation == ir_quadop_vector) { 115311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->emit_swz(ir); 115411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 115511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 115611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 115784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 11580161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 115984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 11600161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 116184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 116284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 116384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 116484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 116584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 116684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 11678364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 11684ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 11694ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 11704ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 11714ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 117284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 117384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1174eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt int vector_elements = ir->operands[0]->type->vector_elements; 1175eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt if (ir->operands[1]) { 1176eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt vector_elements = MAX2(vector_elements, 1177eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt ir->operands[1]->type->vector_elements); 1178eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt } 1179eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt 11800161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 11810161515c395c44233529c8d51f823b60050bc7baEric Anholt 11820161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 11830161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 11840161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 11858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 11860161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 11870161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 11889cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 11899cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 11909cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 11919cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 11929cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 119384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 119484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 11951d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 1196f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, 1197f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt op[0], src_reg_for_float(0.0)); 11981d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1199c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 12000161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 12010161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 1202c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 1203524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 1204524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]); 1205524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 12063acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 12073acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]); 12083acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 12098761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 12108761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]); 12118761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 1212524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 12138c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 12140161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]); 12158c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 1216bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt case ir_unop_exp: 12178c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 1218bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 12198c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 12208c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 12210161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]); 12228c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 12233c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 12240161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]); 12253c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 12263c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 12270161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]); 12283c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 1229f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_sin_reduced: 1230f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_SIN, result_dst, op[0]); 1231f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1232f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_cos_reduced: 1233f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_COS, result_dst, op[0]); 1234f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1235ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 1236ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 1237ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]); 1238ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1239ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 1240ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]); 1241ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1242ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 12433a5ce85cfa4914711e56c8cf831699242618928eIan Romanick case ir_unop_noise: { 12443a5ce85cfa4914711e56c8cf831699242618928eIan Romanick const enum prog_opcode opcode = 12453a5ce85cfa4914711e56c8cf831699242618928eIan Romanick prog_opcode(OPCODE_NOISE1 12463a5ce85cfa4914711e56c8cf831699242618928eIan Romanick + (ir->operands[0]->type->vector_elements) - 1); 12473a5ce85cfa4914711e56c8cf831699242618928eIan Romanick assert((opcode >= OPCODE_NOISE1) && (opcode <= OPCODE_NOISE4)); 12483a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 12493a5ce85cfa4914711e56c8cf831699242618928eIan Romanick ir_to_mesa_emit_op1(ir, opcode, result_dst, op[0]); 12503a5ce85cfa4914711e56c8cf831699242618928eIan Romanick break; 12513a5ce85cfa4914711e56c8cf831699242618928eIan Romanick } 12523a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 125384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 12547b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]); 125584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 125684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 12577b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]); 125884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 12599b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 126084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 12614ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]); 126284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 126384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 12649a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1265411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 1266411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 1267411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 126838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 126938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 1270f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]); 127138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 1273f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]); 127438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 1276f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]); 127738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 1279f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); 128038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 128138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 12824dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 12834dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12844dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_nequal: 12854dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 12864dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12874dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_all_equal: 12886992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "==" operator producing a scalar boolean. */ 12896992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 12906992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 12916992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 12926992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 12936992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); 1294ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements); 12956992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, 12966992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt result_dst, result_src, src_reg_for_float(0.0)); 12976992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 12986992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 12996992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 130038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 13014dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_any_nequal: 13026992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "!=" operator producing a scalar boolean. */ 13036992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 13046992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 13056992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 13066992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 13076992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); 1308ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements); 13096992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 13106992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt result_dst, result_src, src_reg_for_float(0.0)); 13116992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 13126992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 13136992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 13146992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt break; 13155e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 13165e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt case ir_unop_any: 1317ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 1318ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_emit_dp(ir, result_dst, op[0], op[0], 1319ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir->operands[0]->type->vector_elements); 13205e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 13215e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt result_dst, result_src, src_reg_for_float(0.0)); 13225e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 13235e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 13246992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt case ir_binop_logic_xor: 1325f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 132638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 132738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 13284380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_or: 13290161515c395c44233529c8d51f823b60050bc7baEric Anholt /* This could be a saturated add and skip the SNE. */ 13300161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, 13310161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 13320161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 13330161515c395c44233529c8d51f823b60050bc7baEric Anholt 13340161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 13350161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 13360161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 13374380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 13384380099c98119611ceee684669d00be26195c7d7Eric Anholt 13394380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 13404380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 13410161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 13420161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 13430161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 13444380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 13454380099c98119611ceee684669d00be26195c7d7Eric Anholt 134684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 1347ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 1348ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type == ir->operands[1]->type); 1349ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir_to_mesa_emit_dp(ir, result_dst, op[0], op[1], 1350ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick ir->operands[0]->type->vector_elements); 135184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 13529be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 135384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 13544f189b3bf57a6500953dac49105f160af5fa6468Marek Olšák /* sqrt(x) = x * rsq(x). */ 13550161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 13564f189b3bf57a6500953dac49105f160af5fa6468Marek Olšák ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, result_src, op[0]); 1357c9039fdb167865547dc9b3828d69b99209344999Brian Paul /* For incoming channels <= 0, set the result to 0. */ 1358c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0].negate = ~op[0].negate; 13598f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst, 1360c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0], result_src, src_reg_for_float(0.0)); 136184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 1362878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 13630161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 1364878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 136550ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 1366d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 1367d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 1368423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 13690161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 137050ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 1371423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 13720161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 1373423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 13741d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 1375411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 13760161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, 137766afcb560771b6ba6ad668156e9f442e86b9a7a2Eric Anholt op[0], src_reg_for_float(0.0)); 13781d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1379c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 13800161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 1381c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1382c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 13830161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 13840161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 13850161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 1386c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1387c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 13880161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 1389c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1390d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 1391d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]); 1392d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 1393d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 1394c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 13950161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]); 1396c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1397c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 13980161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]); 1399c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1400904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 1401904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]); 1402904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 1403e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 1404e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_bit_not: 1405e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_u2f: 1406e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 1407e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 1408e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 1409e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 1410e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 1411d85d25dd1f4fd281bd210ba6ba5135ba1e3b535fKenneth Graunke case ir_unop_round_even: 1412e64a4aaacbc682f24180dff3627b84861844476dEric Anholt assert(!"GLSL 1.30 features unsupported"); 1413e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 141411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 141511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_quadop_vector: 141611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* This operation should have already been handled. 141711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 141811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 141911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 142084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 1421b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 14220161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 142384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 142484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 142584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 142684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 142784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 142884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 14290161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 143084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 143184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 143284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1433b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 1434b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 1435b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 1436b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 143784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 143884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 14394006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt src_reg = this->result; 14404006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt assert(src_reg.file != PROGRAM_UNDEFINED); 144184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 144284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 144384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 144484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 144584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 1446698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x); 144784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 144884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 1449698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y); 145084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 145184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 1452698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z); 145384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 145484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 1455698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w); 145684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 145784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 145884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 145984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 146084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 146184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 1462698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 146384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 146484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 146584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14660161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], 14670161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[1], 14680161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[2], 14690161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[3]); 147084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14710161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 147284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 147384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 147484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 147584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 147684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1477b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 1478304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul ir_variable *var = ir->var; 147984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14808364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1481304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul switch (var->mode) { 14828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 1483304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1484304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul var->location); 1485b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 14868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 14878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 14888364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1489a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1490a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * including deprecated builtins (like gl_Color), user-assign 1491a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * generic attributes (glBindVertexLocation), and 1492a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * user-defined varyings. 1493a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1494a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1495f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1496304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul assert(var->location != -1); 14972b7be12d5467096362073260911a380c64c772d0Brian Paul entry = new(mem_ctx) variable_storage(var, 14982b7be12d5467096362073260911a380c64c772d0Brian Paul PROGRAM_INPUT, 14992b7be12d5467096362073260911a380c64c772d0Brian Paul var->location); 15002b7be12d5467096362073260911a380c64c772d0Brian Paul if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && 15012b7be12d5467096362073260911a380c64c772d0Brian Paul var->location >= VERT_ATTRIB_GENERIC0) { 15022b7be12d5467096362073260911a380c64c772d0Brian Paul _mesa_add_attribute(prog->Attributes, 15032b7be12d5467096362073260911a380c64c772d0Brian Paul var->name, 15042b7be12d5467096362073260911a380c64c772d0Brian Paul _mesa_sizeof_glsl_type(var->type->gl_type), 15052b7be12d5467096362073260911a380c64c772d0Brian Paul var->type->gl_type, 15062b7be12d5467096362073260911a380c64c772d0Brian Paul var->location - VERT_ATTRIB_GENERIC0); 150786471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul } 150886471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul break; 150986471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul case ir_var_out: 151086471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul assert(var->location != -1); 151186471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul entry = new(mem_ctx) variable_storage(var, 151286471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul PROGRAM_OUTPUT, 151386471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul var->location); 15148364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 15157baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul case ir_var_system_value: 15167baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul entry = new(mem_ctx) variable_storage(var, 15177baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul PROGRAM_SYSTEM_VALUE, 15187baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul var->location); 15197baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul break; 15208364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 15217e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1522304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1523b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1524b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1525224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 1526304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul next_temp += type_size(var->type); 15278364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 152884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 15298364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 15308364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1531304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul printf("Failed to make storage for %s\n", var->name); 15328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1533224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 153484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 153584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1536304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul this->result = ir_to_mesa_src_reg(entry->file, entry->index, var->type); 153784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 153884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 153984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 154084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 154184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1542ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 15430161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 15448258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1545ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1546ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 15474e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 1548ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 15490161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg = this->result; 15504e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 15514d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 15524d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.index += index->value.i[0] * element_size; 15534e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 15544d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg array_base = this->result; 15554d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 15564d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 15574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 15584d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 15594d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 15608258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 15614d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg index_reg; 15628258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 15634d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 15644d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 15654d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 15664d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1567f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 15684d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 15694d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 15704d5da50b94115d055ba8d0ff8717054582665384Eric Anholt this->result, src_reg_for_float(element_size)); 1571bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 15724d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 15734d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 15744d5da50b94115d055ba8d0ff8717054582665384Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 15754e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 157684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 157784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 157885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 157985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); 158085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 158185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = SWIZZLE_NOOP; 158284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15830161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 158484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 158584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15862c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 15872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 15882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 15892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 15900161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 15912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 15922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 15930161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 15942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 15952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 15960161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 15972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 15982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 15992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 16002d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16012d577ee730c30caacf711babde6542766aa0b655Ian Romanick /* If the type is smaller than a vec4, replicate the last channel out. */ 16022d577ee730c30caacf711babde6542766aa0b655Ian Romanick if (ir->type->is_scalar() || ir->type->is_vector()) 16032d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 16042d577ee730c30caacf711babde6542766aa0b655Ian Romanick else 16052d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = SWIZZLE_NOOP; 16062d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16070161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 16082c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 16092c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16102c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 16112c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 16122c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 16132c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 16142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 16150161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg 1616fc63e37b971b641dfdff000ba353c4810414c20eIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v) 1617b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 16185a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* The LHS must be a dereference. If the LHS is a variable indexed array 16195a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * access of a vector, it must be separated into a series conditional moves 16205a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * before reaching this point (see ir_vec_index_to_cond_assign). 16215a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 16225a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->as_dereference()); 1623ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1624ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1625ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1626ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1627ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 16280161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 16290161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 16300161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 16312c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 16325a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick return ir_to_mesa_dst_reg_from_src(v->result); 1633cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1634cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1635c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick/** 1636c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Process the condition of a conditional assignment 1637c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1638c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Examines the condition of a conditional assignment to generate the optimal 1639c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * first operand of a \c CMP instruction. If the condition is a relational 1640c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 1641c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * used as the source for the \c CMP instruction. Otherwise the comparison 1642c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * is processed to a boolean result, and the boolean result is used as the 1643c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operand to the CMP instruction. 1644c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1645c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickbool 1646c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) 1647c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick{ 1648c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_rvalue *src_ir = ir; 1649c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool negate = true; 1650c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool switch_order = false; 1651c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1652c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_expression *const expr = ir->as_expression(); 1653c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if ((expr != NULL) && (expr->get_num_operands() == 2)) { 1654c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool zero_on_left = false; 1655c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1656c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (expr->operands[0]->is_zero()) { 1657c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[1]; 1658c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = true; 1659c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else if (expr->operands[1]->is_zero()) { 1660c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[0]; 1661c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = false; 1662c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1663c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1664c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* a is - 0 + - 0 + 1665c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a < 0) T F F ( a < 0) T F F 1666c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 < a) F F T (-a < 0) F F T 1667c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 1668c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 1669c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a > 0) F F T (-a < 0) F F T 1670c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 > a) T F F ( a < 0) T F F 1671c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 1672c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 1673c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1674c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Note that exchanging the order of 0 and 'a' in the comparison simply 1675c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * means that the value of 'a' should be negated. 1676c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1677c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (src_ir != ir) { 1678c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch (expr->operation) { 1679c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_less: 1680c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1681c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1682c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1683c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1684c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_greater: 1685c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1686c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1687c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1688c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1689c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_lequal: 1690c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1691c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1692c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1693c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1694c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_gequal: 1695c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1696c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1697c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1698c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1699c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick default: 1700c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* This isn't the right kind of comparison afterall, so make sure 1701c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * the whole condition is visited. 1702c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1703c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = ir; 1704c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1705c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1706c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1707c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1708c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1709c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir->accept(this); 1710c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1711c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 1712c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * condition we produced is 0.0 or 1.0. By flipping the sign, we can 1713c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * choose which value OPCODE_CMP produces without an extra instruction 1714c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * computing the condition. 1715c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1716c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (negate) 1717c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick this->result.negate = ~this->result.negate; 1718c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1719c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick return switch_order; 1720c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick} 1721c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 172284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 172384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 172484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 17250161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg l; 17260161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg r; 17277d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 172884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 172984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 173084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1731cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1732fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick l = get_assignment_lhs(ir->lhs, this); 1733cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 17345a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This should really set to the correct maximal writemask for each 17355a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: component written (in the loops below). This case can only 17365a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: occur for matrices, arrays, and structures. 17375a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 17385a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick if (ir->write_mask == 0) { 17395a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 17405a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 17415a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else if (ir->lhs->type->is_scalar()) { 1742b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 17435a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: W component of fragment shader output zero, work correctly. 17445a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 17455a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 17465a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else { 1747b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int swizzles[4]; 1748b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int first_enabled_chan = 0; 1749b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int rhs_chan = 0; 1750b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 17515a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->lhs->type->is_vector()); 17525a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = ir->write_mask; 1753b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1754b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1755b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) { 1756b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt first_enabled_chan = GET_SWZ(r.swizzle, i); 1757b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt break; 1758b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1759b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1760b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1761b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* Swizzle a small RHS vector into the channels being written. 1762b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * 1763b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * glsl ir treats write_mask as dictating how many channels are 1764b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * present on the RHS while Mesa IR treats write_mask as just 1765b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * showing which channels of the vec4 RHS get written. 1766b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt */ 1767b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1768b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) 1769b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 1770b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt else 1771b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = first_enabled_chan; 1772b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1773b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 1774b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[2], swizzles[3]); 17755a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } 17765a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick 17770161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 17780161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 177984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1780346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 1781c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick const bool switch_order = this->process_move_condition(ir->condition); 1782c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_to_mesa_src_reg condition = this->result; 17832d1789e667c4180777829f96856daf91326721b9Eric Anholt 17847d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 1785c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (switch_order) { 1786c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, 1787c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick condition, ir_to_mesa_src_reg_from_dst(l), r); 1788c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else { 1789c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, 1790c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick condition, r, ir_to_mesa_src_reg_from_dst(l)); 1791c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1792c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 17937d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 17947d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 17957d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 17962d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 17977d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 17987d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 17997d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 18007d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 18017d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1802346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 180384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 180484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 180584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 180684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 180784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 180884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 18090161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 18100a46497a4ee3325fab47929cb17cfe2525e1fc33Vinson Lee GLfloat stack_vals[4] = { 0 }; 18110bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 18120bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 181384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 18145b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt /* Unfortunately, 4 floats is all we can get into 18155b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store an 18165b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * aggregate constant and move each constant value into it. If we 18175b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * get lucky, copy propagation will eliminate the extra moves. 18185b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt */ 18195b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18205b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt if (ir->type->base_type == GLSL_TYPE_STRUCT) { 18215b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_src_reg temp_base = get_temp(ir->type); 18225b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); 18235b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18245b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt foreach_iter(exec_list_iterator, iter, ir->components) { 18255b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_constant *field_value = (ir_constant *)iter.get(); 18265b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt int size = type_size(field_value->type); 18275b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18285b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt assert(size > 0); 18295b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18305b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt field_value->accept(this); 18315b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg = this->result; 18325b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18335b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt for (i = 0; i < (unsigned int)size; i++) { 18345b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); 18355b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18365b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg.index++; 18375b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt temp.index++; 18385b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18395b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18405b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt this->result = temp_base; 18415b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt return; 18425b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18435b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 184420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (ir->type->is_array()) { 184520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_src_reg temp_base = get_temp(ir->type); 184620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); 184720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt int size = type_size(ir->type->fields.array); 184820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 184920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt assert(size > 0); 185020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 185120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < ir->type->length; i++) { 185220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir->array_elements[i]->accept(this); 185320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg = this->result; 185420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (int j = 0; j < size; j++) { 185520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); 185620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 185720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.index++; 185820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt temp.index++; 185920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 186020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 186120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt this->result = temp_base; 186220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt return; 186320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 186420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1865ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1866c91809e1e4a4fa8884e6588159368ea32431ee0eEric Anholt ir_to_mesa_src_reg mat = get_temp(ir->type); 1867ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat); 1868ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1869ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1870ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1871ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1872ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 18739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL); 1874ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 18759c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt values, 18769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 18779c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &src_reg.swizzle); 1878ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg); 1879ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1880ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1881ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1882ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1883ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1884ebef04011736ea8e13692fed87623d425c4d1b08Eric Anholt return; 1885582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 18860bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 18870bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt src_reg.file = PROGRAM_CONSTANT; 18880bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 18890bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 18900bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 18910bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 18920bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 18930bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 18940bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 18950bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 18960bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 18970bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 18980bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 18990bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 19000bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19010bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19020bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 19030bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19040bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 19050bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19060bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19070bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 19080bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 19090bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19100bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 19119c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type); 19129c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, 19139c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt values, 19149c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 19159c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &this->result.swizzle); 191684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 191784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 19187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry * 19197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) 19207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{ 19217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry; 19227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, this->function_signatures) { 19247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = (function_entry *)iter.get(); 19257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig == sig) 19277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 19287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = talloc(mem_ctx, function_entry); 19317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig = sig; 19327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig_id = this->next_signature_id++; 19337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = NULL; 19347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Allocate storage for all the parameters. */ 19367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, sig->parameters) { 19377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)iter.get(); 1938b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage; 19397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt storage = find_variable_storage(param); 19417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!storage); 19427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1943b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 1944b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1945b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(storage); 19467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->next_temp += type_size(param->type); 19487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1950576d01ad8c8b8aa57b4711c98d8e004d4f20fc0bEric Anholt if (!sig->return_type->is_void()) { 19517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = get_temp(sig->return_type); 19527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } else { 19537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = ir_to_mesa_undef; 19547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->function_signatures.push_tail(entry); 19577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 19587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt} 195984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 196084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 196184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 196284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 19637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *call_inst; 19647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig = ir->get_callee(); 19657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = get_function_signature(sig); 19667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 19677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process in parameters. */ 19697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list_iterator sig_iter = sig->parameters.iterator(); 19707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 19717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 19727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 19737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_in || 19757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1976b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 19777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 19787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 19807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 19817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 19837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.file = storage->file; 19847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index = storage->index; 19857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.reladdr = NULL; 19867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.writemask = WRITEMASK_XYZW; 19877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.cond_mask = COND_TR; 19887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 19907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 19917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 19927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 19937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 19977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 19997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit call instruction */ 20017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL, 20027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 20037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst->function = entry; 20047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process out parameters. */ 20067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter = sig->parameters.iterator(); 20077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 20087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 20097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 20107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_out || 20127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 2013b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 20147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 20157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r; 20177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.file = storage->file; 20187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index = storage->index; 20197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.reladdr = NULL; 20207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.swizzle = SWIZZLE_NOOP; 20217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.negate = 0; 20227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 20247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result); 20257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 20277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 20287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 20297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 20307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 20347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 20367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process return value. */ 20387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->result = entry->return_reg; 203984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 204084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 204184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 204284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 204384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 20449c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg result_src, coord, lod_info, projector; 2045d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_dst_reg result_dst, coord_dst; 2046d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 2047d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 204884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 204984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->coordinate->accept(this); 2050d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2051d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 2052d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 2053d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 2054d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 2055d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2056d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 2057d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst = ir_to_mesa_dst_reg_from_src(coord); 2058d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, 2059d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt this->result); 2060d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2061de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 2062de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 2063de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 2064de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 2065de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 2066d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 2067d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 2068d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 2069d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 2070d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 2071d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2072d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 2073d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 2074d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 2075d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2076d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 2077d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 2078d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 2079d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2080d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2081d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 2082d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 2083d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 2084d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2085d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2086d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 2087d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txf: 2088d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"GLSL 1.30 features unsupported"); 2089d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2090d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2091d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2092d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 2093d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 2094d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 2095d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 2096d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector); 2097d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2098d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 2099d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 2100d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_src_reg coord_w = coord; 2101d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 2102d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2103d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 2104d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 2105d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 2106d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2107d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 2108d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector); 2109d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2110d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 2111d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w); 2112d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2113d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2114d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 2115d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2116d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2117d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2118b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) { 2119b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 2120b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 2121b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 2122b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 2123b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_Z; 2124b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result); 2125b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2126b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 2127b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2128d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 2129d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 2130d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 2131d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info); 2132d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2133d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2134d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2135d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord); 2136d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2137b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 2138b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 2139b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2140a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2141a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->shader_program, 2142a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->prog); 2143c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt 2144aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt const glsl_type *sampler_type = ir->sampler->type; 2145d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2146c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt switch (sampler_type->sampler_dimensionality) { 2147d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 2148c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 21490a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2150d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2151d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 2152c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 21530a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2154d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2155d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 2156d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 2157d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2158d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 2159d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 2160d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 21610bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick case GLSL_SAMPLER_DIM_RECT: 21620bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick inst->tex_target = TEXTURE_RECT_INDEX; 21630bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick break; 216468772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick case GLSL_SAMPLER_DIM_BUF: 216568772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"FINISHME: Implement ARB_texture_buffer_object"); 216668772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick break; 2167d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 216868772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"Should not get here."); 2169d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2170d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2171d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 217284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 217384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 217484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 217584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 217684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 21777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (ir->get_value()) { 21787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 21797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 21807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 218135220fc5981045331b4f048f0fc2e1371a0673edEric Anholt assert(current_function); 218235220fc5981045331b4f048f0fc2e1371a0673edEric Anholt 21837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir->get_value()->accept(this); 21847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 218584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 21867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l = ir_to_mesa_dst_reg_from_src(current_function->return_reg); 21877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(current_function->sig->return_type); i++) { 21897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 21907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 21917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 21927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op0(ir, OPCODE_RET); 219684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 219784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 219816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 219916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 220016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 22019b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 22029b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt 2203ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák if (ir->condition) { 2204ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák ir->condition->accept(this); 2205ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák this->result.negate = ~this->result.negate; 2206ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák ir_to_mesa_emit_op1(ir, OPCODE_KIL, ir_to_mesa_undef_dst, this->result); 2207ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } else { 2208ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV); 2209ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } 221016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 22119b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt fp->UsesKill = GL_TRUE; 221216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 221384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 221484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 221584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 221684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 2217854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL; 2218cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 2219cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2220cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2221c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2222c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 22230161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 2224c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 22256d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri if (this->options->EmitCondCodes) { 2226854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2227cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2228cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 2229cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 2230cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 2231cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 2232cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 2233cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type); 2234cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV, 2235cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_dst_reg_from_src(temp), 2236cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt result); 2237cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 2238854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 2239854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 2240021222c6a872ca2eef770ebadb8754f659775204Eric Anholt if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF); 2241854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst->dst_reg.cond_mask = COND_NE; 2242854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 2243854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, 2244854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt OPCODE_IF, ir_to_mesa_undef_dst, 2245854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt this->result); 2246854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 2247c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2248c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 2249c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2250c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 2251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2252c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 2253021222c6a872ca2eef770ebadb8754f659775204Eric Anholt else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE); 22540a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 2255c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2256c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 22570161515c395c44233529c8d51f823b60050bc7baEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF, 22580161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 225984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 226084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2261ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 2262ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 22630161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 2264ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 22657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 22667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 2267abc6d7e0b4b04c75129d24c3cb6f021b92cd46f6Eric Anholt mem_ctx = talloc_new(NULL); 2268ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 2269ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 2270fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor() 2271fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{ 2272abc6d7e0b4b04c75129d24c3cb6f021b92cd46f6Eric Anholt talloc_free(mem_ctx); 2273fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt} 2274fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt 227584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 227684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) 227784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 227884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 227984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 228084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 228150fd99d1723a6c7f3bd2dedffeeadf7d5e33b83bBrian Paul assert(reg.index < (1 << INST_INDEX_BITS)); 228284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 228334195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 2284f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 2285ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 2286285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 2287b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt mesa_reg.HasIndex2 = GL_FALSE; 2288405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.RelAddr2 = 0; 2289405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.Index2 = 0; 229084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 229184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 229284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 229384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2294c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 22957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 22967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 2297c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2298c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2299e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 230064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 230164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 230264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 2303c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2304c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 230564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 230664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 2307c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 230864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 230964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 231064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 231164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 231264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 231364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 231464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 231564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 231664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 231764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 231864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 2319c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2320c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 23213ef83d270b2c24867a0d020b81bdc6c54cb1c9b0Eric Anholt if_stack = talloc_zero_array(v->mem_ctx, int, if_count); 23223ef83d270b2c24867a0d020b81bdc6c54cb1c9b0Eric Anholt loop_stack = talloc_zero_array(v->mem_ctx, int, loop_count); 2323c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2324c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2325c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 2326c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 232764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 2328c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 2329c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2330c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 233164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 233264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 2333c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2334c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 233564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 2336c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 2337c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 233864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 233964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 234064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 234164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 234264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 234364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 234464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 234564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 234664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 234764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 234864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 234964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 235064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 235164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 235264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 235364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 235464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 235564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 235664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 235764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 235864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 23597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 23607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 23617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 23627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 23637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 23647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 23657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 23667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 23677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 23687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 23697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 2370c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 2371c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2372c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2373c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2374c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2375c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2376c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 2377c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 2378c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 2379c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2380c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2381c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 2382c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2383748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 2384c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2385c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2386c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 2387c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 2388c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2389748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 2390748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 239164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 2392748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 2393748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2394748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 2395748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 2396748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 2397748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 2398c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 2399c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 2400748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2401748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 2402c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2403c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2404748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 2405748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 2406c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2407c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2408c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2409ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void 2410ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog) 2411ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{ 2412d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt unsigned int i; 2413d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2414d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed = 0; 2415ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2416ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (i = 0; i < prog->NumInstructions; i++) { 2417ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt struct prog_instruction *inst = &prog->Instructions[i]; 2418d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2419d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (_mesa_is_tex_instruction(inst->Opcode)) { 2420d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplerTargets[inst->TexSrcUnit] = 2421d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt (gl_texture_index)inst->TexSrcTarget; 2422d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed |= 1 << inst->TexSrcUnit; 2423d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (inst->TexShadow) { 2424d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->ShadowSamplers |= 1 << inst->TexSrcUnit; 2425d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2426d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2427ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2428d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2429d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt _mesa_update_shader_textures_used(prog); 2430ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt} 2431ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 243299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholtstruct uniform_sort { 243399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct gl_uniform *u; 243499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt int pos; 243599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt}; 243699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 243799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt/* The shader_program->Uniforms list is almost sorted in increasing 243899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt * uniform->{Frag,Vert}Pos locations, but not quite when there are 243999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt * uniforms shared between targets. We need to add parameters in 244099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt * increasing order for the targets. 244199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt */ 244299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholtstatic int 244399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholtsort_uniforms(const void *a, const void *b) 244499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt{ 244599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct uniform_sort *u1 = (struct uniform_sort *)a; 244699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct uniform_sort *u2 = (struct uniform_sort *)b; 244799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 244899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt return u1->pos - u2->pos; 244999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt} 245099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 24510924ba0c3496160a134d37cec800f902ae805b9cEric Anholt/* Add the uniforms to the parameters. The linker chose locations 24520924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * in our parameters lists (which weren't created yet), which the 24530924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * uniforms code will use to poke values into our parameters list 24540924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * when uniforms are updated. 245585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 245685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void 24570924ba0c3496160a134d37cec800f902ae805b9cEric Anholtadd_uniforms_to_parameters_list(struct gl_shader_program *shader_program, 24580924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_shader *shader, 24590924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_program *prog) 246085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 246185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt unsigned int i; 246299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt unsigned int next_sampler = 0, num_uniforms = 0; 246399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct uniform_sort *sorted_uniforms; 246499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 246599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt sorted_uniforms = talloc_array(NULL, struct uniform_sort, 246699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt shader_program->Uniforms->NumUniforms); 246785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 24680924ba0c3496160a134d37cec800f902ae805b9cEric Anholt for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) { 24690924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i; 24700924ba0c3496160a134d37cec800f902ae805b9cEric Anholt int parameter_index = -1; 24710924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 24720924ba0c3496160a134d37cec800f902ae805b9cEric Anholt switch (shader->Type) { 24730924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_VERTEX_SHADER: 24740924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->VertPos; 24750924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 24760924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_FRAGMENT_SHADER: 24770924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->FragPos; 24780924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 24790924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_GEOMETRY_SHADER: 24800924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->GeomPos; 24810924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 24820924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 24830924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 24840924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Only add uniforms used in our target. */ 248599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt if (parameter_index != -1) { 248699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt sorted_uniforms[num_uniforms].pos = parameter_index; 248799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt sorted_uniforms[num_uniforms].u = uniform; 248899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt num_uniforms++; 248999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 249099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 249199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 249299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt qsort(sorted_uniforms, num_uniforms, sizeof(struct uniform_sort), 249399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt sort_uniforms); 249499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 249599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt for (i = 0; i < num_uniforms; i++) { 249699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct gl_uniform *uniform = sorted_uniforms[i].u; 249799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt int parameter_index = sorted_uniforms[i].pos; 249899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt const glsl_type *type = uniform->Type; 249999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt unsigned int size; 25000924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 25010924ba0c3496160a134d37cec800f902ae805b9cEric Anholt if (type->is_vector() || 25020924ba0c3496160a134d37cec800f902ae805b9cEric Anholt type->is_scalar()) { 25030924ba0c3496160a134d37cec800f902ae805b9cEric Anholt size = type->vector_elements; 25040924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } else { 25050924ba0c3496160a134d37cec800f902ae805b9cEric Anholt size = type_size(type) * 4; 25060924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 25070924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2508aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt gl_register_file file; 25090924ba0c3496160a134d37cec800f902ae805b9cEric Anholt if (type->is_sampler() || 25100924ba0c3496160a134d37cec800f902ae805b9cEric Anholt (type->is_array() && type->fields.array->is_sampler())) { 2511aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt file = PROGRAM_SAMPLER; 2512aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } else { 2513aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt file = PROGRAM_UNIFORM; 2514aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 251585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2516aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, 2517aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt uniform->Name); 25180924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2519aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index < 0) { 2520aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt index = _mesa_add_parameter(prog->Parameters, file, 2521aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt uniform->Name, size, type->gl_type, 2522aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt NULL, NULL, 0x0); 2523aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2524aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt /* Sampler uniform values are stored in prog->SamplerUnits, 2525aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * and the entry in that array is selected by this index we 2526aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * store in ParameterValues[]. 2527aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt */ 2528aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (file == PROGRAM_SAMPLER) { 2529aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt for (unsigned int j = 0; j < size / 4; j++) 2530aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt prog->Parameters->ParameterValues[index + j][0] = next_sampler++; 2531aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 2532aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2533aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt /* The location chosen in the Parameters list here (returned 2534aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * from _mesa_add_uniform) has to match what the linker chose. 2535aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt */ 2536aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index != parameter_index) { 2537500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt fail_link(shader_program, "Allocation of uniform `%s' to target " 2538500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt "failed (%d vs %d)\n", 2539500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt uniform->Name, index, parameter_index); 25400924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 254185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 254285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 254399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 254499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt talloc_free(sorted_uniforms); 254585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 254685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 25472f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 2548f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergset_uniform_initializer(struct gl_context *ctx, void *mem_ctx, 25492f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program, 25502f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const char *name, const glsl_type *type, 25512f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *val) 25522f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 25532f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_record()) { 25542f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *field_constant; 25552f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 25562f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)val->components.get_head(); 25572f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 25582f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 25592f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *field_type = type->fields.structure[i].type; 25602f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name, 25612f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt type->fields.structure[i].name); 25622f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 25632f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_type, field_constant); 25642f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)field_constant->next; 25652f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 25662f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt return; 25672f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 25682f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 25692f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt int loc = _mesa_get_uniform_location(ctx, shader_program, name); 25702f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 25712f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (loc == -1) { 2572500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt fail_link(shader_program, 2573500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt "Couldn't find uniform for initializer %s\n", name); 2574500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt return; 25752f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 25762f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 25772f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 25782f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *element; 25792f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *element_type; 25802f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_array()) { 25812f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val->array_elements[i]; 25822f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type->fields.array; 25832f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 25842f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val; 25852f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type; 25862f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 25872f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 25882f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *values; 25892f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 25902f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->base_type == GLSL_TYPE_BOOL) { 25912f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt int *conv = talloc_array(mem_ctx, int, element_type->components()); 25922f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int j = 0; j < element_type->components(); j++) { 25932f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt conv[j] = element->value.b[j]; 25942f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 25952f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = (void *)conv; 25962f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = glsl_type::get_instance(GLSL_TYPE_INT, 25972f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 25982f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 1); 25992f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 26002f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = &element->value; 26012f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 26022f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26032f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->is_matrix()) { 26042f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform_matrix(ctx, shader_program, 26052f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->matrix_columns, 26062f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 26072f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc, 1, GL_FALSE, (GLfloat *)values); 26082f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += element_type->matrix_columns; 26092f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 26102f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 26112f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values, element_type->gl_type); 26122f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += type_size(element_type); 26132f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 26142f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 26152f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 26162f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26172f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 2618f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergset_uniform_initializers(struct gl_context *ctx, 26192f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program) 26202f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 26212f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *mem_ctx = NULL; 26222f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26233322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { 26242f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader *shader = shader_program->_LinkedShaders[i]; 26253322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 26263322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (shader == NULL) 26273322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 26283322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 26292f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt foreach_iter(exec_list_iterator, iter, *shader->ir) { 26302f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 26312f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_variable *var = ir->as_variable(); 26322f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26332f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!var || var->mode != ir_var_uniform || !var->constant_value) 26342f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt continue; 26352f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26362f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!mem_ctx) 26372f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt mem_ctx = talloc_new(NULL); 26382f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26392f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, 26402f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt var->type, var->constant_value); 26412f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 26422f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 26432f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26442f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt talloc_free(mem_ctx); 26452f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 26462f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 264734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt/* 264834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * On a basic block basis, tracks available PROGRAM_TEMPORARY register 264934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * channels for copy propagation and updates following instructions to 265034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * use the original versions. 265134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 265234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * The ir_to_mesa_visitor lazily produces code assuming that this pass 265334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * will occur. As an example, a TXP production before this pass: 265434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 265534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 265634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 265734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 265834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 265934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * and after: 266034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 266134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 266234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 266334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 266434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 266534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * which allows for dead code elimination on TEMP[1]'s writes. 266634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 266734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtvoid 266834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtir_to_mesa_visitor::copy_propagate(void) 266934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt{ 267025beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt ir_to_mesa_instruction **acp = talloc_zero_array(mem_ctx, 267125beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt ir_to_mesa_instruction *, 267225beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt this->next_temp * 4); 267334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 267434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt foreach_iter(exec_list_iterator, iter, this->instructions) { 267534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 267634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 26775c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick assert(inst->dst_reg.file != PROGRAM_TEMPORARY 26785c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick || inst->dst_reg.index < this->next_temp); 26795c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick 268034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* First, do any copy propagation possible into the src regs. */ 268134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int r = 0; r < 3; r++) { 268234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *first = NULL; 268334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt bool good = true; 268434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt int acp_base = inst->src_reg[r].index * 4; 268534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 268634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->src_reg[r].file != PROGRAM_TEMPORARY || 268734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt inst->src_reg[r].reladdr) 268834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt continue; 268934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 269034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* See if we can find entries in the ACP consisting of MOVs 269134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * from the same src register for all the swizzled channels 269234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * of this src register reference. 269334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 269434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 269534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt int src_chan = GET_SWZ(inst->src_reg[r].swizzle, i); 269634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_chan = acp[acp_base + src_chan]; 269734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 269834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!copy_chan) { 269934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 270034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 270134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 270234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 270334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!first) { 270434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt first = copy_chan; 270534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } else { 270634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (first->src_reg[0].file != copy_chan->src_reg[0].file || 270734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt first->src_reg[0].index != copy_chan->src_reg[0].index) { 270834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 270934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 271034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 271134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 271234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 271334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 271434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (good) { 271534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* We've now validated that we can copy-propagate to 271634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * replace this src register reference. Do it. 271734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 271834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt inst->src_reg[r].file = first->src_reg[0].file; 271934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt inst->src_reg[r].index = first->src_reg[0].index; 272034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 272134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt int swizzle = 0; 272234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 272334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt int src_chan = GET_SWZ(inst->src_reg[r].swizzle, i); 272434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_inst = acp[acp_base + src_chan]; 272534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt swizzle |= (GET_SWZ(copy_inst->src_reg[0].swizzle, src_chan) << 272634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt (3 * i)); 272734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 272834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt inst->src_reg[r].swizzle = swizzle; 272934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 273034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 273134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 273234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt switch (inst->op) { 273334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_BGNLOOP: 273434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_ENDLOOP: 273534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_ELSE: 273634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_ENDIF: 273734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* End of a basic block, clear the ACP entirely. */ 273825beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 273934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 274034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 274134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt default: 274234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* Continuing the block, clear any written channels from 274334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * the ACP. 274434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 274534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->dst_reg.file == PROGRAM_TEMPORARY) { 274634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->dst_reg.reladdr) { 274725beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 274834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } else { 274934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 275034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->dst_reg.writemask & (1 << i)) { 275134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt acp[4 * inst->dst_reg.index + i] = NULL; 275234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 275334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 275434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 275534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 275634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 275734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 275834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 275934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* If this is a copy, add it to the ACP. */ 276034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->op == OPCODE_MOV && 276134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt inst->dst_reg.file == PROGRAM_TEMPORARY && 276234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt !inst->dst_reg.reladdr && 276334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt !inst->saturate && 276434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt !inst->src_reg[0].reladdr && 276534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt !inst->src_reg[0].negate) { 276634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 276734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->dst_reg.writemask & (1 << i)) { 276834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt acp[4 * inst->dst_reg.index + i] = inst; 276934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 277034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 277134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 277234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 27737772a34f3aedfa8ef58ad5f912f56bd5adf27057Vinson Lee 277425beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt talloc_free(acp); 277534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt} 277634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2777f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 2778f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 2779f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Convert a shader's GLSL IR into a Mesa gl_program. 2780f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 27816162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulstatic struct gl_program * 27826162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulget_mesa_program(struct gl_context *ctx, 27836162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul struct gl_shader_program *shader_program, 278495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 278584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 278684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 278784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2788c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 2789c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2790364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 2791364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 2792c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 27937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt GLboolean progress; 27946d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri struct gl_shader_compiler_options *options = 27956d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 2796364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2797364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 2798c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 2799c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 2800c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 2801c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2802c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 2803c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 2804c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 2805c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2806903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul case GL_GEOMETRY_SHADER: 2807903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target = GL_GEOMETRY_PROGRAM_NV; 2808903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target_string = "geometry"; 2809903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul break; 2810c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 2811c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 28124841c0a15adcc722e67d7d246987cd686d3f7a17José Fonseca return NULL; 2813364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 281484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 28151124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 28161124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 2817859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 2818364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 2819364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 2820364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 2821364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2822364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Attributes = _mesa_new_parameter_list(); 2823364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 2824364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 2825aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt v.shader_program = shader_program; 28266d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri v.options = options; 2827364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 28280924ba0c3496160a134d37cec800f902ae805b9cEric Anholt add_uniforms_to_parameters_list(shader_program, shader, prog); 28290924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 28307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 283116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 2832021222c6a872ca2eef770ebadb8754f659775204Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_END); 283384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 28347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Now emit bodies for any functions that were used. */ 28357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt do { 28367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_FALSE; 28377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 28387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v.function_signatures) { 28397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 28407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 28417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (!entry->bgn_inst) { 28427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt v.current_function = entry; 28437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 28447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB); 28457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst->function = entry; 28467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 28477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt visit_exec_list(&entry->sig->body, &v); 28487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2849806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt ir_to_mesa_instruction *last; 2850806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt last = (ir_to_mesa_instruction *)v.instructions.get_tail(); 2851806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt if (last->op != OPCODE_RET) 2852806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_RET); 2853806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt 285440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt ir_to_mesa_instruction *end; 285540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB); 285640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end->function = entry; 285740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt 28587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_TRUE; 28597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 28607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 28617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } while (progress); 28627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2863364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 2864364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 286584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 286684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 286784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 286884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 286984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 287084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 287184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 287284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 2873850c659044d081c53713800cacf8d518fae6cd70Eric Anholt mesa_instruction_annotation = talloc_array(v.mem_ctx, ir_instruction *, 2874364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 287584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 287634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt v.copy_propagate(); 287734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2878f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Convert ir_mesa_instructions into prog_instructions. 2879f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 288084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 2881c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 288284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 2883f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 2884b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 288584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 2886854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 2887ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (inst->saturate) 2888ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt mesa_inst->SaturateMode = SATURATE_ZERO_ONE; 288984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.File = inst->dst_reg.file; 289084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.Index = inst->dst_reg.index; 2891854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask; 289212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; 2893f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL; 289484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); 289584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); 289684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); 2897d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 2898d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 2899b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 2900c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 2901aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 29025755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák /* Set IndirectRegisterFiles. */ 29035755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->DstReg.RelAddr) 29045755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; 29055755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 2906f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Update program's bitmask of indirectly accessed register files */ 29075755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák for (unsigned src = 0; src < 3; src++) 29085755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->SrcReg[src].RelAddr) 29095755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; 29105755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 29116d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri if (options->EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { 2912500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt fail_link(shader_program, "Couldn't flatten if statement\n"); 291395c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt } 291495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt 291540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt switch (mesa_inst->Opcode) { 291640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_BGNSUB: 29177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function->inst = i; 291840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 291940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 292040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ENDSUB: 292140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 292240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 292340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_CAL: 29247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ 292540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 292640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ARL: 2927d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 292840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 292940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt default: 293040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 293140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt } 29327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 293384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 2934c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 29356162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 29366162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) 29376162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 29386162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 29396162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 29406162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) { 29416162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul free(mesa_instructions); 29426162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul _mesa_reference_program(ctx, &shader->Program, NULL); 29436162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul return NULL; 294484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 2945c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 29467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 2947925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 2948c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2949455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2950455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL IR for linked %s program %d:\n", target_string, 2951455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2952455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt _mesa_print_ir(shader->ir, NULL); 2953455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2954455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2955455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("Mesa IR for linked %s program %d:\n", target_string, 2956455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2957364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 2958364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 2959364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2960364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2961364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 2962364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 2963364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2964925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt do_set_program_inouts(shader->ir, prog); 2965925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt count_resources(prog); 2966925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 296716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 2968364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 296928faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 297028faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 297128faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 297228faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 2973364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 2974364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2975364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 297616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 2977f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 2978f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 2979f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Called via ctx->Driver.CompilerShader(). 2980f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * This is a no-op. 2981f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * XXX can we remove the ctx->Driver.CompileShader() hook? 2982f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 2983d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean 2984f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader) 2985d19eecef54384c163af27a470496ed885a5a271bEric Anholt{ 2986d19eecef54384c163af27a470496ed885a5a271bEric Anholt assert(shader->CompileStatus); 2987fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick (void) ctx; 2988d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2989d19eecef54384c163af27a470496ed885a5a271bEric Anholt return GL_TRUE; 2990d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 2991d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2992f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 2993f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 2994f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a shader. 2995f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Called via ctx->Driver.LinkShader() 2996f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * This actually involves converting GLSL IR into Mesa gl_programs with 2997f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * code lowering and other optimizations. 2998f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 2999d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean 3000f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 3001d19eecef54384c163af27a470496ed885a5a271bEric Anholt{ 3002d19eecef54384c163af27a470496ed885a5a271bEric Anholt assert(prog->LinkStatus); 3003d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30043322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 30053322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 30063322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 30073322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 3008d19eecef54384c163af27a470496ed885a5a271bEric Anholt bool progress; 3009d19eecef54384c163af27a470496ed885a5a271bEric Anholt exec_list *ir = prog->_LinkedShaders[i]->ir; 3010f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const struct gl_shader_compiler_options *options = 30116d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 3012d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3013d19eecef54384c163af27a470496ed885a5a271bEric Anholt do { 3014d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = false; 3015d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3016d19eecef54384c163af27a470496ed885a5a271bEric Anholt /* Lowering */ 3017d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_mat_op_to_vec(ir); 3018c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 3019c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick | LOG_TO_LOG2 3020c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); 3021d19eecef54384c163af27a470496ed885a5a271bEric Anholt 302287708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 302387708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri 3024e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress; 3025d19eecef54384c163af27a470496ed885a5a271bEric Anholt 302611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick progress = lower_quadop_vector(ir, true) || progress; 302711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 3028940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke if (options->EmitNoIfs) { 3029940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke progress = lower_discard(ir) || progress; 30309ac6a9b2fa45debac63f2e2b20d78c4776d06e37Kenneth Graunke progress = lower_if_to_cond_assign(ir) || progress; 3031940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke } 3032d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30332b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick if (options->EmitNoNoise) 30342b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick progress = lower_noise(ir) || progress; 30352b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick 3036a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick /* If there are forms of indirect addressing that the driver 3037a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick * cannot handle, perform the lowering pass. 3038a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick */ 3039a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 3040a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 3041a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick progress = 3042a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick lower_variable_index_to_cond_assign(ir, 3043a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectInput, 3044a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectOutput, 3045a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectTemp, 3046a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectUniform) 3047a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || progress; 3048a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick 3049d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = do_vec_index_to_cond_assign(ir) || progress; 3050d19eecef54384c163af27a470496ed885a5a271bEric Anholt } while (progress); 3051d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3052d19eecef54384c163af27a470496ed885a5a271bEric Anholt validate_ir_tree(ir); 3053d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3054d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30553322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 3056d19eecef54384c163af27a470496ed885a5a271bEric Anholt struct gl_program *linked_prog; 3057d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30583322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 30593322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 30603322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 3061d19eecef54384c163af27a470496ed885a5a271bEric Anholt linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 3062d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30636162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (linked_prog) { 30646162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul bool ok = true; 30656162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 30666162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul switch (prog->_LinkedShaders[i]->Type) { 30676162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul case GL_VERTEX_SHADER: 30686162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul _mesa_reference_vertprog(ctx, &prog->VertexProgram, 30696162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul (struct gl_vertex_program *)linked_prog); 30706162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 30716162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul linked_prog); 30726162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 30736162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul case GL_FRAGMENT_SHADER: 30746162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul _mesa_reference_fragprog(ctx, &prog->FragmentProgram, 30756162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul (struct gl_fragment_program *)linked_prog); 30766162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 30776162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul linked_prog); 30786162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 3079903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul case GL_GEOMETRY_SHADER: 3080903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul _mesa_reference_geomprog(ctx, &prog->GeometryProgram, 3081903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul (struct gl_geometry_program *)linked_prog); 3082903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul ok = ctx->Driver.ProgramStringNotify(ctx, GL_GEOMETRY_PROGRAM_NV, 3083903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul linked_prog); 3084903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul break; 30856162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 30866162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!ok) { 30876162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul return GL_FALSE; 30886162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 3089d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 30906162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 30913cd233eb5714137dccb6218ad78005511bcc02bdEric Anholt _mesa_reference_program(ctx, &linked_prog, NULL); 3092d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3093d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3094d19eecef54384c163af27a470496ed885a5a271bEric Anholt return GL_TRUE; 3095d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 309616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 3097f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3098f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3099f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Compile a GLSL shader. Called via glCompileShader(). 3100f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 310116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 3102f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) 3103364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 31042462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 31052462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 31065e18b051c039564d1998818d08caf1bff3983630Ian Romanick 3107153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 3108a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke /* Check if the user called glCompileShader without first calling 3109a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke * glShaderSource. This should fail to compile, but not raise a GL_ERROR. 3110a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke */ 3111a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke if (source == NULL) { 3112a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke shader->CompileStatus = GL_FALSE; 3113a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke return; 3114a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke } 3115a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke 311606143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick state->error = preprocess(state, &source, &state->info_log, 31177dcfc44b72f00ba5a38cb02123c80113440f0de9Kenneth Graunke &ctx->Extensions, ctx->API); 3118153eca98064252be4daad9cc27746f37c245b627Ian Romanick 31191b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 31201b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt printf("GLSL source for shader %d:\n", shader->Name); 31211b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt printf("%s\n", shader->Source); 31221b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt } 31231b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt 3124153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 3125153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 3126153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 3127153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 3128153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 3129364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 31304a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt talloc_free(shader->ir); 313116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 3132364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 313316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 3134364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 313516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 3136ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3137ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 31382f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt /* Do some optimization at compile time to reduce shader IR size 31392f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt * and reduce later work if the same shader is linked multiple times 31402f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt */ 3141e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri while (do_common_optimization(shader->ir, false, 32)) 31422f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt ; 3143ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 3144ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3145364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3146364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3147364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 3148364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3149364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 3150364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 315125f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 3152d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 3153d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 3154d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 3155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 3156b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt if (ctx->Shader.Flags & GLSL_LOG) { 3157b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt _mesa_write_shader_to_file(shader); 3158b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt } 3159b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt 31600df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 31610df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->CompileStatus) { 31620df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL IR for shader %d:\n", shader->Name); 31630df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt _mesa_print_ir(shader->ir, NULL); 31640df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("\n\n"); 31650df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } else { 31660df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d failed to compile.\n", shader->Name); 31670df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 31680df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->InfoLog && shader->InfoLog[0] != 0) { 31690df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d info log:\n", shader->Name); 31700df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", shader->InfoLog); 31710df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3172455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt } 3173455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt 3174116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 31754a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt reparent_ir(shader->ir, shader->ir); 3176116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 3177364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt talloc_free(state); 3178d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3179d19eecef54384c163af27a470496ed885a5a271bEric Anholt if (shader->CompileStatus) { 3180d19eecef54384c163af27a470496ed885a5a271bEric Anholt if (!ctx->Driver.CompileShader(ctx, shader)) 3181d19eecef54384c163af27a470496ed885a5a271bEric Anholt shader->CompileStatus = GL_FALSE; 3182d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3183d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 3184364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3185f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3186f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3187f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a GLSL shader program. Called via glLinkProgram(). 3188f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 3189364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 3190f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 3191364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 3192364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 3193849e18153cd91d812f694b806a84008498860bc3Eric Anholt 3194364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 3195364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3196849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 3197364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3198364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 3199849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 3200500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt fail_link(prog, "linking with uncompiled shader"); 3201849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 3202364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3203364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3204364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3205364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 3206364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); 3207364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); 3208903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul _mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL); 3209364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3210849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 32115d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt link_shaders(ctx, prog); 3212849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 3213364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3214364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 32150df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (!ctx->Driver.LinkShader(ctx, prog)) { 3216d19eecef54384c163af27a470496ed885a5a271bEric Anholt prog->LinkStatus = GL_FALSE; 3217af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3218af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3219af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt 32202f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializers(ctx, prog); 32212f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 3222af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 3223af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (!prog->LinkStatus) { 32240df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d failed to link\n", prog->Name); 32250df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 32260df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt 32270df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (prog->InfoLog && prog->InfoLog[0] != 0) { 32280df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d info log:\n", prog->Name); 32290df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", prog->InfoLog); 32300df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3231364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3232364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 3233364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3234364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 3235