ir_to_mesa.cpp revision 6437a71d4172273db670b959dd66e3b34c866962
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" 436437a71d4172273db670b959dd66e3b34c866962Ian Romanick#include "linker.h" 4484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 450a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h" 46afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h" 47fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h" 48bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick 49bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanickextern "C" { 50bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick#include "main/shaderapi.h" 51bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick#include "main/uniforms.h" 52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h" 53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h" 54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h" 55afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h" 56afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h" 57afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h" 58a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt#include "program/sampler.h" 59aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt} 6084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkeclass src_reg; 62cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkeclass dst_reg; 63cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 649c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtstatic int swizzle_for_size(int size); 659c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 66554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/** 67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with 68554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields. 69554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 70fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkeclass src_reg { 71fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkepublic: 72b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke src_reg(gl_register_file file, int index, const glsl_type *type) 739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 74b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke this->file = file; 759c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->index = index; 769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) 779c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = swizzle_for_size(type->vector_elements); 789c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt else 799c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = SWIZZLE_XYZW; 809c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->negate = 0; 819c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->reladdr = NULL; 829c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 839c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 84fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg() 859c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 869c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->file = PROGRAM_UNDEFINED; 8748c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->index = 0; 8848c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->swizzle = 0; 8948c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->negate = 0; 9048c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->reladdr = NULL; 919c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 929c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 93cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke explicit src_reg(dst_reg reg); 94cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 95caf974c5259f14b50257e8dd9b325a87378259afBrian Paul gl_register_file file; /**< PROGRAM_* from Mesa */ 96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 97582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int negate; /**< NEGATE_XYZW mask from mesa */ 99f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 100fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg *reladdr; 101fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke}; 102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 103fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkeclass dst_reg { 104fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkepublic: 105b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke dst_reg(gl_register_file file, int writemask) 106cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke { 107cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->file = file; 108cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = 0; 109cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->writemask = writemask; 110cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->cond_mask = COND_TR; 111cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->reladdr = NULL; 112cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke } 113cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 114cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg() 115cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke { 116cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->file = PROGRAM_UNDEFINED; 117cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = 0; 118cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->writemask = 0; 119cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->cond_mask = COND_TR; 120cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->reladdr = NULL; 121cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke } 122cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 123cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke explicit dst_reg(src_reg reg); 124cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 125b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke gl_register_file file; /**< PROGRAM_* from Mesa */ 126554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 127554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 128854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLuint cond_mask:4; 129f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 130fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg *reladdr; 131fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke}; 132554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 133cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkesrc_reg::src_reg(dst_reg reg) 134cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke{ 135b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke this->file = reg.file; 136cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = reg.index; 137cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->swizzle = SWIZZLE_XYZW; 138cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->negate = 0; 139f7cd9a858c043e609fcdbf9ac9dfc1ef7ad002bfIan Romanick this->reladdr = reg.reladdr; 140cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke} 141cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 142cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkedst_reg::dst_reg(src_reg reg) 143cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke{ 144cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->file = reg.file; 145cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = reg.index; 146cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->writemask = WRITEMASK_XYZW; 147cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->cond_mask = COND_TR; 148cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->reladdr = reg.reladdr; 149cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke} 150cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 151554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node { 152554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 153d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke /* Callers of this ralloc-based new need not call delete. It's 154d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke * easier to just ralloc_free 'ctx' (or any of its ancestors). */ 1557406898441bfec937840d575500fb6d43192310dEric Anholt static void* operator new(size_t size, void *ctx) 1567406898441bfec937840d575500fb6d43192310dEric Anholt { 1577406898441bfec937840d575500fb6d43192310dEric Anholt void *node; 1587406898441bfec937840d575500fb6d43192310dEric Anholt 159d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke node = rzalloc_size(ctx, size); 1607406898441bfec937840d575500fb6d43192310dEric Anholt assert(node != NULL); 1617406898441bfec937840d575500fb6d43192310dEric Anholt 1627406898441bfec937840d575500fb6d43192310dEric Anholt return node; 1637406898441bfec937840d575500fb6d43192310dEric Anholt } 1647406898441bfec937840d575500fb6d43192310dEric Anholt 165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op; 166fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst; 167fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src[3]; 168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** Pointer to the ir source this tree came from for debugging */ 169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_instruction *ir; 170854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLboolean cond_update; 171ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt bool saturate; 172d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler; /**< sampler index */ 173d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int tex_target; /**< One of TEXTURE_*_INDEX */ 174b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt GLboolean tex_shadow; 1757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ 177554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 179b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node { 180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 181caf974c5259f14b50257e8dd9b325a87378259afBrian Paul variable_storage(ir_variable *var, gl_register_file file, int index) 182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt : file(file), index(index), var(var) 183554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt { 184554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /* empty */ 185554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt } 186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 187caf974c5259f14b50257e8dd9b325a87378259afBrian Paul gl_register_file file; 188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; 189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_variable *var; /* variable that maps to this, if any */ 190554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 191554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node { 1937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic: 1947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig; 1957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * identifier of this function signature used by the program. 1987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * At the point that Mesa instructions for function calls are 2007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * generated, we don't know the address of the first instruction of 2017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * the function body. So we make the BranchTarget that is called a 2027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * small integer and rewrite them during set_branchtargets(). 2037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 2047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int sig_id; 2057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 2077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Pointer to first instruction of the function body. 2087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 2097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set during function body emits after main() is processed. 2107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 2117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *bgn_inst; 2127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 2147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Index of the first instruction of the function body in actual 2157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Mesa IR. 2167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 2177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set after convertion from ir_to_mesa_instruction to prog_instruction. 2187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 2197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int inst; 2207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** Storage for the return value. */ 222fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg return_reg; 2237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}; 2247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 225554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor { 226554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 227554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_visitor(); 228fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt ~ir_to_mesa_visitor(); 229554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *current_function; 2317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 232f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx; 233364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 234aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt struct gl_shader_program *shader_program; 2356d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri struct gl_shader_compiler_options *options; 236364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 237554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int next_temp; 238a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 239b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *find_variable_storage(ir_variable *var); 240554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *get_function_signature(ir_function_signature *sig); 2427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 243fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg get_temp(const glsl_type *type); 244fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke void reladdr_to_temp(ir_instruction *ir, src_reg *reg, int *num_reladdr); 245554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 246fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src_reg_for_float(float val); 247554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 248554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 249554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 250554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 251554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 252554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 253554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 254554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 255554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 256554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 257554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 258554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 259554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 260554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 261554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 262554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 263554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 264554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 265554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 266554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 267554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 268554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 269554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 27016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 271554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 272554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 273554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 274554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 275fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg result; 276554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 277b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 278b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 279554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 2817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 2827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 2837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 284554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 285554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 286554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 28701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op); 28801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 28901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 29001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0); 29101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 29201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 29301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1); 29401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 29501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 29601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 29701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg src0, src_reg src1, src_reg src2); 298554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 299ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick /** 300ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick * Emit the correct dot-product instruction for the type of arguments 301ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick */ 3027f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick ir_to_mesa_instruction * emit_dp(ir_instruction *ir, 3037f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick dst_reg dst, 3047f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick src_reg src0, 3057f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick src_reg src1, 3067f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick unsigned elements); 30701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 30801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke void emit_scalar(ir_instruction *ir, enum prog_opcode op, 30901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0); 31001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 31101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke void emit_scalar(ir_instruction *ir, enum prog_opcode op, 31201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1); 313904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 314f2616e56de8a48360cae8f269727b58490555f4dIan Romanick void emit_scs(ir_instruction *ir, enum prog_opcode op, 315fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst, const src_reg &src); 316f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 31779a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_mad(ir_expression *ir, 3183f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 319ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick bool try_emit_mad_for_and_not(ir_expression *ir, 320ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick int mul_operand); 32179a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_sat(ir_expression *ir); 3223f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 32311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick void emit_swz(ir_expression *ir); 32411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 325c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool process_move_condition(ir_rvalue *ir); 326c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 32734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt void copy_propagate(void); 32834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 329364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 330554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 331554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 332ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkesrc_reg undef_src = src_reg(PROGRAM_UNDEFINED, 0, NULL); 33384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 334ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkedst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP); 335c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 336ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkedst_reg address_reg = dst_reg(PROGRAM_ADDRESS, WRITEMASK_X); 3370161515c395c44233529c8d51f823b60050bc7baEric Anholt 338f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulstatic int 339f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulswizzle_for_size(int size) 3400161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 3410161515c395c44233529c8d51f823b60050bc7baEric Anholt int size_swizzles[4] = { 3420161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 3430161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 3440161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 3450161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 3460161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 3470161515c395c44233529c8d51f823b60050bc7baEric Anholt 3489fea9e5e2115bcb52435648d2ef753638733d7d9Ian Romanick assert((size >= 1) && (size <= 4)); 3490161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 3500161515c395c44233529c8d51f823b60050bc7baEric Anholt} 3510161515c395c44233529c8d51f823b60050bc7baEric Anholt 35284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 35301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 35401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 35501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg src0, src_reg src1, src_reg src2) 35684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 357364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 358f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 359f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 360f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 361f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 362f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 363f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 364f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 365f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 366f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 367f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 368f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 369f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 370f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 371f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 372f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 373f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 374ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_ARL, address_reg, *dst.reladdr); 375f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 376f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 377f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 37884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 37984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 380461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst = dst; 381461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[0] = src0; 382461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[1] = src1; 383461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[2] = src2; 384c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 38584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function = NULL; 3877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3880161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 38984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 39184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 39284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 39501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 39601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1) 39784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 398ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, dst, src0, src1, undef_src); 39984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 40084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 40184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 40201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 40301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0) 404bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 4055a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(dst.writemask != 0); 406ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, dst, src0, undef_src, undef_src); 407bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 408bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 409021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 41001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op) 411021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 412ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); 413021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 414021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 4157f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanickir_to_mesa_instruction * 41601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_dp(ir_instruction *ir, 41701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1, 41801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke unsigned elements) 419ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick{ 420ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick static const gl_inst_opcode dot_opcodes[] = { 421ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick OPCODE_DP2, OPCODE_DP3, OPCODE_DP4 422ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick }; 423ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 4247f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick return emit(ir, dot_opcodes[elements - 2], dst, src0, src1); 425ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick} 426ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 42712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 42812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 42912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 43212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 43312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 43412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 43512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 43601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op, 43701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 43801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg orig_src0, src_reg orig_src1) 43912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 44012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 441315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 44412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 44512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 44612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 44712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 448582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 44912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 450fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src0 = orig_src0; 451fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src1 = orig_src1; 45212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 45312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 45412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 45512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 456904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 457904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 45812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 459f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 460f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 461f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 462f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 463904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 464904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 465904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 46612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 46712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 46812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 469904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 470904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 471904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 472904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 47312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 47401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, op, dst, src0, src1); 475461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = this_mask; 47612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 47712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 47812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 47912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 480904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 48101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op, 48201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0) 483904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 484ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke src_reg undef = undef_src; 485904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 486904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 487904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 48801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, op, dst, src0, undef); 489904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 490904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 491f2616e56de8a48360cae8f269727b58490555f4dIan Romanick/** 492f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Emit an OPCODE_SCS instruction 493f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 494f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * The \c SCS opcode functions a bit differently than the other Mesa (or 495f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * ARB_fragment_program) opcodes. Instead of splatting its result across all 496f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * four components of the destination, it writes one value to the \c x 497f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * component and another value to the \c y component. 498f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 499f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param ir IR instruction being processed 500f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which 501f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * value is desired. 502f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param dst Destination register 503f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param src Source register 504f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 505f2616e56de8a48360cae8f269727b58490555f4dIan Romanickvoid 506f2616e56de8a48360cae8f269727b58490555f4dIan Romanickir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op, 507fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst, 508fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke const src_reg &src) 509f2616e56de8a48360cae8f269727b58490555f4dIan Romanick{ 510f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Vertex programs cannot use the SCS opcode. 511f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 512f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 51301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, op, dst, src); 514f2616e56de8a48360cae8f269727b58490555f4dIan Romanick return; 515f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 516f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 517f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned component = (op == OPCODE_SIN) ? 0 : 1; 518f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned scs_mask = (1U << component); 519f2616e56de8a48360cae8f269727b58490555f4dIan Romanick int done_mask = ~dst.writemask; 520fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg tmp; 521f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 522f2616e56de8a48360cae8f269727b58490555f4dIan Romanick assert(op == OPCODE_SIN || op == OPCODE_COS); 523f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 524f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there are compnents in the destination that differ from the component 525f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * that will be written by the SCS instrution, we'll need a temporary. 526f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 527f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (scs_mask != unsigned(dst.writemask)) { 528f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp = get_temp(glsl_type::vec4_type); 529f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 530f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 531f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned i = 0; i < 4; i++) { 532f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned this_mask = (1U << i); 533fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src0 = src; 534f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 535f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if ((done_mask & this_mask) != 0) 536f2616e56de8a48360cae8f269727b58490555f4dIan Romanick continue; 537f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 538f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* The source swizzle specified which component of the source generates 539f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * sine / cosine for the current component in the destination. The SCS 540f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * instruction requires that this value be swizzle to the X component. 541f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Replace the current swizzle with a swizzle that puts the source in 542f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the X component. 543f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 544f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned src0_swiz = GET_SWZ(src.swizzle, i); 545f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 546f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 547f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0_swiz, src0_swiz); 548f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned j = i + 1; j < 4; j++) { 549f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 550f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 551f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 552f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 553f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (!(done_mask & (1 << j)) && 554f2616e56de8a48360cae8f269727b58490555f4dIan Romanick GET_SWZ(src0.swizzle, j) == src0_swiz) { 555f2616e56de8a48360cae8f269727b58490555f4dIan Romanick this_mask |= (1 << j); 556f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 557f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 558f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 559f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this_mask != scs_mask) { 560f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_instruction *inst; 561cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg tmp_dst = dst_reg(tmp); 562f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 563f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction. 564f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 56501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, OPCODE_SCS, tmp_dst, src0); 566461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = scs_mask; 567f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 568f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Move the result of the SCS instruction to the desired location in 569f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the destination. 570f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 571f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp.swizzle = MAKE_SWIZZLE4(component, component, 572f2616e56de8a48360cae8f269727b58490555f4dIan Romanick component, component); 57301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, OPCODE_SCS, dst, tmp); 574461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = this_mask; 575f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } else { 576f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction to write directly to the destination. 577f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 57801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *inst = emit(ir, OPCODE_SCS, dst, src0); 579461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = scs_mask; 580f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 581f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 582f2616e56de8a48360cae8f269727b58490555f4dIan Romanick done_mask |= this_mask; 583f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 584f2616e56de8a48360cae8f269727b58490555f4dIan Romanick} 585f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 58607e9b9049f94ceb443eac1206cc3f9e1e51ac6c1Kenneth Graunkesrc_reg 5870161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 588b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 589fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src(PROGRAM_CONSTANT, -1, NULL); 5901d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 591461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = _mesa_add_unnamed_constant(this->prog->Parameters, 5926d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (const gl_constant_value *)&val, 1, &src.swizzle); 5931d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 594461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke return src; 5951d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 5961d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 5972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 5982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 5992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 6002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 6012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 6022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 6032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 6042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 6052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 6062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 6072c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 608a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 6099968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 610a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 611a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 612a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 613a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 614a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 615a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 616a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 617a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 6182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 6195c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick assert(type->length > 0); 6202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 6212c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 6222c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 6232c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 6242c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 6252c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6262c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 6278d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt case GLSL_TYPE_SAMPLER: 6280924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Samplers take up one slot in UNIFORMS[], but they're baked in 6290924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * at link time. 6308d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt */ 6310924ba0c3496160a134d37cec800f902ae805b9cEric Anholt return 1; 6322c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 6332c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 63419acfa42ed47edb63f5ec3de8051a3102e62e96bJosé Fonseca return 0; 6352c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6362c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 6372c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 638d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 639d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 640d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 641d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 642d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 643d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 644fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkesrc_reg 645d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 646d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 647fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 648d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 649461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.file = PROGRAM_TEMPORARY; 650461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = next_temp; 651461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.reladdr = NULL; 652d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 653d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 65420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (type->is_array() || type->is_record()) { 655461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = SWIZZLE_NOOP; 65620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } else { 6574c7e215c7bb09f827df630cbfc80e87869351f18Eric Anholt src.swizzle = swizzle_for_size(type->vector_elements); 65820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 659461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.negate = 0; 660d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 661461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke return src; 662d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 663d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 664b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 665a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 66684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 667a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 668b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 670b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 671b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 67284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6730161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 674a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 67584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 67684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 677a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 678a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 67984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 68084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 68184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 68284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 6834a962170d7cf4243d6ae156fca20a6167388925dEric Anholt if (strcmp(ir->name, "gl_FragCoord") == 0) { 6844a962170d7cf4243d6ae156fca20a6167388925dEric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 6854a962170d7cf4243d6ae156fca20a6167388925dEric Anholt 6864a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->OriginUpperLeft = ir->origin_upper_left; 6874a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->PixelCenterInteger = ir->pixel_center_integer; 688a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace 689a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace } else if (strcmp(ir->name, "gl_FragDepth") == 0) { 690a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 691a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace switch (ir->depth_layout) { 692a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_none: 693a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE; 694a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 695a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_any: 696a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY; 697a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 698a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_greater: 699a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER; 700a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 701a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_less: 702a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS; 703a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 704a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_unchanged: 705a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED; 706a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 707a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace default: 708a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace assert(0); 709a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 710a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace } 7114a962170d7cf4243d6ae156fca20a6167388925dEric Anholt } 7126c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7136c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 7146c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt unsigned int i; 71589d81ab16c05818b290ed735c1343d3abde449bfIan Romanick const ir_state_slot *const slots = ir->state_slots; 71689d81ab16c05818b290ed735c1343d3abde449bfIan Romanick assert(ir->state_slots != NULL); 7176c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7186c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* Check if this statevar's setup in the STATE file exactly 7196c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * matches how we'll want to reference it as a 7206c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * struct/array/whatever. If not, then we need to move it into 7216c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * temporary storage and hope that it'll get copy-propagated 7226c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * out. 7236c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt */ 72489d81ab16c05818b290ed735c1343d3abde449bfIan Romanick for (i = 0; i < ir->num_state_slots; i++) { 72589d81ab16c05818b290ed735c1343d3abde449bfIan Romanick if (slots[i].swizzle != SWIZZLE_XYZW) { 7266c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt break; 7276c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7286c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7296c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 73007e9b9049f94ceb443eac1206cc3f9e1e51ac6c1Kenneth Graunke variable_storage *storage; 731fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst; 73289d81ab16c05818b290ed735c1343d3abde449bfIan Romanick if (i == ir->num_state_slots) { 7336c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* We'll set the index later. */ 7346c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 7356c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 7366c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 737ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke dst = undef_dst; 7386c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 73989d81ab16c05818b290ed735c1343d3abde449bfIan Romanick /* The variable_storage constructor allocates slots based on the size 74089d81ab16c05818b290ed735c1343d3abde449bfIan Romanick * of the type. However, this had better match the number of state 74189d81ab16c05818b290ed735c1343d3abde449bfIan Romanick * elements that we're going to copy into the new temporary. 74289d81ab16c05818b290ed735c1343d3abde449bfIan Romanick */ 743847f991a87b9549eb89a521edb7cd149005006bbBrian Paul assert((int) ir->num_state_slots == type_size(ir->type)); 74489d81ab16c05818b290ed735c1343d3abde449bfIan Romanick 7456c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 7466c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp); 7476c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 7486c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp += type_size(ir->type); 7496c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 750cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst = dst_reg(src_reg(PROGRAM_TEMPORARY, storage->index, NULL)); 7516c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7526c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7536c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 754a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick for (unsigned int i = 0; i < ir->num_state_slots; i++) { 755a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick int index = _mesa_add_state_reference(this->prog->Parameters, 756a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick (gl_state_index *)slots[i].tokens); 757a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick 758a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick if (storage->file == PROGRAM_STATE_VAR) { 759a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick if (storage->index == -1) { 760a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick storage->index = index; 7616c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 762a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick assert(index == storage->index + (int)i); 7636c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 764a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick } else { 765fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src(PROGRAM_STATE_VAR, index, NULL); 766a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick src.swizzle = slots[i].swizzle; 76701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, dst, src); 768a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick /* even a float takes up a whole vec4 reg in a struct/array. */ 769a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick dst.index++; 7706c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7716c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 772a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick 7736c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (storage->file == PROGRAM_TEMPORARY && 774847f991a87b9549eb89a521edb7cd149005006bbBrian Paul dst.index != storage->index + (int) ir->num_state_slots) { 7758aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(this->shader_program, 7768aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "failed to load builtin uniform `%s' " 7778aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "(%d/%d regs loaded)\n", 7788aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick ir->name, dst.index - storage->index, 7798aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick type_size(ir->type)); 7806c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7816c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 78284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 78384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 78484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 78584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 78684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 7870f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_dereference_variable *counter = NULL; 7880f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7890f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->counter != NULL) 790dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter = new(mem_ctx) ir_dereference_variable(ir->counter); 7910f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7920f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->from != NULL) { 7930f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick assert(ir->counter != NULL); 7940f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 795dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_assignment *a = 796dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_assignment(counter, ir->from, NULL); 7970f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7980f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 7990f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 80084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 80101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_BGNLOOP); 8020f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8030f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->to) { 8040f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 805dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type, 806dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter, ir->to); 807dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_if *if_stmt = new(mem_ctx) ir_if(e); 8080f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 809dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_loop_jump *brk = 810dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); 8110f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8120f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->then_instructions.push_tail(brk); 8130f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8140f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->accept(this); 8150f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 8160f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 81764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 8180f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8190f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->increment) { 8200f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 821dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_expression(ir_binop_add, counter->type, 822dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter, ir->increment); 8230f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 824dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_assignment *a = 825dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_assignment(counter, e, NULL); 8260f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8270f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 8280f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 8290f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 83001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_ENDLOOP); 83184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 83284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 83384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 83484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 83584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 83664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 83764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 83801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_BRK); 83964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 84064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 84101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_CONT); 84264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 84364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 84484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 84584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 84884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 84984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 85084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 85184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 85284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 85384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 85484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 85584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 85684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 85784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 85884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 86084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 86184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 86284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 86384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 86784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 86984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 87084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 87184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 87284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 87384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 87484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 87584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 87679a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 8773f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 8783f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 8793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 880fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg a, b, c; 8813f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8823f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 8833f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 8843f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 8853f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8863f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 8873f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 8883f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 8893f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 8903f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 8913f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 8923f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8933f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 89401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, c); 8953f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8963f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 8973f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 8983f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 899ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick/** 900ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * Emit OPCODE_MAD(a, -b, a) instead of AND(a, NOT(b)) 901ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 902ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * The logic values are 1.0 for true and 0.0 for false. Logical-and is 903ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * implemented using multiplication, and logical-or is implemented using 904ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * addition. Logical-not can be implemented as (true - x), or (1.0 - x). 905ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * As result, the logical expression (a & !b) can be rewritten as: 906ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 907ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a * !b 908ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a * (1 - b) 909ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - (a * 1) - (a * b) 910ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a + -(a * b) 911ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a + (a * -b) 912ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 913ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * This final expression can be implemented as a single MAD(a, -b, a) 914ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * instruction. 915ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick */ 916ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanickbool 917ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanickir_to_mesa_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand) 918ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick{ 919ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick const int other_operand = 1 - try_operand; 920ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick src_reg a, b; 921ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 922ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick ir_expression *expr = ir->operands[try_operand]->as_expression(); 923ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (!expr || expr->operation != ir_unop_logic_not) 924ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return false; 925ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 926ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick ir->operands[other_operand]->accept(this); 927ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick a = this->result; 928ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick expr->operands[0]->accept(this); 929ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick b = this->result; 930ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 931ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick b.negate = ~b.negate; 932ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 933ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick this->result = get_temp(ir->type); 934ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, a); 935ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 936ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return true; 937ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick} 938ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 93979a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 940ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholtir_to_mesa_visitor::try_emit_sat(ir_expression *ir) 941ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt{ 942ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt /* Saturates were only introduced to vertex programs in 943ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt * NV_vertex_program3, so don't give them to drivers in the VP. 944ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt */ 945ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 946ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 947ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 948ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 949ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (!sat_src) 950ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 951ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 952ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt sat_src->accept(this); 953fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src = this->result; 954ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 95562722d90af9d43d889af33b080a682f2004e049cEric Anholt /* If we generated an expression instruction into a temporary in 95662722d90af9d43d889af33b080a682f2004e049cEric Anholt * processing the saturate's operand, apply the saturate to that 95762722d90af9d43d889af33b080a682f2004e049cEric Anholt * instruction. Otherwise, generate a MOV to do the saturate. 95862722d90af9d43d889af33b080a682f2004e049cEric Anholt * 95962722d90af9d43d889af33b080a682f2004e049cEric Anholt * Note that we have to be careful to only do this optimization if 96062722d90af9d43d889af33b080a682f2004e049cEric Anholt * the instruction in question was what generated src->result. For 96162722d90af9d43d889af33b080a682f2004e049cEric Anholt * example, ir_dereference_array might generate a MUL instruction 96262722d90af9d43d889af33b080a682f2004e049cEric Anholt * to create the reladdr, and return us a src reg using that 96362722d90af9d43d889af33b080a682f2004e049cEric Anholt * reladdr. That MUL result is not the value we're trying to 96462722d90af9d43d889af33b080a682f2004e049cEric Anholt * saturate. 96562722d90af9d43d889af33b080a682f2004e049cEric Anholt */ 96662722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_expression *sat_src_expr = sat_src->as_expression(); 96762722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_to_mesa_instruction *new_inst; 96862722d90af9d43d889af33b080a682f2004e049cEric Anholt new_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 96962722d90af9d43d889af33b080a682f2004e049cEric Anholt if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul || 97062722d90af9d43d889af33b080a682f2004e049cEric Anholt sat_src_expr->operation == ir_binop_add || 97162722d90af9d43d889af33b080a682f2004e049cEric Anholt sat_src_expr->operation == ir_binop_dot)) { 97262722d90af9d43d889af33b080a682f2004e049cEric Anholt new_inst->saturate = true; 97362722d90af9d43d889af33b080a682f2004e049cEric Anholt } else { 97462722d90af9d43d889af33b080a682f2004e049cEric Anholt this->result = get_temp(ir->type); 97562722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_to_mesa_instruction *inst; 97662722d90af9d43d889af33b080a682f2004e049cEric Anholt inst = emit(ir, OPCODE_MOV, dst_reg(this->result), src); 97762722d90af9d43d889af33b080a682f2004e049cEric Anholt inst->saturate = true; 97862722d90af9d43d889af33b080a682f2004e049cEric Anholt } 979ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 980ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return true; 981ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt} 982ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 98384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 984f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 985fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg *reg, int *num_reladdr) 986f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 987f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 988f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 989f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 990ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_ARL, address_reg, *reg->reladdr); 991f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 992f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 993fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 994f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 99501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, dst_reg(temp), *reg); 996f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 997f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 998f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 999f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 1000f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 1001f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 1002f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 100311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickir_to_mesa_visitor::emit_swz(ir_expression *ir) 100411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick{ 100511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Assume that the vector operator is in a form compatible with OPCODE_SWZ. 100611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This means that each of the operands is either an immediate value of -1, 100711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * 0, or 1, or is a component from one source register (possibly with 100811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * negation). 100911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 101011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick uint8_t components[4] = { 0 }; 101111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick bool negate[4] = { false }; 101211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_variable *var = NULL; 101311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick for (unsigned i = 0; i < ir->type->vector_elements; i++) { 101511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_rvalue *op = ir->operands[i]; 101611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 101811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick while (op != NULL) { 102011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick switch (op->ir_type) { 102111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_constant: { 102211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 102411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick const ir_constant *const c = op->as_constant(); 102611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (c->is_one()) { 102711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 102811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_zero()) { 102911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ZERO; 103011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_negative_one()) { 103111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 103211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 103311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else { 103411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"SWZ constant must be 0.0 or 1.0."); 103511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 103611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 103811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 103911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 104011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 104111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_dereference_variable: { 104211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 104311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick (ir_dereference_variable *) op; 104411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 104511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert((var == NULL) || (deref->var == var)); 104611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_X; 104711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick var = deref->var; 104811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 104911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 105011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 105111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_expression: { 105311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_expression *const expr = (ir_expression *) op; 105411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(expr->operation == ir_unop_neg); 105611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 105711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = expr->operands[0]; 105911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 106011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 106111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_swizzle: { 106311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_swizzle *const swiz = (ir_swizzle *) op; 106411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = swiz->mask.x; 106611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = swiz->val; 106711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 106811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 106911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick default: 107111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 107211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 107311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 107411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 107511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 107611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(var != NULL); 107811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 108011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick new(mem_ctx) ir_dereference_variable(var); 108111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 108211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result.file = PROGRAM_UNDEFINED; 108311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(this); 108411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (this->result.file == PROGRAM_UNDEFINED) { 108511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_print_visitor v; 108611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick printf("Failed to get tree for expression operand:\n"); 108711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(&v); 108811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick exit(1); 108911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 109011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 1091fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 109211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 109311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src = this->result; 109411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.swizzle = MAKE_SWIZZLE4(components[0], 109511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[1], 109611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[2], 109711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[3]); 109811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.negate = ((unsigned(negate[0]) << 0) 109911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[1]) << 1) 110011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[2]) << 2) 110111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[3]) << 3)); 110211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 110311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Storage for our result. Ideally for an assignment we'd be using the 110411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * actual storage for the result here, instead. 110511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 1106fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke const src_reg result_src = get_temp(ir->type); 1107cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg result_dst = dst_reg(result_src); 110811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 110911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Limit writes to the channels that will be used by result_src later. 111011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This does limit this temp's use as a temporary for multi-instruction 111111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * sequences. 111211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 111311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick result_dst.writemask = (1 << ir->type->vector_elements) - 1; 111411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 111501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SWZ, result_dst, src); 111611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result = result_src; 111711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick} 111811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 111911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickvoid 112084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 112184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 112284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 1123fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg op[Elements(ir->operands)]; 1124fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg result_src; 1125fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg result_dst; 112684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 11273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 11283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 11293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 11303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 11313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 11333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 1135ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 1136ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b)) 1137ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick */ 1138ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (ir->operation == ir_binop_logic_and) { 1139ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (try_emit_mad_for_and_not(ir, 1)) 1140ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return; 1141ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (try_emit_mad_for_and_not(ir, 0)) 1142ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return; 1143ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick } 1144ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 1145ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (try_emit_sat(ir)) 1146ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return; 11473f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 114811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (ir->operation == ir_quadop_vector) { 114911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->emit_swz(ir); 115011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 115111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 115211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 115384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 11540161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 115584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 11560161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 115784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 115884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 115984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 116084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 116184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 116284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 11638364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 11644ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 11654ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 11664ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 11674ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 116884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 116984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1170eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt int vector_elements = ir->operands[0]->type->vector_elements; 1171eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt if (ir->operands[1]) { 1172eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt vector_elements = MAX2(vector_elements, 1173eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt ir->operands[1]->type->vector_elements); 1174eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt } 1175eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt 11760161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 11770161515c395c44233529c8d51f823b60050bc7baEric Anholt 11780161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 11790161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 11800161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 11818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 11820161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 1183cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke result_dst = dst_reg(result_src); 11849cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 11859cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 11869cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 11879cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 11889cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 118984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 119084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 11911d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 11926ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick /* Previously 'SEQ dst, src, 0.0' was used for this. However, many 11936ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * older GPUs implement SEQ using multiple instructions (i915 uses two 11946ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * SGE instructions and a MUL instruction). Since our logic values are 11956ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * 0.0 and 1.0, 1-x also implements !x. 11966ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick */ 11976ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick op[0].negate = ~op[0].negate; 11986ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick emit(ir, OPCODE_ADD, result_dst, op[0], src_reg_for_float(1.0)); 11991d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1200c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 12010161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 12020161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 1203c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 1204524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 120501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_ABS, result_dst, op[0]); 1206524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 12073acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 120801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SSG, result_dst, op[0]); 12093acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 12108761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 121101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RCP, result_dst, op[0]); 12128761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 1213524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 12148c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 121501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_EX2, result_dst, op[0]); 12168c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 1217bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt case ir_unop_exp: 12188c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 1219bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 12208c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 12218c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 122201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_LG2, result_dst, op[0]); 12238c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 12243c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 122501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_SIN, result_dst, op[0]); 12263c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 12273c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 122801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_COS, result_dst, op[0]); 12293c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 1230f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_sin_reduced: 1231f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_SIN, result_dst, op[0]); 1232f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1233f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_cos_reduced: 1234f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_COS, result_dst, op[0]); 1235f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1236ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 1237ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 123801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_DDX, result_dst, op[0]); 1239ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1240ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 124101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_DDY, result_dst, op[0]); 1242ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1243ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 12443a5ce85cfa4914711e56c8cf831699242618928eIan Romanick case ir_unop_noise: { 12453a5ce85cfa4914711e56c8cf831699242618928eIan Romanick const enum prog_opcode opcode = 12463a5ce85cfa4914711e56c8cf831699242618928eIan Romanick prog_opcode(OPCODE_NOISE1 12473a5ce85cfa4914711e56c8cf831699242618928eIan Romanick + (ir->operands[0]->type->vector_elements) - 1); 12483a5ce85cfa4914711e56c8cf831699242618928eIan Romanick assert((opcode >= OPCODE_NOISE1) && (opcode <= OPCODE_NOISE4)); 12493a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 125001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, opcode, result_dst, op[0]); 12513a5ce85cfa4914711e56c8cf831699242618928eIan Romanick break; 12523a5ce85cfa4914711e56c8cf831699242618928eIan Romanick } 12533a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 125484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 125501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 125684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 125784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 125801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SUB, result_dst, op[0], op[1]); 125984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 12609b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 126184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 126201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 126384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 126484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 12659a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1266e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke break; 1267411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 1268e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */ 1269e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke assert(ir->type->is_integer()); 1270e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 1271411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 127238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 127338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 127401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SLT, result_dst, op[0], op[1]); 127538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 127701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SGT, result_dst, op[0], op[1]); 127838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 128001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SLE, result_dst, op[0], op[1]); 128138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 128238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 128301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SGE, result_dst, op[0], op[1]); 128438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 128538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 128601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 12874dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12884dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_nequal: 128901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 12904dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12914dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_all_equal: 12926992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "==" operator producing a scalar boolean. */ 12936992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 12946992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 1295fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 129601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]); 1297ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick 1298ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick /* After the dot-product, the value will be an integer on the 1299ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * range [0,4]. Zero becomes 1.0, and positive values become zero. 1300ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick */ 130101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_dp(ir, result_dst, temp, temp, vector_elements); 1302ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick 1303ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick /* Negating the result of the dot-product gives values on the range 1304ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * [-4, 0]. Zero becomes 1.0, and negative values become zero. This 1305ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * achieved using SGE. 1306ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick */ 1307ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick src_reg sge_src = result_src; 1308ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick sge_src.negate = ~sge_src.negate; 1309ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick emit(ir, OPCODE_SGE, result_dst, sge_src, src_reg_for_float(0.0)); 13106992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 131101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 13126992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 131338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 13144dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_any_nequal: 13156992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "!=" operator producing a scalar boolean. */ 13166992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 13176992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 1318fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 131901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]); 1320e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick 1321e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* After the dot-product, the value will be an integer on the 1322e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * range [0,4]. Zero stays zero, and positive values become 1.0. 1323e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1324e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick ir_to_mesa_instruction *const dp = 1325e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick emit_dp(ir, result_dst, temp, temp, vector_elements); 1326e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 1327e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* The clamping to [0,1] can be done for free in the fragment 1328e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * shader with a saturate. 1329e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1330e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick dp->saturate = true; 1331e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick } else { 1332e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* Negating the result of the dot-product gives values on the range 1333e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * [-4, 0]. Zero stays zero, and negative values become 1.0. This 1334e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * achieved using SLT. 1335e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1336e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick src_reg slt_src = result_src; 1337e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick slt_src.negate = ~slt_src.negate; 1338e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 1339e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick } 13406992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 134101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 13426992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 13436992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt break; 13445e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 134592ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick case ir_unop_any: { 1346ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 134792ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick 134892ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* After the dot-product, the value will be an integer on the 134992ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * range [0,4]. Zero stays zero, and positive values become 1.0. 135092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 135192ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick ir_to_mesa_instruction *const dp = 135292ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick emit_dp(ir, result_dst, op[0], op[0], 135392ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick ir->operands[0]->type->vector_elements); 135492ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 135592ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* The clamping to [0,1] can be done for free in the fragment 135692ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * shader with a saturate. 135792ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 135892ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick dp->saturate = true; 135992ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } else { 136092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* Negating the result of the dot-product gives values on the range 136192ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * [-4, 0]. Zero stays zero, and negative values become 1.0. This 136292ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * is achieved using SLT. 136392ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 136492ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick src_reg slt_src = result_src; 136592ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick slt_src.negate = ~slt_src.negate; 136692ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 136792ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } 13685e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 136992ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } 13705e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 13716992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt case ir_binop_logic_xor: 137201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 137338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 137438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 137541f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick case ir_binop_logic_or: { 137641f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* After the addition, the value will be an integer on the 137741f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * range [0,2]. Zero stays zero, and positive values become 1.0. 137841f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 137941f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick ir_to_mesa_instruction *add = 138041f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 138141f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 138241f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* The clamping to [0,1] can be done for free in the fragment 138341f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * shader with a saturate. 138441f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 138541f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick add->saturate = true; 138641f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } else { 138741f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* Negating the result of the addition gives values on the range 138841f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * [-2, 0]. Zero stays zero, and negative values become 1.0. This 138941f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * is achieved using SLT. 139041f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 139141f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick src_reg slt_src = result_src; 139241f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick slt_src.negate = ~slt_src.negate; 139341f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 139441f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } 13954380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 139641f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } 13974380099c98119611ceee684669d00be26195c7d7Eric Anholt 13984380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 13994380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 140001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 14014380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 14024380099c98119611ceee684669d00be26195c7d7Eric Anholt 140384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 1404ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 1405ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type == ir->operands[1]->type); 140601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_dp(ir, result_dst, op[0], op[1], 140701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir->operands[0]->type->vector_elements); 140884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 14099be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 141084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 14114f189b3bf57a6500953dac49105f160af5fa6468Marek Olšák /* sqrt(x) = x * rsq(x). */ 141201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); 141301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, result_src, op[0]); 1414c9039fdb167865547dc9b3828d69b99209344999Brian Paul /* For incoming channels <= 0, set the result to 0. */ 1415c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0].negate = ~op[0].negate; 141601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, result_dst, 1417c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0], result_src, src_reg_for_float(0.0)); 141884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 1419878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 142001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); 1421878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 142250ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 1423006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_u2f: 1424d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 1425d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 1426006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_i2u: 1427006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_u2i: 1428423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 14290161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 143050ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 1431423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 143201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_TRUNC, result_dst, op[0]); 1433423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 14341d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 1435411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 143601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, 143766afcb560771b6ba6ad668156e9f442e86b9a7a2Eric Anholt op[0], src_reg_for_float(0.0)); 14381d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1439c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 144001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_TRUNC, result_dst, op[0]); 1441c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1442c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 14430161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 144401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FLR, result_dst, op[0]); 14450161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 1446c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1447c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 144801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FLR, result_dst, op[0]); 1449c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1450d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 145101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FRC, result_dst, op[0]); 1452d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 1453d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 1454c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 145501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MIN, result_dst, op[0], op[1]); 1456c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1457c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 145801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MAX, result_dst, op[0], op[1]); 1459c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1460904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 146101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_POW, result_dst, op[0], op[1]); 1462904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 1463e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 14641d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt /* GLSL 1.30 integer ops are unsupported in Mesa IR, but since 14651d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt * hardware backends have no way to avoid Mesa IR generation 14661d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt * even if they don't use it, we need to emit "something" and 14671d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt * continue. 14681d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt */ 1469e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 1470e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 1471e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 1472e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 1473e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 14741d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 14751d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt break; 14761d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt 14771d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt case ir_unop_bit_not: 1478d85d25dd1f4fd281bd210ba6ba5135ba1e3b535fKenneth Graunke case ir_unop_round_even: 14791d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt emit(ir, OPCODE_MOV, result_dst, op[0]); 1480e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 148111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 148211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_quadop_vector: 148311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* This operation should have already been handled. 148411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 148511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 148611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 148784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 1488b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 14890161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 149084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 149184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 149284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 149384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 149484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 149584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1496fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 149784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 149884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 149984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1500b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 1501b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 1502b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 1503b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 150484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 150584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 1506461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 1507461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke assert(src.file != PROGRAM_UNDEFINED); 150884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 150984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 151084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 151184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 151284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 1513461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x); 151484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 151584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 1516461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y); 151784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 151884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 1519461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z); 152084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 152184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 1522461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w); 152384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 152484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 152584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 152684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 152784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 152884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 1529698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 153084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 153184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 153284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1533461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 153484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1535461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke this->result = src; 153684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 153784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 153884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 153984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 154084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1541b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 1542304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul ir_variable *var = ir->var; 154384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15448364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1545304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul switch (var->mode) { 15468364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 1547304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1548304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul var->location); 1549b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 15508364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 15518364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 15528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1553a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1554a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * including deprecated builtins (like gl_Color), 1555a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * user-assigned generic attributes (glBindVertexLocation), 1556a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * and user-defined varyings. 1557a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1558a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1559f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1560304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul assert(var->location != -1); 15612b7be12d5467096362073260911a380c64c772d0Brian Paul entry = new(mem_ctx) variable_storage(var, 15622b7be12d5467096362073260911a380c64c772d0Brian Paul PROGRAM_INPUT, 15632b7be12d5467096362073260911a380c64c772d0Brian Paul var->location); 156486471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul break; 156586471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul case ir_var_out: 156686471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul assert(var->location != -1); 156786471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul entry = new(mem_ctx) variable_storage(var, 156886471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul PROGRAM_OUTPUT, 156986471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul var->location); 15708364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 15717baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul case ir_var_system_value: 15727baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul entry = new(mem_ctx) variable_storage(var, 15737baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul PROGRAM_SYSTEM_VALUE, 15747baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul var->location); 15757baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul break; 15768364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 15777e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1578304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1579b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1580b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1581224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 1582304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul next_temp += type_size(var->type); 15838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 158484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 15858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 15868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1587304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul printf("Failed to make storage for %s\n", var->name); 15888364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1589224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 159084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 159184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1592fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke this->result = src_reg(entry->file, entry->index, var->type); 159384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 159484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 159584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 159684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 159784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1598ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 1599fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 16008258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1601ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1602ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 16034e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 1604ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 1605461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 16064e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 16074d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 1608461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index += index->value.i[0] * element_size; 16094e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 16104d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 16114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 16124d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 16134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 16144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 16158258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 1616fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg index_reg; 16178258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 16184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 16194d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 16204d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 16214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1622f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 162301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, dst_reg(index_reg), 162401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke this->result, src_reg_for_float(element_size)); 1625bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 16264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 1627d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick /* If there was already a relative address register involved, add the 1628d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick * new and the old together to get the new offset. 1629d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick */ 1630d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick if (src.reladdr != NULL) { 1631d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick src_reg accum_reg = get_temp(glsl_type::float_type); 1632d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1633d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick emit(ir, OPCODE_ADD, dst_reg(accum_reg), 1634d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick index_reg, *src.reladdr); 1635d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1636d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick index_reg = accum_reg; 1637d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick } 1638d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1639fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src.reladdr = ralloc(mem_ctx, src_reg); 1640461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke memcpy(src.reladdr, &index_reg, sizeof(index_reg)); 16414e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 164284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 164384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 164485e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 1645461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = swizzle_for_size(ir->type->vector_elements); 164685e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 1647461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = SWIZZLE_NOOP; 164884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1649461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke this->result = src; 165084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 165184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 16522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 16532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 16542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 16552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 16560161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 16572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 16582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16590161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 16602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 16620161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 16632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 16642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 16652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 16662d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16672d577ee730c30caacf711babde6542766aa0b655Ian Romanick /* If the type is smaller than a vec4, replicate the last channel out. */ 16682d577ee730c30caacf711babde6542766aa0b655Ian Romanick if (ir->type->is_scalar() || ir->type->is_vector()) 16692d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 16702d577ee730c30caacf711babde6542766aa0b655Ian Romanick else 16712d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = SWIZZLE_NOOP; 16722d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16730161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 16742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 16752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 16772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 16782c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 16792c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 16802c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 1681fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkestatic dst_reg 1682fc63e37b971b641dfdff000ba353c4810414c20eIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v) 1683b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 16845a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* The LHS must be a dereference. If the LHS is a variable indexed array 16855a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * access of a vector, it must be separated into a series conditional moves 16865a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * before reaching this point (see ir_vec_index_to_cond_assign). 16875a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 16885a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->as_dereference()); 1689ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1690ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1691ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1692ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1693ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 16940161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 16950161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 16960161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 16972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 1698cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke return dst_reg(v->result); 1699cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1700cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1701c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick/** 1702c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Process the condition of a conditional assignment 1703c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1704c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Examines the condition of a conditional assignment to generate the optimal 1705c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * first operand of a \c CMP instruction. If the condition is a relational 1706c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 1707c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * used as the source for the \c CMP instruction. Otherwise the comparison 1708c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * is processed to a boolean result, and the boolean result is used as the 1709c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operand to the CMP instruction. 1710c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1711c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickbool 1712c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) 1713c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick{ 1714c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_rvalue *src_ir = ir; 1715c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool negate = true; 1716c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool switch_order = false; 1717c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1718c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_expression *const expr = ir->as_expression(); 1719c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if ((expr != NULL) && (expr->get_num_operands() == 2)) { 1720c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool zero_on_left = false; 1721c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1722c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (expr->operands[0]->is_zero()) { 1723c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[1]; 1724c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = true; 1725c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else if (expr->operands[1]->is_zero()) { 1726c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[0]; 1727c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = false; 1728c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1729c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1730c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* a is - 0 + - 0 + 1731c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a < 0) T F F ( a < 0) T F F 1732c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 < a) F F T (-a < 0) F F T 1733c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 1734c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 1735c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a > 0) F F T (-a < 0) F F T 1736c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 > a) T F F ( a < 0) T F F 1737c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 1738c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 1739c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1740c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Note that exchanging the order of 0 and 'a' in the comparison simply 1741c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * means that the value of 'a' should be negated. 1742c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1743c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (src_ir != ir) { 1744c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch (expr->operation) { 1745c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_less: 1746c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1747c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1748c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1749c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1750c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_greater: 1751c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1752c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1753c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1754c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1755c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_lequal: 1756c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1757c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1758c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1759c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1760c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_gequal: 1761c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1762c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1763c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1764c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1765c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick default: 1766c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* This isn't the right kind of comparison afterall, so make sure 1767c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * the whole condition is visited. 1768c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1769c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = ir; 1770c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1771c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1772c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1773c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1774c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1775c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir->accept(this); 1776c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1777c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 1778c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * condition we produced is 0.0 or 1.0. By flipping the sign, we can 1779c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * choose which value OPCODE_CMP produces without an extra instruction 1780c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * computing the condition. 1781c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1782c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (negate) 1783c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick this->result.negate = ~this->result.negate; 1784c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1785c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick return switch_order; 1786c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick} 1787c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 178884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 178984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 179084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1791fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg l; 1792fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r; 17937d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 179484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 179584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 179684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1797cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1798fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick l = get_assignment_lhs(ir->lhs, this); 1799cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 18005a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This should really set to the correct maximal writemask for each 18015a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: component written (in the loops below). This case can only 18025a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: occur for matrices, arrays, and structures. 18035a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 18045a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick if (ir->write_mask == 0) { 18055a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 18065a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 18075a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else if (ir->lhs->type->is_scalar()) { 1808b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 18095a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: W component of fragment shader output zero, work correctly. 18105a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 18115a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 18125a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else { 1813b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int swizzles[4]; 1814b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int first_enabled_chan = 0; 1815b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int rhs_chan = 0; 1816b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 18175a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->lhs->type->is_vector()); 18185a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = ir->write_mask; 1819b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1820b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1821b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) { 1822b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt first_enabled_chan = GET_SWZ(r.swizzle, i); 1823b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt break; 1824b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1825b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1826b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1827b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* Swizzle a small RHS vector into the channels being written. 1828b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * 1829b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * glsl ir treats write_mask as dictating how many channels are 1830b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * present on the RHS while Mesa IR treats write_mask as just 1831b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * showing which channels of the vec4 RHS get written. 1832b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt */ 1833b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1834b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) 1835b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 1836b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt else 1837b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = first_enabled_chan; 1838b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1839b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 1840b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[2], swizzles[3]); 18415a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } 18425a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick 18430161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 18440161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 184584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1846346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 1847c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick const bool switch_order = this->process_move_condition(ir->condition); 1848fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg condition = this->result; 18492d1789e667c4180777829f96856daf91326721b9Eric Anholt 18507d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 1851c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (switch_order) { 185201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, l, condition, src_reg(l), r); 1853c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else { 185401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, l, condition, r, src_reg(l)); 1855c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1856c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 18577d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 18587d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 18597d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 18602d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 18617d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 186201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 18637d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 18647d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 18657d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1866346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 186784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 186884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 186984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 187084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 187184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 187284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1873fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 18740a46497a4ee3325fab47929cb17cfe2525e1fc33Vinson Lee GLfloat stack_vals[4] = { 0 }; 18750bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 18760bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 187784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 18785b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt /* Unfortunately, 4 floats is all we can get into 18795b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store an 18805b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * aggregate constant and move each constant value into it. If we 18815b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * get lucky, copy propagation will eliminate the extra moves. 18825b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt */ 18835b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18845b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt if (ir->type->base_type == GLSL_TYPE_STRUCT) { 1885fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp_base = get_temp(ir->type); 1886cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg temp = dst_reg(temp_base); 18875b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18885b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt foreach_iter(exec_list_iterator, iter, ir->components) { 18895b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_constant *field_value = (ir_constant *)iter.get(); 18905b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt int size = type_size(field_value->type); 18915b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18925b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt assert(size > 0); 18935b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18945b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt field_value->accept(this); 1895461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 18965b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18975b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt for (i = 0; i < (unsigned int)size; i++) { 189801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, temp, src); 18995b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 1900461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index++; 19015b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt temp.index++; 19025b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 19035b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 19045b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt this->result = temp_base; 19055b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt return; 19065b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 19075b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 190820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (ir->type->is_array()) { 1909fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp_base = get_temp(ir->type); 1910cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg temp = dst_reg(temp_base); 191120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt int size = type_size(ir->type->fields.array); 191220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 191320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt assert(size > 0); 191420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 191520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < ir->type->length; i++) { 191620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir->array_elements[i]->accept(this); 1917461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 191820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (int j = 0; j < size; j++) { 191901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, temp, src); 192020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1921461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index++; 192220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt temp.index++; 192320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 192420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 192520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt this->result = temp_base; 192620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt return; 192720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 192820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1929ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1930fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg mat = get_temp(ir->type); 1931cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg mat_column = dst_reg(mat); 1932ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1933ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1934ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1935ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1936ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1937fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src = src_reg(PROGRAM_CONSTANT, -1, NULL); 1938461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = _mesa_add_unnamed_constant(this->prog->Parameters, 19396d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 19409c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 1941461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke &src.swizzle); 194201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, mat_column, src); 1943ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1944ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1945ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1946ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1947ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1948ebef04011736ea8e13692fed87623d425c4d1b08Eric Anholt return; 1949582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 19500bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 1951461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.file = PROGRAM_CONSTANT; 19520bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 19530bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 19540bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 19550bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19560bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 19570bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19580bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 19590bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19600bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19610bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 19620bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19630bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 19640bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19650bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19660bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 19670bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19680bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 19690bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19700bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19710bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 19720bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 19730bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19740bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 1975fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke this->result = src_reg(PROGRAM_CONSTANT, -1, ir->type); 19769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, 19776d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 19789c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 19799c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &this->result.swizzle); 198084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 198184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 19827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry * 19837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) 19847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{ 19857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry; 19867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, this->function_signatures) { 19887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = (function_entry *)iter.get(); 19897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig == sig) 19917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 19927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1994d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke entry = ralloc(mem_ctx, function_entry); 19957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig = sig; 19967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig_id = this->next_signature_id++; 19977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = NULL; 19987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Allocate storage for all the parameters. */ 20007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, sig->parameters) { 20017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)iter.get(); 2002b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage; 20037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt storage = find_variable_storage(param); 20057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!storage); 20067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2007b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 2008b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 2009b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(storage); 20107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->next_temp += type_size(param->type); 20127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2014576d01ad8c8b8aa57b4711c98d8e004d4f20fc0bEric Anholt if (!sig->return_type->is_void()) { 20157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = get_temp(sig->return_type); 20167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } else { 2017ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke entry->return_reg = undef_src; 20187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->function_signatures.push_tail(entry); 20217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 20227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt} 202384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 202484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 202584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 202684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 20277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *call_inst; 20287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig = ir->get_callee(); 20297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = get_function_signature(sig); 20307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 20317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process in parameters. */ 20337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list_iterator sig_iter = sig->parameters.iterator(); 20347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 20357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 20367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 20377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_in || 20397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 2040b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 20417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 20427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 2044fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r = this->result; 20457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2046fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg l; 20477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.file = storage->file; 20487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index = storage->index; 20497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.reladdr = NULL; 20507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.writemask = WRITEMASK_XYZW; 20517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.cond_mask = COND_TR; 20527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 205401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 20557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 20567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 20577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 20617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 20637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit call instruction */ 20655d9718f0dbe1bb9b25324c43ed0fa631735c6a51Kenneth Graunke call_inst = emit(ir, OPCODE_CAL); 20667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst->function = entry; 20677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process out parameters. */ 20697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter = sig->parameters.iterator(); 20707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 20717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 20727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 20737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_out || 20757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 2076b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 20777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 20787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2079fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r; 20807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.file = storage->file; 20817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index = storage->index; 20827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.reladdr = NULL; 20837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.swizzle = SWIZZLE_NOOP; 20847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.negate = 0; 20857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 2087cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg l = dst_reg(this->result); 20887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 209001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 20917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 20927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 20937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 20977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 20997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process return value. */ 21017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->result = entry->return_reg; 210284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 210384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 210484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 210584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 210684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 210768074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke src_reg result_src, coord, lod_info, projector, dx, dy; 2108fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg result_dst, coord_dst; 2109d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 2110d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 211184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2112ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke if (ir->op == ir_txs) 2113ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke this->result = src_reg_for_float(0.0); 2114ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke else 2115ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->coordinate->accept(this); 2116d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2117d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 2118d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 2119d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 2120d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 2121d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2122d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 2123cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke coord_dst = dst_reg(coord); 212401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, this->result); 2125d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2126de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 2127de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 2128de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 2129de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 2130de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 2131d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 2132d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 2133d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 2134d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 2135cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke result_dst = dst_reg(result_src); 2136d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2137d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 2138d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 2139ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txs: 2140d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 2141d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2142d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 2143d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 2144d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 2145d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2146d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 214730be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke case ir_txf: 214830be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke /* Pretend to be TXL so the sampler, coordinate, lod are available */ 2149d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 2150d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 2151d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 2152d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2153d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2154d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 215568074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke opcode = OPCODE_TXD; 215668074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke ir->lod_info.grad.dPdx->accept(this); 215768074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke dx = this->result; 215868074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke ir->lod_info.grad.dPdy->accept(this); 215968074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke dy = this->result; 216068074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke break; 2161d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2162d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2163da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák const glsl_type *sampler_type = ir->sampler->type; 2164da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 2165d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 2166d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 2167d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 2168d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 216901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, projector); 2170d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2171d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 2172d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 2173fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg coord_w = coord; 2174d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 2175d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2176d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 2177d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 2178d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 2179d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2180d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 218101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_RCP, coord_dst, projector); 2182d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 21839996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* In the case where we have to project the coordinates "by hand," 21849996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * the shadow comparitor value must also be projected. 21859996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 218601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg tmp_src = coord; 21879996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick if (ir->shadow_comparitor) { 21889996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* Slot the shadow value in as the second to last component of the 21899996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * coord. 21909996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 21919996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick ir->shadow_comparitor->accept(this); 21929996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 21939996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_src = get_temp(glsl_type::vec4_type); 219401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg tmp_dst = dst_reg(tmp_src); 21959996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 2196da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák /* Projective division not allowed for array samplers. */ 2197da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák assert(!sampler_type->sampler_array); 2198da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 21999996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_dst.writemask = WRITEMASK_Z; 220001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, tmp_dst, this->result); 22019996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 22029996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_dst.writemask = WRITEMASK_XY; 220301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, tmp_dst, coord); 22049996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick } 22059996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 2206d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 220701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, coord_dst, tmp_src, coord_w); 2208d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2209d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2210d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 2211d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2212d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2213d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 22149996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* If projection is done and the opcode is not OPCODE_TXP, then the shadow 22159996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * comparitor was put in the correct place (and projected) by the code, 22169996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * above, that handles by-hand projection. 22179996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 22189996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick if (ir->shadow_comparitor && (!ir->projector || opcode == OPCODE_TXP)) { 2219b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 2220b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 2221b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 2222b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 2223da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 2224da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák /* XXX This will need to be updated for cubemap array samplers. */ 2225da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D && 2226da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák sampler_type->sampler_array) { 2227da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák coord_dst.writemask = WRITEMASK_W; 2228da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák } else { 2229da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák coord_dst.writemask = WRITEMASK_Z; 2230da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák } 2231da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 223201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, this->result); 2233b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2234b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 2235b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2236d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 2237d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 2238d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 223901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, lod_info); 2240d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2241d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2242d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 224368074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke if (opcode == OPCODE_TXD) 224468074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke inst = emit(ir, opcode, result_dst, coord, dx, dy); 224568074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke else 224668074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke inst = emit(ir, opcode, result_dst, coord); 2247d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2248b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 2249b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 2250b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2251a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2252a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->shader_program, 2253a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->prog); 2254c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt 2255c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt switch (sampler_type->sampler_dimensionality) { 2256d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 2257c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 22580a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2259d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2260d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 2261c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 22620a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2263d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2264d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 2265d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 2266d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2267d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 2268d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 2269d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 22700bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick case GLSL_SAMPLER_DIM_RECT: 22710bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick inst->tex_target = TEXTURE_RECT_INDEX; 22720bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick break; 227368772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick case GLSL_SAMPLER_DIM_BUF: 227468772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"FINISHME: Implement ARB_texture_buffer_object"); 227568772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick break; 2276d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 227768772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"Should not get here."); 2278d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2279d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2280d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 228184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 228284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 228384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 228484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 228584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 22867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (ir->get_value()) { 2287fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg l; 22887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 22897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 229035220fc5981045331b4f048f0fc2e1371a0673edEric Anholt assert(current_function); 229135220fc5981045331b4f048f0fc2e1371a0673edEric Anholt 22927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir->get_value()->accept(this); 2293fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r = this->result; 229484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2295cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke l = dst_reg(current_function->return_reg); 22967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 22977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(current_function->sig->return_type); i++) { 229801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 22997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 23007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 23017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 23027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 23037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 230401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_RET); 230584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 230684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 230716efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 230816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 230916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 23109b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 23119b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt 2312ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák if (ir->condition) { 2313ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák ir->condition->accept(this); 2314ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák this->result.negate = ~this->result.negate; 2315ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_KIL, undef_dst, this->result); 2316ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } else { 231701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_KIL_NV); 2318ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } 231916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 23209b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt fp->UsesKill = GL_TRUE; 232116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 232284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 232384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 232484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 232584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 2326847d397b3415b6705a084013903e1a7e8384e1d2Marek Olšák ir_to_mesa_instruction *cond_inst, *if_inst; 2327cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 2328cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2329cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2330c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2331c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 23320161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 2333c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 23346d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri if (this->options->EmitCondCodes) { 2335854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2336cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2337cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 2338cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 2339cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 2340cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 2341cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 2342fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::bool_type); 234301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke cond_inst = emit(ir->condition, OPCODE_MOV, dst_reg(temp), result); 2344cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 2345854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 2346854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 234701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke if_inst = emit(ir->condition, OPCODE_IF); 2348461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if_inst->dst.cond_mask = COND_NE; 2349854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 2350ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke if_inst = emit(ir->condition, OPCODE_IF, undef_dst, this->result); 2351854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 2352c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2353c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 2354c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2355c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 2356c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2357c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 2358847d397b3415b6705a084013903e1a7e8384e1d2Marek Olšák emit(ir->condition, OPCODE_ELSE); 23590a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 2360c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2361c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 23625d9718f0dbe1bb9b25324c43ed0fa631735c6a51Kenneth Graunke if_inst = emit(ir->condition, OPCODE_ENDIF); 236384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 236484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2365ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 2366ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 23670161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 2368ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 23697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 23707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 2371d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mem_ctx = ralloc_context(NULL); 2372ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 2373ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 2374fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor() 2375fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{ 2376d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(mem_ctx); 2377fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt} 2378fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt 237984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 2380fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkemesa_src_reg_from_ir_src_reg(src_reg reg) 238184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 238284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 238384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 238484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 238550fd99d1723a6c7f3bd2dedffeeadf7d5e33b83bBrian Paul assert(reg.index < (1 << INST_INDEX_BITS)); 238684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 238734195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 2388f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 2389ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 2390285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 2391b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt mesa_reg.HasIndex2 = GL_FALSE; 2392405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.RelAddr2 = 0; 2393405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.Index2 = 0; 239484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 239584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 239684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 239784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2398c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 23997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 24007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 2401c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2402c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2403e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 240464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 240564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 240664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 2407c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2408c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 240964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 241064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 2411c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 241264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 241364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 241464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 241564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 241664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 241764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 241864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 241964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 242064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 242164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 242264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 2423c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2424c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2425d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke if_stack = rzalloc_array(v->mem_ctx, int, if_count); 2426d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke loop_stack = rzalloc_array(v->mem_ctx, int, loop_count); 2427c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2428c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2429c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 2430c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 243164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 2432c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 2433c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2434c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 243564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 243664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 2437c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2438c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 243964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 2440c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 2441c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 244264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 244364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 244464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 244564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 244664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 244764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 244864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 244964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 245064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 245164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 245264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 245364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 245464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 245564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 245664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 245764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 245864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 245964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 246064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 246164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 246264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 24637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 24647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 24657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 24667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 24677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 24697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 24707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 24717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 24727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 24737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 2474c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 2475c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2476c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2477c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2478c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2479c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2480c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 2481c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 2482c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 2483c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2484c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2485c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 2486c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2487748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 2488c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2489c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2490c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 2491c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 2492c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2493748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 2494748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 249564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 2496748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 2497748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2498748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 2499748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 2500748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 2501748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 2502c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 2503c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 2504748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2505748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 2506c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2507c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2508748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 2509748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 2510c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2511c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2512c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 25138cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 25148cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul/** 25158cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * Count resources used by the given gpu program (number of texture 25168cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * samplers, etc). 25178cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul */ 2518ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void 2519ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog) 2520ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{ 2521d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt unsigned int i; 2522d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2523d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed = 0; 2524ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2525ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (i = 0; i < prog->NumInstructions; i++) { 2526ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt struct prog_instruction *inst = &prog->Instructions[i]; 2527d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2528d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (_mesa_is_tex_instruction(inst->Opcode)) { 2529d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplerTargets[inst->TexSrcUnit] = 2530d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt (gl_texture_index)inst->TexSrcTarget; 2531d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed |= 1 << inst->TexSrcUnit; 2532d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (inst->TexShadow) { 2533d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->ShadowSamplers |= 1 << inst->TexSrcUnit; 2534d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2535d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2536ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2537d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2538d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt _mesa_update_shader_textures_used(prog); 2539ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt} 2540ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 25418cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 25428cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul/** 25438cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * Check if the given vertex/fragment/shader program is within the 25448cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * resource limits of the context (number of texture units, etc). 25458cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * If any of those checks fail, record a linker error. 25468cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * 25478cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * XXX more checks are needed... 25488cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul */ 25498cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paulstatic void 25508cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paulcheck_resources(const struct gl_context *ctx, 25518cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul struct gl_shader_program *shader_program, 25528cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul struct gl_program *prog) 25538cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul{ 25548cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul switch (prog->Target) { 25558cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul case GL_VERTEX_PROGRAM_ARB: 25568cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (_mesa_bitcount(prog->SamplersUsed) > 25578cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul ctx->Const.MaxVertexTextureImageUnits) { 25588aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 25598aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Too many vertex shader texture samplers"); 25608cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25610f84ddad29284b407c6bbef0b731201056d40324Marek Olšák if (prog->Parameters->NumParameters > MAX_UNIFORMS) { 25628aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, "Too many vertex shader constants"); 25638cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25648cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul break; 25658cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul case MESA_GEOMETRY_PROGRAM: 25668cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (_mesa_bitcount(prog->SamplersUsed) > 2567e0e94026a0648d6b33d6b7cf2b9b01429cf945e4Brian Paul ctx->Const.MaxGeometryTextureImageUnits) { 25688aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 25698aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Too many geometry shader texture samplers"); 25708cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25718cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (prog->Parameters->NumParameters > 25720f84ddad29284b407c6bbef0b731201056d40324Marek Olšák MAX_GEOMETRY_UNIFORM_COMPONENTS / 4) { 25738aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, "Too many geometry shader constants"); 25748cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25758cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul break; 25768cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul case GL_FRAGMENT_PROGRAM_ARB: 25778cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (_mesa_bitcount(prog->SamplersUsed) > 25788cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul ctx->Const.MaxTextureImageUnits) { 25798aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 25808aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Too many fragment shader texture samplers"); 25818cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25820f84ddad29284b407c6bbef0b731201056d40324Marek Olšák if (prog->Parameters->NumParameters > MAX_UNIFORMS) { 25838aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, "Too many fragment shader constants"); 25848cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25858cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul break; 25868cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul default: 25878cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul _mesa_problem(ctx, "unexpected program type in check_resources()"); 25888cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25898cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul} 25908cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 25916437a71d4172273db670b959dd66e3b34c866962Ian Romanickclass add_uniform_to_shader : public uniform_field_visitor { 25926437a71d4172273db670b959dd66e3b34c866962Ian Romanickpublic: 25936437a71d4172273db670b959dd66e3b34c866962Ian Romanick add_uniform_to_shader(struct gl_shader_program *shader_program, 25946437a71d4172273db670b959dd66e3b34c866962Ian Romanick struct gl_program_parameter_list *params) 25956437a71d4172273db670b959dd66e3b34c866962Ian Romanick : shader_program(shader_program), params(params), next_sampler(0) 25966437a71d4172273db670b959dd66e3b34c866962Ian Romanick { 25976437a71d4172273db670b959dd66e3b34c866962Ian Romanick /* empty */ 25986437a71d4172273db670b959dd66e3b34c866962Ian Romanick } 25998cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 26006437a71d4172273db670b959dd66e3b34c866962Ian Romanick int process(ir_variable *var) 26016437a71d4172273db670b959dd66e3b34c866962Ian Romanick { 26026437a71d4172273db670b959dd66e3b34c866962Ian Romanick this->idx = -1; 26036437a71d4172273db670b959dd66e3b34c866962Ian Romanick this->uniform_field_visitor::process(var); 26046437a71d4172273db670b959dd66e3b34c866962Ian Romanick 26056437a71d4172273db670b959dd66e3b34c866962Ian Romanick return this->idx; 26066437a71d4172273db670b959dd66e3b34c866962Ian Romanick } 26076437a71d4172273db670b959dd66e3b34c866962Ian Romanick 26086437a71d4172273db670b959dd66e3b34c866962Ian Romanickprivate: 26096437a71d4172273db670b959dd66e3b34c866962Ian Romanick virtual void visit_field(const glsl_type *type, const char *name); 26106437a71d4172273db670b959dd66e3b34c866962Ian Romanick 26116437a71d4172273db670b959dd66e3b34c866962Ian Romanick struct gl_shader_program *shader_program; 26126437a71d4172273db670b959dd66e3b34c866962Ian Romanick struct gl_program_parameter_list *params; 26136437a71d4172273db670b959dd66e3b34c866962Ian Romanick int next_sampler; 26146437a71d4172273db670b959dd66e3b34c866962Ian Romanick int idx; 26156437a71d4172273db670b959dd66e3b34c866962Ian Romanick}; 26166437a71d4172273db670b959dd66e3b34c866962Ian Romanick 26176437a71d4172273db670b959dd66e3b34c866962Ian Romanickvoid 26186437a71d4172273db670b959dd66e3b34c866962Ian Romanickadd_uniform_to_shader::visit_field(const glsl_type *type, const char *name) 261985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 2620b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick unsigned int size; 262199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 2622b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (type->is_vector() || type->is_scalar()) { 2623b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick size = type->vector_elements; 2624b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } else { 2625b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick size = type_size(type) * 4; 2626b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } 262785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2628b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick gl_register_file file; 2629b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (type->is_sampler() || 2630b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick (type->is_array() && type->fields.array->is_sampler())) { 2631b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick file = PROGRAM_SAMPLER; 2632b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } else { 2633b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick file = PROGRAM_UNIFORM; 2634b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } 26350924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 26366437a71d4172273db670b959dd66e3b34c866962Ian Romanick int index = _mesa_lookup_parameter_index(params, -1, name); 2637b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (index < 0) { 26386437a71d4172273db670b959dd66e3b34c866962Ian Romanick index = _mesa_add_parameter(params, file, name, size, type->gl_type, 2639b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick NULL, NULL, 0x0); 26400924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2641b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick /* Sampler uniform values are stored in prog->SamplerUnits, 2642b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * and the entry in that array is selected by this index we 2643b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * store in ParameterValues[]. 2644b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick */ 2645b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (file == PROGRAM_SAMPLER) { 2646b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick for (unsigned int j = 0; j < size / 4; j++) 26476437a71d4172273db670b959dd66e3b34c866962Ian Romanick params->ParameterValues[index + j][0].f = this->next_sampler++; 264899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 264999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 265099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 26516437a71d4172273db670b959dd66e3b34c866962Ian Romanick /* The first part of the uniform that's processed determines the base 26526437a71d4172273db670b959dd66e3b34c866962Ian Romanick * location of the whole uniform (for structures). 26536437a71d4172273db670b959dd66e3b34c866962Ian Romanick */ 26546437a71d4172273db670b959dd66e3b34c866962Ian Romanick if (this->idx < 0) 26556437a71d4172273db670b959dd66e3b34c866962Ian Romanick this->idx = index; 2656b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick} 26570924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2658b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick/** 2659b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * Generate the program parameters list for the user uniforms in a shader 2660b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * 2661b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * \param shader_program Linked shader program. This is only used to 2662b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * emit possible link errors to the info log. 2663b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * \param sh Shader whose uniforms are to be processed. 2664b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * \param params Parameter list to be filled in. 2665b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick */ 2666b2572928a50ce42abc2733202d08f5a00733d707Ian Romanickvoid 2667b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program 2668b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick *shader_program, 2669b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick struct gl_shader *sh, 2670b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick struct gl_program_parameter_list 2671b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick *params) 2672b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick{ 26736437a71d4172273db670b959dd66e3b34c866962Ian Romanick add_uniform_to_shader add(shader_program, params); 267485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2675b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick foreach_list(node, sh->ir) { 2676b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick ir_variable *var = ((ir_instruction *) node)->as_variable(); 26770924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2678b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if ((var == NULL) || (var->mode != ir_var_uniform) 2679b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick || (strncmp(var->name, "gl_", 3) == 0)) 2680b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick continue; 2681aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 26826437a71d4172273db670b959dd66e3b34c866962Ian Romanick int loc = add.process(var); 2683aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2684b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick /* The location chosen in the Parameters list here (returned from 2685b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * _mesa_add_parameter) has to match what the linker chose. 2686b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick */ 2687b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (var->location != loc) { 2688b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick linker_error(shader_program, 2689b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick "Allocation of uniform `%s' to target failed " 2690b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick "(%d vs %d)\n", 2691b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick var->name, loc, var->location); 269285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 269385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 269485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 269585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 26962f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 2697f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergset_uniform_initializer(struct gl_context *ctx, void *mem_ctx, 26982f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program, 26992f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const char *name, const glsl_type *type, 27002f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *val) 27012f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 27022f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_record()) { 27032f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *field_constant; 27042f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27052f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)val->components.get_head(); 27062f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27072f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 27082f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *field_type = type->fields.structure[i].type; 2709d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, 27102f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt type->fields.structure[i].name); 27112f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 27122f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_type, field_constant); 27132f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)field_constant->next; 27142f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27152f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt return; 27162f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27172f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27182f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt int loc = _mesa_get_uniform_location(ctx, shader_program, name); 27192f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27202f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (loc == -1) { 27218aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 27228aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Couldn't find uniform for initializer %s\n", name); 2723500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt return; 27242f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27252f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27262f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 27272f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *element; 27282f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *element_type; 27292f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_array()) { 27302f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val->array_elements[i]; 27312f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type->fields.array; 27322f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 27332f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val; 27342f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type; 27352f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27362f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27372f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *values; 27382f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27392f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->base_type == GLSL_TYPE_BOOL) { 2740d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke int *conv = ralloc_array(mem_ctx, int, element_type->components()); 27412f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int j = 0; j < element_type->components(); j++) { 27422f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt conv[j] = element->value.b[j]; 27432f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27442f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = (void *)conv; 27452f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = glsl_type::get_instance(GLSL_TYPE_INT, 27462f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 27472f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 1); 27482f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 27492f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = &element->value; 27502f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27512f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27522f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->is_matrix()) { 27532f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform_matrix(ctx, shader_program, 27542f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->matrix_columns, 27552f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 27562f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc, 1, GL_FALSE, (GLfloat *)values); 27572f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += element_type->matrix_columns; 27582f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 27592f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 27602f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values, element_type->gl_type); 27612f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += type_size(element_type); 27622f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27632f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27642f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 27652f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27662f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 2767f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergset_uniform_initializers(struct gl_context *ctx, 27682f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program) 27692f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 27702f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *mem_ctx = NULL; 27712f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27723322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { 27732f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader *shader = shader_program->_LinkedShaders[i]; 27743322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 27753322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (shader == NULL) 27763322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 27773322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 27782f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt foreach_iter(exec_list_iterator, iter, *shader->ir) { 27792f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 27802f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_variable *var = ir->as_variable(); 27812f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27822f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!var || var->mode != ir_var_uniform || !var->constant_value) 27832f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt continue; 27842f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27852f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!mem_ctx) 2786d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mem_ctx = ralloc_context(NULL); 27872f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27882f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, 27892f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt var->type, var->constant_value); 27902f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27912f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27922f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 2793d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(mem_ctx); 27942f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 27952f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 279634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt/* 279734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * On a basic block basis, tracks available PROGRAM_TEMPORARY register 279834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * channels for copy propagation and updates following instructions to 279934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * use the original versions. 280034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 280134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * The ir_to_mesa_visitor lazily produces code assuming that this pass 280234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * will occur. As an example, a TXP production before this pass: 280334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 280434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 280534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 280634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 280734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 280834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * and after: 280934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 281034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 281134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 281234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 281334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 281434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * which allows for dead code elimination on TEMP[1]'s writes. 281534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 281634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtvoid 281734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtir_to_mesa_visitor::copy_propagate(void) 281834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt{ 2819d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx, 282025beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt ir_to_mesa_instruction *, 282125beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt this->next_temp * 4); 28228902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 28238902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca int level = 0; 282434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 282534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt foreach_iter(exec_list_iterator, iter, this->instructions) { 282634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 282734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2828461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke assert(inst->dst.file != PROGRAM_TEMPORARY 2829461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke || inst->dst.index < this->next_temp); 28305c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick 283134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* First, do any copy propagation possible into the src regs. */ 283234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int r = 0; r < 3; r++) { 283334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *first = NULL; 283434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt bool good = true; 2835461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int acp_base = inst->src[r].index * 4; 283634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2837461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->src[r].file != PROGRAM_TEMPORARY || 2838461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].reladdr) 283934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt continue; 284034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 284134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* See if we can find entries in the ACP consisting of MOVs 284234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * from the same src register for all the swizzled channels 284334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * of this src register reference. 284434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 284534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2846461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(inst->src[r].swizzle, i); 284734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_chan = acp[acp_base + src_chan]; 284834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 284934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!copy_chan) { 285034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 285134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 285234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 285334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 28548902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca assert(acp_level[acp_base + src_chan] <= level); 28558902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 285634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!first) { 285734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt first = copy_chan; 285834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } else { 2859461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (first->src[0].file != copy_chan->src[0].file || 2860461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke first->src[0].index != copy_chan->src[0].index) { 286134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 286234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 286334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 286434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 286534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 286634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 286734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (good) { 286834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* We've now validated that we can copy-propagate to 286934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * replace this src register reference. Do it. 287034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 2871461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].file = first->src[0].file; 2872461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].index = first->src[0].index; 287334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 287434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt int swizzle = 0; 287534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2876461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(inst->src[r].swizzle, i); 287734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_inst = acp[acp_base + src_chan]; 2878461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << 287934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt (3 * i)); 288034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 2881461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].swizzle = swizzle; 288234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 288334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 288434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 288534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt switch (inst->op) { 288634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_BGNLOOP: 288734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_ENDLOOP: 288834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* End of a basic block, clear the ACP entirely. */ 288925beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 289034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 289134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 28928902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_IF: 28938902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca ++level; 28948902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca break; 28958902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 28968902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_ENDIF: 28978902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_ELSE: 28988902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca /* Clear all channels written inside the block from the ACP, but 28998902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca * leaving those that were not touched. 29008902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca */ 29018902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca for (int r = 0; r < this->next_temp; r++) { 29028902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca for (int c = 0; c < 4; c++) { 29038902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (!acp[4 * r + c]) 29048902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca continue; 29058902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 29068902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (acp_level[4 * r + c] >= level) 29078902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca acp[4 * r + c] = NULL; 29088902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca } 29098902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca } 29108902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (inst->op == OPCODE_ENDIF) 29118902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca --level; 29128902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca break; 29138902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 291434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt default: 291534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* Continuing the block, clear any written channels from 291634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * the ACP. 291734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 2918461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { 291976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Any temporary might be written, so no copy propagation 292076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt * across this instruction. 292176857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt */ 292276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 2923461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke } else if (inst->dst.file == PROGRAM_OUTPUT && 2924461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.reladdr) { 292576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Any output might be written, so no copy propagation 292676857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt * from outputs across this instruction. 292776857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt */ 292876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int r = 0; r < this->next_temp; r++) { 292976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 29303803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick if (!acp[4 * r + c]) 29313803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick continue; 29323803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick 2933461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) 293476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt acp[4 * r + c] = NULL; 293576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 293676857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 2937461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke } else if (inst->dst.file == PROGRAM_TEMPORARY || 2938461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.file == PROGRAM_OUTPUT) { 293976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Clear where it's used as dst. */ 2940461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.file == PROGRAM_TEMPORARY) { 294176857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 2942461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.writemask & (1 << c)) { 2943461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * inst->dst.index + c] = NULL; 294476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 294576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 294676857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 294776857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 294876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Clear where it's used as src. */ 294976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int r = 0; r < this->next_temp; r++) { 295076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 295176857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt if (!acp[4 * r + c]) 295276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt continue; 295376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 2954461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); 295576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 2956461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (acp[4 * r + c]->src[0].file == inst->dst.file && 2957461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * r + c]->src[0].index == inst->dst.index && 2958461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask & (1 << src_chan)) 295976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt { 296076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt acp[4 * r + c] = NULL; 296134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 296234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 296334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 296434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 296534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 296634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 296734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 296834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* If this is a copy, add it to the ACP. */ 296934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->op == OPCODE_MOV && 2970461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.file == PROGRAM_TEMPORARY && 2971461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->dst.reladdr && 297234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt !inst->saturate && 2973461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->src[0].reladdr && 2974461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->src[0].negate) { 297534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2976461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.writemask & (1 << i)) { 2977461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * inst->dst.index + i] = inst; 2978461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp_level[4 * inst->dst.index + i] = level; 297934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 298034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 298134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 298234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 29837772a34f3aedfa8ef58ad5f912f56bd5adf27057Vinson Lee 29848902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca ralloc_free(acp_level); 2985d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(acp); 298634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt} 298734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2988f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 2989f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 2990f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Convert a shader's GLSL IR into a Mesa gl_program. 2991f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 29926162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulstatic struct gl_program * 29936162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulget_mesa_program(struct gl_context *ctx, 29946162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul struct gl_shader_program *shader_program, 299595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 299684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 299784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 299884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2999c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 3000c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 3001364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 3002364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 3003c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 30047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt GLboolean progress; 30056d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri struct gl_shader_compiler_options *options = 30066d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 3007364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3008364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 3009c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 3010c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 3011c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 3012c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 3013c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 3014c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 3015c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 3016c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 3017903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul case GL_GEOMETRY_SHADER: 3018903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target = GL_GEOMETRY_PROGRAM_NV; 3019903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target_string = "geometry"; 3020903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul break; 3021c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 3022c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 30234841c0a15adcc722e67d7d246987cd686d3f7a17José Fonseca return NULL; 3024364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 302584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30261124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 30271124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 3028859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 3029364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 3030364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 3031364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 3032364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 3033364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 3034aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt v.shader_program = shader_program; 30356d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri v.options = options; 3036364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3037b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick _mesa_generate_parameters_list_for_uniforms(shader_program, shader, 3038b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick prog->Parameters); 30390924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 30407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 304116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 304201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke v.emit(NULL, OPCODE_END); 304384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Now emit bodies for any functions that were used. */ 30457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt do { 30467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_FALSE; 30477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 30487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v.function_signatures) { 30497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 30507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 30517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (!entry->bgn_inst) { 30527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt v.current_function = entry; 30537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 305401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke entry->bgn_inst = v.emit(NULL, OPCODE_BGNSUB); 30557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst->function = entry; 30567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 30577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt visit_exec_list(&entry->sig->body, &v); 30587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3059806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt ir_to_mesa_instruction *last; 3060806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt last = (ir_to_mesa_instruction *)v.instructions.get_tail(); 3061806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt if (last->op != OPCODE_RET) 306201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke v.emit(NULL, OPCODE_RET); 3063806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt 306440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt ir_to_mesa_instruction *end; 306501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke end = v.emit(NULL, OPCODE_ENDSUB); 306640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end->function = entry; 306740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt 30687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_TRUE; 30697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 30707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 30717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } while (progress); 30727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3073364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 3074364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 307584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 307684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 307784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 307884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 307984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 308084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 308184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 308284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 3083d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mesa_instruction_annotation = ralloc_array(v.mem_ctx, ir_instruction *, 3084364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 308584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 308634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt v.copy_propagate(); 308734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 3088f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Convert ir_mesa_instructions into prog_instructions. 3089f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 309084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 3091c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 309284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 3093f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 3094b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 309584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 3096854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 3097ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (inst->saturate) 3098ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt mesa_inst->SaturateMode = SATURATE_ZERO_ONE; 3099461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.File = inst->dst.file; 3100461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.Index = inst->dst.index; 3101461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.CondMask = inst->dst.cond_mask; 3102461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.WriteMask = inst->dst.writemask; 3103461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.RelAddr = inst->dst.reladdr != NULL; 3104461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src[0]); 3105461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src[1]); 3106461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src[2]); 3107d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 3108d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 3109b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 3110c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 3111aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 31125755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák /* Set IndirectRegisterFiles. */ 31135755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->DstReg.RelAddr) 31145755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; 31155755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 3116f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Update program's bitmask of indirectly accessed register files */ 31175755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák for (unsigned src = 0; src < 3; src++) 31185755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->SrcReg[src].RelAddr) 31195755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; 31205755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 312140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt switch (mesa_inst->Opcode) { 3122322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_IF: 3123488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain if (options->MaxIfDepth == 0) { 3124322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 3125322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't flatten if-statement. " 3126322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 3127322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 3128322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 3129322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 3130322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_BGNLOOP: 3131322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick if (options->EmitNoLoops) { 3132322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 3133322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't unroll loop. " 3134322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 3135322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 3136322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 3137322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 3138322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_CONT: 3139322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick if (options->EmitNoCont) { 3140322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 3141322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't lower continue-statement. " 3142322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 3143322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 3144322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 3145322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 314640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_BGNSUB: 31477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function->inst = i; 314840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 314940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 315040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ENDSUB: 315140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 315240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 315340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_CAL: 31547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ 315540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 315640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ARL: 3157d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 315840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 315940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt default: 316040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 316140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt } 31627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 316384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 3164c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 31656162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 31666162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) 31676162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 31686162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 31696162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 31706162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) { 31716162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul free(mesa_instructions); 31726162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul _mesa_reference_program(ctx, &shader->Program, NULL); 31736162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul return NULL; 317484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 3175c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 31767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 3177925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 3178c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 3179455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 3180455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL IR for linked %s program %d:\n", target_string, 3181455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 3182455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt _mesa_print_ir(shader->ir, NULL); 3183455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 3184455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 3185455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("Mesa IR for linked %s program %d:\n", target_string, 3186455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 3187364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 3188364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 3189364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3190364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3191364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 3192364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 3193364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3194925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt do_set_program_inouts(shader->ir, prog); 3195925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt count_resources(prog); 3196925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 31978cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul check_resources(ctx, shader_program, prog); 31988cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 319916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 3200364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 320128faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 320228faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 320328faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 320428faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 3205364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 3206364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 3207364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 320816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 3209f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3210f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3211f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a shader. 3212f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Called via ctx->Driver.LinkShader() 3213f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * This actually involves converting GLSL IR into Mesa gl_programs with 3214f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * code lowering and other optimizations. 3215f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 3216d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean 3217f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 3218d19eecef54384c163af27a470496ed885a5a271bEric Anholt{ 3219d19eecef54384c163af27a470496ed885a5a271bEric Anholt assert(prog->LinkStatus); 3220d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32213322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 32223322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 32233322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 32243322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 3225d19eecef54384c163af27a470496ed885a5a271bEric Anholt bool progress; 3226d19eecef54384c163af27a470496ed885a5a271bEric Anholt exec_list *ir = prog->_LinkedShaders[i]->ir; 3227f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const struct gl_shader_compiler_options *options = 32286d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 3229d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3230d19eecef54384c163af27a470496ed885a5a271bEric Anholt do { 3231d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = false; 3232d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3233d19eecef54384c163af27a470496ed885a5a271bEric Anholt /* Lowering */ 3234d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_mat_op_to_vec(ir); 3235c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 3236478034f34a59969103237eb78bc82f9e70fe81c2Bryan Cain | LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP 3237c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); 3238d19eecef54384c163af27a470496ed885a5a271bEric Anholt 323987708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 324087708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri 32411d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick progress = do_common_optimization(ir, true, true, 32421d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick options->MaxUnrollIterations) 32431d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick || progress; 3244d19eecef54384c163af27a470496ed885a5a271bEric Anholt 324511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick progress = lower_quadop_vector(ir, true) || progress; 324611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 3247488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain if (options->MaxIfDepth == 0) 3248940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke progress = lower_discard(ir) || progress; 3249488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain 3250488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress; 3251d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32522b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick if (options->EmitNoNoise) 32532b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick progress = lower_noise(ir) || progress; 32542b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick 3255a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick /* If there are forms of indirect addressing that the driver 3256a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick * cannot handle, perform the lowering pass. 3257a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick */ 3258a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 3259a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 3260a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick progress = 3261a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick lower_variable_index_to_cond_assign(ir, 3262a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectInput, 3263a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectOutput, 3264a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectTemp, 3265a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectUniform) 3266a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || progress; 3267a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick 3268d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = do_vec_index_to_cond_assign(ir) || progress; 3269d19eecef54384c163af27a470496ed885a5a271bEric Anholt } while (progress); 3270d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3271d19eecef54384c163af27a470496ed885a5a271bEric Anholt validate_ir_tree(ir); 3272d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3273d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32743322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 3275d19eecef54384c163af27a470496ed885a5a271bEric Anholt struct gl_program *linked_prog; 3276d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32773322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 32783322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 32793322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 3280d19eecef54384c163af27a470496ed885a5a271bEric Anholt linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 3281d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32826162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (linked_prog) { 3283e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick static const GLenum targets[] = { 3284e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_VERTEX_PROGRAM_ARB, 3285e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_FRAGMENT_PROGRAM_ARB, 3286e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_GEOMETRY_PROGRAM_NV 3287e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick }; 32886162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 3289e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick if (i == MESA_SHADER_VERTEX) { 32901ad54ae0b1713e399c5db43d0eba87861075b4c7Paul Berry ((struct gl_vertex_program *)linked_prog)->UsesClipDistance 32911ad54ae0b1713e399c5db43d0eba87861075b4c7Paul Berry = prog->Vert.UsesClipDistance; 3292e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick } 3293e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick 3294e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 3295e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick linked_prog); 3296e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick if (!ctx->Driver.ProgramStringNotify(ctx, targets[i], linked_prog)) { 32976162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul return GL_FALSE; 32986162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 3299d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 33006162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 33013cd233eb5714137dccb6218ad78005511bcc02bdEric Anholt _mesa_reference_program(ctx, &linked_prog, NULL); 3302d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3303d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3304d19eecef54384c163af27a470496ed885a5a271bEric Anholt return GL_TRUE; 3305d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 330616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 3307f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3308f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3309f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Compile a GLSL shader. Called via glCompileShader(). 3310f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 331116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 3312f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) 3313364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 33142462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 33152462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 33165e18b051c039564d1998818d08caf1bff3983630Ian Romanick 3317153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 3318a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke /* Check if the user called glCompileShader without first calling 3319a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke * glShaderSource. This should fail to compile, but not raise a GL_ERROR. 3320a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke */ 3321a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke if (source == NULL) { 3322a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke shader->CompileStatus = GL_FALSE; 3323a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke return; 3324a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke } 3325a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke 332606143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick state->error = preprocess(state, &source, &state->info_log, 33277dcfc44b72f00ba5a38cb02123c80113440f0de9Kenneth Graunke &ctx->Extensions, ctx->API); 3328153eca98064252be4daad9cc27746f37c245b627Ian Romanick 33291b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 33309bd7e9c6b29b212a97bd4ca6c62836160b2f7698Eric Anholt printf("GLSL source for %s shader %d:\n", 33319bd7e9c6b29b212a97bd4ca6c62836160b2f7698Eric Anholt _mesa_glsl_shader_target_name(state->target), shader->Name); 33321b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt printf("%s\n", shader->Source); 33331b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt } 33341b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt 3335153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 3336153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 3337153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 3338153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 3339153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 3340364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3341d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(shader->ir); 334216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 3343364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 334416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 3345364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 334616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 3347ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3348ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 33492f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt /* Do some optimization at compile time to reduce shader IR size 33502f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt * and reduce later work if the same shader is linked multiple times 33512f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt */ 33521d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick while (do_common_optimization(shader->ir, false, false, 32)) 33532f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt ; 3354ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 3355ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3356364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3357364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3358364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 3359364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3360364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 3361364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 336225f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 3363d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 3364d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 3365d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 3366c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 3367b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt if (ctx->Shader.Flags & GLSL_LOG) { 3368b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt _mesa_write_shader_to_file(shader); 3369b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt } 3370b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt 33710df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 33720df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->CompileStatus) { 33730df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL IR for shader %d:\n", shader->Name); 33740df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt _mesa_print_ir(shader->ir, NULL); 33750df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("\n\n"); 33760df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } else { 33770df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d failed to compile.\n", shader->Name); 33780df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 33790df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->InfoLog && shader->InfoLog[0] != 0) { 33800df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d info log:\n", shader->Name); 33810df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", shader->InfoLog); 33820df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3383455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt } 3384455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt 3385116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 33864a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt reparent_ir(shader->ir, shader->ir); 3387116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 3388d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(state); 3389d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 3390364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3391f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3392f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3393f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a GLSL shader program. Called via glLinkProgram(). 3394f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 3395364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 3396f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 3397364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 3398364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 3399849e18153cd91d812f694b806a84008498860bc3Eric Anholt 3400364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 3401364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3402849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 3403364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3404364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 3405849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 34068aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(prog, "linking with uncompiled shader"); 3407849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 3408364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3409364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3410364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3411849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 34125d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt link_shaders(ctx, prog); 3413849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 3414364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3415364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 34160df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (!ctx->Driver.LinkShader(ctx, prog)) { 3417d19eecef54384c163af27a470496ed885a5a271bEric Anholt prog->LinkStatus = GL_FALSE; 3418af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3419af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3420af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt 34212f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializers(ctx, prog); 34222f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 3423af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 3424af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (!prog->LinkStatus) { 34250df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d failed to link\n", prog->Name); 34260df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 34270df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt 34280df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (prog->InfoLog && prog->InfoLog[0] != 0) { 34290df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d info log:\n", prog->Name); 34300df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", prog->InfoLog); 34310df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3432364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3433364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 3434364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3435364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 3436