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" 38719909698c67c287a393d2380278e7b7495ae018Ian Romanick#include "ir_uniform.h" 3984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h" 40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h" 41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h" 42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h" 43364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h" 446437a71d4172273db670b959dd66e3b34c866962Ian Romanick#include "linker.h" 4584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 460a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h" 47afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h" 48fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h" 49bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick 50bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanickextern "C" { 51bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick#include "main/shaderapi.h" 52bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick#include "main/uniforms.h" 53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h" 54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h" 55afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h" 56afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.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; 175554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 176554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 177b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node { 178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 179caf974c5259f14b50257e8dd9b325a87378259afBrian Paul variable_storage(ir_variable *var, gl_register_file file, int index) 180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt : file(file), index(index), var(var) 181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt { 182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /* empty */ 183554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt } 184554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 185caf974c5259f14b50257e8dd9b325a87378259afBrian Paul gl_register_file file; 186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; 187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_variable *var; /* variable that maps to this, if any */ 188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node { 1917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic: 1927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig; 1937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * identifier of this function signature used by the program. 1967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * At the point that Mesa instructions for function calls are 1987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * generated, we don't know the address of the first instruction of 1997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * the function body. So we make the BranchTarget that is called a 2007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * small integer and rewrite them during set_branchtargets(). 2017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 2027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int sig_id; 2037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 2057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Pointer to first instruction of the function body. 2067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 2077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set during function body emits after main() is processed. 2087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 2097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *bgn_inst; 2107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 2127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Index of the first instruction of the function body in actual 2137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Mesa IR. 2147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 2157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set after convertion from ir_to_mesa_instruction to prog_instruction. 2167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 2177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int inst; 2187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** Storage for the return value. */ 220fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg return_reg; 2217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}; 2227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 223554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor { 224554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 225554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_visitor(); 226fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt ~ir_to_mesa_visitor(); 227554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *current_function; 2297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 230f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx; 231364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 232aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt struct gl_shader_program *shader_program; 2336d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri struct gl_shader_compiler_options *options; 234364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 235554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int next_temp; 236a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 237b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *find_variable_storage(ir_variable *var); 238554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 239fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg get_temp(const glsl_type *type); 240fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke void reladdr_to_temp(ir_instruction *ir, src_reg *reg, int *num_reladdr); 241554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 242fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src_reg_for_float(float val); 243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 244554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 245554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 246554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 247554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 248554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 249554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 250554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 251554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 252554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 253554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 254554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 255554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 256554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 257554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 258554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 259554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 260554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 261554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 262554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 263554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 264554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 265554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 26616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 267554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 268554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 269554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 270554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 271fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg result; 272554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 273b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 274b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 275554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 2777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 2787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 2797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 280554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 281554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 282554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 28301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op); 28401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 28501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 28601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0); 28701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 28801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 28901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1); 29001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 29101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 29201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 29301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg src0, src_reg src1, src_reg src2); 294554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 295ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick /** 296ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick * Emit the correct dot-product instruction for the type of arguments 297ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick */ 2987f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick ir_to_mesa_instruction * emit_dp(ir_instruction *ir, 2997f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick dst_reg dst, 3007f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick src_reg src0, 3017f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick src_reg src1, 3027f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick unsigned elements); 30301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 30401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke void emit_scalar(ir_instruction *ir, enum prog_opcode op, 30501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0); 30601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 30701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke void emit_scalar(ir_instruction *ir, enum prog_opcode op, 30801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1); 309904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 310f2616e56de8a48360cae8f269727b58490555f4dIan Romanick void emit_scs(ir_instruction *ir, enum prog_opcode op, 311fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst, const src_reg &src); 312f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 31379a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_mad(ir_expression *ir, 3143f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 315ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick bool try_emit_mad_for_and_not(ir_expression *ir, 316ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick int mul_operand); 31779a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_sat(ir_expression *ir); 3183f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 31911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick void emit_swz(ir_expression *ir); 32011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 321c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool process_move_condition(ir_rvalue *ir); 322c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 32334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt void copy_propagate(void); 32434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 325364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 326554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 327554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 328ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkesrc_reg undef_src = src_reg(PROGRAM_UNDEFINED, 0, NULL); 32984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 330ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkedst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP); 331c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 332ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkedst_reg address_reg = dst_reg(PROGRAM_ADDRESS, WRITEMASK_X); 3330161515c395c44233529c8d51f823b60050bc7baEric Anholt 334f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulstatic int 335f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulswizzle_for_size(int size) 3360161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 337591594ea1e5e9e5865b10b786509b9c3cec042a7Brian Paul static const int size_swizzles[4] = { 3380161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 3390161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 3400161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 3410161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 3420161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 3430161515c395c44233529c8d51f823b60050bc7baEric Anholt 3449fea9e5e2115bcb52435648d2ef753638733d7d9Ian Romanick assert((size >= 1) && (size <= 4)); 3450161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 3460161515c395c44233529c8d51f823b60050bc7baEric Anholt} 3470161515c395c44233529c8d51f823b60050bc7baEric Anholt 34884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 34901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 35001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 35101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg src0, src_reg src1, src_reg src2) 35284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 353364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 354f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 355f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 356f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 357f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 358f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 359f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 360f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 361f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 362f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 363f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 364f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 365f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 366f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 367f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 368f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 369f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 370ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_ARL, address_reg, *dst.reladdr); 371f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 372f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 373f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 37484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 37584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 376461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst = dst; 377461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[0] = src0; 378461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[1] = src1; 379461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[2] = src2; 380c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 38184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3820161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 38384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 38584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 38684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 38901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 39001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1) 39184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 392ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, dst, src0, src1, undef_src); 39384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 39484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 39601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 39701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0) 398bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 3995a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(dst.writemask != 0); 400ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, dst, src0, undef_src, undef_src); 401bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 402bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 403021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 40401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op) 405021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 406ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); 407021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 408021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 4097f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanickir_to_mesa_instruction * 41001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_dp(ir_instruction *ir, 41101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1, 41201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke unsigned elements) 413ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick{ 414ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick static const gl_inst_opcode dot_opcodes[] = { 415ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick OPCODE_DP2, OPCODE_DP3, OPCODE_DP4 416ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick }; 417ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 4187f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick return emit(ir, dot_opcodes[elements - 2], dst, src0, src1); 419ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick} 420ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 42112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 42212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 42312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 42412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 42512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 42612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 42712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 42812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 42912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 43001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op, 43101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 43201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg orig_src0, src_reg orig_src1) 43312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 43412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 435315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 43612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 43712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 43812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 43912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 44012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 442582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 444fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src0 = orig_src0; 445fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src1 = orig_src1; 44612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 44712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 44812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 44912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 450904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 451904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 45212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 453f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 454f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 455f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 456f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 457904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 458904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 459904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 46012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 46112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 46212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 463904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 464904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 465904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 466904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 46712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 46801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, op, dst, src0, src1); 469461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = this_mask; 47012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 47112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 47212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 47312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 474904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 47501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op, 47601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0) 477904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 478ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke src_reg undef = undef_src; 479904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 480904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 481904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 48201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, op, dst, src0, undef); 483904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 484904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 485f2616e56de8a48360cae8f269727b58490555f4dIan Romanick/** 486f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Emit an OPCODE_SCS instruction 487f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 488f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * The \c SCS opcode functions a bit differently than the other Mesa (or 489f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * ARB_fragment_program) opcodes. Instead of splatting its result across all 490f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * four components of the destination, it writes one value to the \c x 491f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * component and another value to the \c y component. 492f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 493f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param ir IR instruction being processed 494f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which 495f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * value is desired. 496f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param dst Destination register 497f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param src Source register 498f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 499f2616e56de8a48360cae8f269727b58490555f4dIan Romanickvoid 500f2616e56de8a48360cae8f269727b58490555f4dIan Romanickir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op, 501fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst, 502fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke const src_reg &src) 503f2616e56de8a48360cae8f269727b58490555f4dIan Romanick{ 504f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Vertex programs cannot use the SCS opcode. 505f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 506f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 50701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, op, dst, src); 508f2616e56de8a48360cae8f269727b58490555f4dIan Romanick return; 509f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 510f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 511f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned component = (op == OPCODE_SIN) ? 0 : 1; 512f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned scs_mask = (1U << component); 513f2616e56de8a48360cae8f269727b58490555f4dIan Romanick int done_mask = ~dst.writemask; 514fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg tmp; 515f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 516f2616e56de8a48360cae8f269727b58490555f4dIan Romanick assert(op == OPCODE_SIN || op == OPCODE_COS); 517f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 518f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there are compnents in the destination that differ from the component 519f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * that will be written by the SCS instrution, we'll need a temporary. 520f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 521f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (scs_mask != unsigned(dst.writemask)) { 522f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp = get_temp(glsl_type::vec4_type); 523f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 524f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 525f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned i = 0; i < 4; i++) { 526f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned this_mask = (1U << i); 527fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src0 = src; 528f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 529f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if ((done_mask & this_mask) != 0) 530f2616e56de8a48360cae8f269727b58490555f4dIan Romanick continue; 531f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 532f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* The source swizzle specified which component of the source generates 533f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * sine / cosine for the current component in the destination. The SCS 534f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * instruction requires that this value be swizzle to the X component. 535f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Replace the current swizzle with a swizzle that puts the source in 536f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the X component. 537f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 538f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned src0_swiz = GET_SWZ(src.swizzle, i); 539f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 540f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 541f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0_swiz, src0_swiz); 542f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned j = i + 1; j < 4; j++) { 543f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 544f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 545f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 546f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 547f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (!(done_mask & (1 << j)) && 548f2616e56de8a48360cae8f269727b58490555f4dIan Romanick GET_SWZ(src0.swizzle, j) == src0_swiz) { 549f2616e56de8a48360cae8f269727b58490555f4dIan Romanick this_mask |= (1 << j); 550f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 551f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 552f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 553f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this_mask != scs_mask) { 554f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_instruction *inst; 555cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg tmp_dst = dst_reg(tmp); 556f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 557f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction. 558f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 55901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, OPCODE_SCS, tmp_dst, src0); 560461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = scs_mask; 561f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 562f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Move the result of the SCS instruction to the desired location in 563f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the destination. 564f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 565f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp.swizzle = MAKE_SWIZZLE4(component, component, 566f2616e56de8a48360cae8f269727b58490555f4dIan Romanick component, component); 56701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, OPCODE_SCS, dst, tmp); 568461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = this_mask; 569f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } else { 570f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction to write directly to the destination. 571f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 57201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *inst = emit(ir, OPCODE_SCS, dst, src0); 573461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = scs_mask; 574f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 575f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 576f2616e56de8a48360cae8f269727b58490555f4dIan Romanick done_mask |= this_mask; 577f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 578f2616e56de8a48360cae8f269727b58490555f4dIan Romanick} 579f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 58007e9b9049f94ceb443eac1206cc3f9e1e51ac6c1Kenneth Graunkesrc_reg 5810161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 582b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 583fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src(PROGRAM_CONSTANT, -1, NULL); 5841d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 585461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = _mesa_add_unnamed_constant(this->prog->Parameters, 5866d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (const gl_constant_value *)&val, 1, &src.swizzle); 5871d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 588461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke return src; 5891d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 5901d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 5912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 5922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 5932c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 5942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 5952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 5962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 5972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 5982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 5992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 6002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 6012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 602a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 6039968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 604a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 605a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 606a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 607a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 608a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 609a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 610a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 611a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 6122c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 6135c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick assert(type->length > 0); 6142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 6152c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 6162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 6172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 6182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 6192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 6218d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt case GLSL_TYPE_SAMPLER: 6220924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Samplers take up one slot in UNIFORMS[], but they're baked in 6230924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * at link time. 6248d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt */ 6250924ba0c3496160a134d37cec800f902ae805b9cEric Anholt return 1; 6262c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 6272c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 62819acfa42ed47edb63f5ec3de8051a3102e62e96bJosé Fonseca return 0; 6292c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6302c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 6312c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 632d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 633d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 634d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 635d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 636d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 637d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 638fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkesrc_reg 639d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 640d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 641fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 642d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 643461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.file = PROGRAM_TEMPORARY; 644461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = next_temp; 645461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.reladdr = NULL; 646d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 647d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 64820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (type->is_array() || type->is_record()) { 649461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = SWIZZLE_NOOP; 65020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } else { 6514c7e215c7bb09f827df630cbfc80e87869351f18Eric Anholt src.swizzle = swizzle_for_size(type->vector_elements); 65220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 653461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.negate = 0; 654d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 655461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke return src; 656d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 657d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 658b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 659a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 66084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 661a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 662b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 66384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 664b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 665b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 66684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6670161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 668a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 671a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 672a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 67384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 67484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 67584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 67684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 6774a962170d7cf4243d6ae156fca20a6167388925dEric Anholt if (strcmp(ir->name, "gl_FragCoord") == 0) { 6784a962170d7cf4243d6ae156fca20a6167388925dEric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 6794a962170d7cf4243d6ae156fca20a6167388925dEric Anholt 6804a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->OriginUpperLeft = ir->origin_upper_left; 6814a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->PixelCenterInteger = ir->pixel_center_integer; 6824a962170d7cf4243d6ae156fca20a6167388925dEric Anholt } 6836c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 6846c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 6856c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt unsigned int i; 68689d81ab16c05818b290ed735c1343d3abde449bfIan Romanick const ir_state_slot *const slots = ir->state_slots; 68789d81ab16c05818b290ed735c1343d3abde449bfIan Romanick assert(ir->state_slots != NULL); 6886c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 6896c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* Check if this statevar's setup in the STATE file exactly 6906c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * matches how we'll want to reference it as a 6916c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * struct/array/whatever. If not, then we need to move it into 6926c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * temporary storage and hope that it'll get copy-propagated 6936c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * out. 6946c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt */ 69589d81ab16c05818b290ed735c1343d3abde449bfIan Romanick for (i = 0; i < ir->num_state_slots; i++) { 69689d81ab16c05818b290ed735c1343d3abde449bfIan Romanick if (slots[i].swizzle != SWIZZLE_XYZW) { 6976c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt break; 6986c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 6996c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7006c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 70107e9b9049f94ceb443eac1206cc3f9e1e51ac6c1Kenneth Graunke variable_storage *storage; 702fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst; 70389d81ab16c05818b290ed735c1343d3abde449bfIan Romanick if (i == ir->num_state_slots) { 7046c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* We'll set the index later. */ 7056c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 7066c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 7076c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 708ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke dst = undef_dst; 7096c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 71089d81ab16c05818b290ed735c1343d3abde449bfIan Romanick /* The variable_storage constructor allocates slots based on the size 71189d81ab16c05818b290ed735c1343d3abde449bfIan Romanick * of the type. However, this had better match the number of state 71289d81ab16c05818b290ed735c1343d3abde449bfIan Romanick * elements that we're going to copy into the new temporary. 71389d81ab16c05818b290ed735c1343d3abde449bfIan Romanick */ 714847f991a87b9549eb89a521edb7cd149005006bbBrian Paul assert((int) ir->num_state_slots == type_size(ir->type)); 71589d81ab16c05818b290ed735c1343d3abde449bfIan Romanick 7166c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 7176c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp); 7186c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 7196c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp += type_size(ir->type); 7206c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 721cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst = dst_reg(src_reg(PROGRAM_TEMPORARY, storage->index, NULL)); 7226c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7236c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7246c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 725a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick for (unsigned int i = 0; i < ir->num_state_slots; i++) { 726a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick int index = _mesa_add_state_reference(this->prog->Parameters, 727a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick (gl_state_index *)slots[i].tokens); 728a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick 729a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick if (storage->file == PROGRAM_STATE_VAR) { 730a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick if (storage->index == -1) { 731a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick storage->index = index; 7326c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 733a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick assert(index == storage->index + (int)i); 7346c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 735a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick } else { 736fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src(PROGRAM_STATE_VAR, index, NULL); 737a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick src.swizzle = slots[i].swizzle; 73801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, dst, src); 739a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick /* even a float takes up a whole vec4 reg in a struct/array. */ 740a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick dst.index++; 7416c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7426c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 743a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick 7446c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (storage->file == PROGRAM_TEMPORARY && 745847f991a87b9549eb89a521edb7cd149005006bbBrian Paul dst.index != storage->index + (int) ir->num_state_slots) { 7468aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(this->shader_program, 7478aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "failed to load builtin uniform `%s' " 7488aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "(%d/%d regs loaded)\n", 7498aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick ir->name, dst.index - storage->index, 7508aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick type_size(ir->type)); 7516c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7526c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 75384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 75484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 75584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 75684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 75784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 7580f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_dereference_variable *counter = NULL; 7590f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7600f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->counter != NULL) 761dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter = new(mem_ctx) ir_dereference_variable(ir->counter); 7620f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7630f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->from != NULL) { 7640f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick assert(ir->counter != NULL); 7650f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 766dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_assignment *a = 767dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_assignment(counter, ir->from, NULL); 7680f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7690f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 7700f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 77184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 77201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_BGNLOOP); 7730f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7740f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->to) { 7750f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 776dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type, 777dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter, ir->to); 778dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_if *if_stmt = new(mem_ctx) ir_if(e); 7790f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 780dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_loop_jump *brk = 781dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); 7820f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7830f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->then_instructions.push_tail(brk); 7840f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7850f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->accept(this); 7860f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 7870f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 78864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 7890f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7900f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->increment) { 7910f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 792dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_expression(ir_binop_add, counter->type, 793dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter, ir->increment); 7940f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 795dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_assignment *a = 796dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_assignment(counter, e, NULL); 7970f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7980f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 7990f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 8000f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 80101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_ENDLOOP); 80284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 80384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 80484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 80584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 80684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 80764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 80864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 80901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_BRK); 81064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 81164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 81201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_CONT); 81364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 81464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 81584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 81684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 81784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 81884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 81984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 82084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 82184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 82284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 82484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 82584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 82684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 82784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 82884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 82984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 83084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 83184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 83284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 83384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 83484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 83584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 83684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 83784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 83884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 83984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 84084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 84184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 84384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 84484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 84584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 84684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84779a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 8483f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 8493f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 8503f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 851fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg a, b, c; 8523f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8533f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 8543f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 8553f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 8563f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8573f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 8583f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 8593f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 8603f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 8613f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 8623f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 8633f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8643f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 86501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, c); 8663f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8673f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 8683f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 8693f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 870ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick/** 871ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * Emit OPCODE_MAD(a, -b, a) instead of AND(a, NOT(b)) 872ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 873ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * The logic values are 1.0 for true and 0.0 for false. Logical-and is 874ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * implemented using multiplication, and logical-or is implemented using 875ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * addition. Logical-not can be implemented as (true - x), or (1.0 - x). 876ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * As result, the logical expression (a & !b) can be rewritten as: 877ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 878ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a * !b 879ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a * (1 - b) 880ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - (a * 1) - (a * b) 881ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a + -(a * b) 882ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a + (a * -b) 883ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 884ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * This final expression can be implemented as a single MAD(a, -b, a) 885ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * instruction. 886ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick */ 887ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanickbool 888ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanickir_to_mesa_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand) 889ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick{ 890ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick const int other_operand = 1 - try_operand; 891ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick src_reg a, b; 892ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 893ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick ir_expression *expr = ir->operands[try_operand]->as_expression(); 894ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (!expr || expr->operation != ir_unop_logic_not) 895ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return false; 896ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 897ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick ir->operands[other_operand]->accept(this); 898ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick a = this->result; 899ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick expr->operands[0]->accept(this); 900ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick b = this->result; 901ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 902ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick b.negate = ~b.negate; 903ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 904ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick this->result = get_temp(ir->type); 905ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, a); 906ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 907ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return true; 908ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick} 909ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 91079a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 911ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholtir_to_mesa_visitor::try_emit_sat(ir_expression *ir) 912ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt{ 913ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt /* Saturates were only introduced to vertex programs in 914ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt * NV_vertex_program3, so don't give them to drivers in the VP. 915ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt */ 916ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 917ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 918ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 919ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 920ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (!sat_src) 921ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 922ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 923ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt sat_src->accept(this); 924fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src = this->result; 925ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 92662722d90af9d43d889af33b080a682f2004e049cEric Anholt /* If we generated an expression instruction into a temporary in 92762722d90af9d43d889af33b080a682f2004e049cEric Anholt * processing the saturate's operand, apply the saturate to that 92862722d90af9d43d889af33b080a682f2004e049cEric Anholt * instruction. Otherwise, generate a MOV to do the saturate. 92962722d90af9d43d889af33b080a682f2004e049cEric Anholt * 93062722d90af9d43d889af33b080a682f2004e049cEric Anholt * Note that we have to be careful to only do this optimization if 93162722d90af9d43d889af33b080a682f2004e049cEric Anholt * the instruction in question was what generated src->result. For 93262722d90af9d43d889af33b080a682f2004e049cEric Anholt * example, ir_dereference_array might generate a MUL instruction 93362722d90af9d43d889af33b080a682f2004e049cEric Anholt * to create the reladdr, and return us a src reg using that 93462722d90af9d43d889af33b080a682f2004e049cEric Anholt * reladdr. That MUL result is not the value we're trying to 93562722d90af9d43d889af33b080a682f2004e049cEric Anholt * saturate. 93662722d90af9d43d889af33b080a682f2004e049cEric Anholt */ 93762722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_expression *sat_src_expr = sat_src->as_expression(); 93862722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_to_mesa_instruction *new_inst; 93962722d90af9d43d889af33b080a682f2004e049cEric Anholt new_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 94062722d90af9d43d889af33b080a682f2004e049cEric Anholt if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul || 94162722d90af9d43d889af33b080a682f2004e049cEric Anholt sat_src_expr->operation == ir_binop_add || 94262722d90af9d43d889af33b080a682f2004e049cEric Anholt sat_src_expr->operation == ir_binop_dot)) { 94362722d90af9d43d889af33b080a682f2004e049cEric Anholt new_inst->saturate = true; 94462722d90af9d43d889af33b080a682f2004e049cEric Anholt } else { 94562722d90af9d43d889af33b080a682f2004e049cEric Anholt this->result = get_temp(ir->type); 94662722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_to_mesa_instruction *inst; 94762722d90af9d43d889af33b080a682f2004e049cEric Anholt inst = emit(ir, OPCODE_MOV, dst_reg(this->result), src); 94862722d90af9d43d889af33b080a682f2004e049cEric Anholt inst->saturate = true; 94962722d90af9d43d889af33b080a682f2004e049cEric Anholt } 950ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 951ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return true; 952ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt} 953ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 95484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 955f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 956fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg *reg, int *num_reladdr) 957f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 958f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 959f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 960f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 961ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_ARL, address_reg, *reg->reladdr); 962f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 963f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 964fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 965f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 96601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, dst_reg(temp), *reg); 967f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 968f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 969f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 970f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 971f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 972f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 973f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 97411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickir_to_mesa_visitor::emit_swz(ir_expression *ir) 97511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick{ 97611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Assume that the vector operator is in a form compatible with OPCODE_SWZ. 97711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This means that each of the operands is either an immediate value of -1, 97811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * 0, or 1, or is a component from one source register (possibly with 97911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * negation). 98011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 98111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick uint8_t components[4] = { 0 }; 98211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick bool negate[4] = { false }; 98311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_variable *var = NULL; 98411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 98511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick for (unsigned i = 0; i < ir->type->vector_elements; i++) { 98611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_rvalue *op = ir->operands[i]; 98711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 98811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 98911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 99011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick while (op != NULL) { 99111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick switch (op->ir_type) { 99211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_constant: { 99311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 99411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 99511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 99611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick const ir_constant *const c = op->as_constant(); 99711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (c->is_one()) { 99811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 99911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_zero()) { 100011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ZERO; 100111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_negative_one()) { 100211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 100311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 100411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else { 100511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"SWZ constant must be 0.0 or 1.0."); 100611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 100711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 100811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 100911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 101011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 101111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_dereference_variable: { 101311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 101411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick (ir_dereference_variable *) op; 101511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert((var == NULL) || (deref->var == var)); 101711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_X; 101811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick var = deref->var; 101911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 102011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 102111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 102211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_expression: { 102411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_expression *const expr = (ir_expression *) op; 102511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(expr->operation == ir_unop_neg); 102711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 102811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = expr->operands[0]; 103011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 103111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 103211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_swizzle: { 103411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_swizzle *const swiz = (ir_swizzle *) op; 103511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = swiz->mask.x; 103711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = swiz->val; 103811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 103911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 104011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 104111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick default: 104211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 104311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 104411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 104511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 104611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 104711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 104811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(var != NULL); 104911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 105111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick new(mem_ctx) ir_dereference_variable(var); 105211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result.file = PROGRAM_UNDEFINED; 105411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(this); 105511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (this->result.file == PROGRAM_UNDEFINED) { 105611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_print_visitor v; 105711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick printf("Failed to get tree for expression operand:\n"); 105811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(&v); 105911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick exit(1); 106011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 106111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 1062fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 106311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src = this->result; 106511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.swizzle = MAKE_SWIZZLE4(components[0], 106611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[1], 106711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[2], 106811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[3]); 106911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.negate = ((unsigned(negate[0]) << 0) 107011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[1]) << 1) 107111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[2]) << 2) 107211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[3]) << 3)); 107311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Storage for our result. Ideally for an assignment we'd be using the 107511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * actual storage for the result here, instead. 107611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 1077fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke const src_reg result_src = get_temp(ir->type); 1078cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg result_dst = dst_reg(result_src); 107911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 108011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Limit writes to the channels that will be used by result_src later. 108111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This does limit this temp's use as a temporary for multi-instruction 108211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * sequences. 108311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 108411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick result_dst.writemask = (1 << ir->type->vector_elements) - 1; 108511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 108601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SWZ, result_dst, src); 108711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result = result_src; 108811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick} 108911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 109011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickvoid 109184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 109284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 109384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 1094fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg op[Elements(ir->operands)]; 1095fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg result_src; 1096fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg result_dst; 109784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 10983f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 10993f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 11003f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 11013f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 11023f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11033f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 11043f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11053f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 1106ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 1107ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b)) 1108ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick */ 1109ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (ir->operation == ir_binop_logic_and) { 1110ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (try_emit_mad_for_and_not(ir, 1)) 1111ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return; 1112ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (try_emit_mad_for_and_not(ir, 0)) 1113ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return; 1114ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick } 1115ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 1116ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (try_emit_sat(ir)) 1117ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return; 11183f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 111911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (ir->operation == ir_quadop_vector) { 112011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->emit_swz(ir); 112111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 112211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 112311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 112484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 11250161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 112684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 11270161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 112884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 112984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 113084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 113184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 113284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 113384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 11348364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 11354ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 11364ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 11374ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 11384ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 113984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 114084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1141eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt int vector_elements = ir->operands[0]->type->vector_elements; 1142eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt if (ir->operands[1]) { 1143eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt vector_elements = MAX2(vector_elements, 1144eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt ir->operands[1]->type->vector_elements); 1145eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt } 1146eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt 11470161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 11480161515c395c44233529c8d51f823b60050bc7baEric Anholt 11490161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 11500161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 11510161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 11528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 11530161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 1154cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke result_dst = dst_reg(result_src); 11559cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 11569cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 11579cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 11589cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 11599cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 116084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 116184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 11621d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 11636ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick /* Previously 'SEQ dst, src, 0.0' was used for this. However, many 11646ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * older GPUs implement SEQ using multiple instructions (i915 uses two 11656ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * SGE instructions and a MUL instruction). Since our logic values are 11666ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * 0.0 and 1.0, 1-x also implements !x. 11676ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick */ 11686ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick op[0].negate = ~op[0].negate; 11696ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick emit(ir, OPCODE_ADD, result_dst, op[0], src_reg_for_float(1.0)); 11701d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1171c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 11720161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 11730161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 1174c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 1175524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 117601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_ABS, result_dst, op[0]); 1177524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 11783acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 117901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SSG, result_dst, op[0]); 11803acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 11818761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 118201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RCP, result_dst, op[0]); 11838761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 1184524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 11858c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 118601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_EX2, result_dst, op[0]); 11878c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 1188bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt case ir_unop_exp: 11898c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 1190bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 11918c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 11928c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 119301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_LG2, result_dst, op[0]); 11948c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 11953c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 119601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_SIN, result_dst, op[0]); 11973c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 11983c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 119901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_COS, result_dst, op[0]); 12003c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 1201f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_sin_reduced: 1202f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_SIN, result_dst, op[0]); 1203f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1204f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_cos_reduced: 1205f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_COS, result_dst, op[0]); 1206f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1207ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 1208ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 120901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_DDX, result_dst, op[0]); 1210ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1211ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 121201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_DDY, result_dst, op[0]); 1213ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1214ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 12153a5ce85cfa4914711e56c8cf831699242618928eIan Romanick case ir_unop_noise: { 12163a5ce85cfa4914711e56c8cf831699242618928eIan Romanick const enum prog_opcode opcode = 12173a5ce85cfa4914711e56c8cf831699242618928eIan Romanick prog_opcode(OPCODE_NOISE1 12183a5ce85cfa4914711e56c8cf831699242618928eIan Romanick + (ir->operands[0]->type->vector_elements) - 1); 12193a5ce85cfa4914711e56c8cf831699242618928eIan Romanick assert((opcode >= OPCODE_NOISE1) && (opcode <= OPCODE_NOISE4)); 12203a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 122101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, opcode, result_dst, op[0]); 12223a5ce85cfa4914711e56c8cf831699242618928eIan Romanick break; 12233a5ce85cfa4914711e56c8cf831699242618928eIan Romanick } 12243a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 122584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 122601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 122784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 122884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 122901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SUB, result_dst, op[0], op[1]); 123084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 12319b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 123284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 123301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 123484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 123584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 12369a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1237e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke break; 1238411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 1239e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */ 1240e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke assert(ir->type->is_integer()); 1241e66fc1cb035caa5375c4ef3578420476ea94d371Kenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 1242411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 124338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 124438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 124501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SLT, result_dst, op[0], op[1]); 124638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 124738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 124801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SGT, result_dst, op[0], op[1]); 124938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 125038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 125101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SLE, result_dst, op[0], op[1]); 125238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 125338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 125401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SGE, result_dst, op[0], op[1]); 125538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 125638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 125701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 12584dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12594dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_nequal: 126001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 12614dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12624dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_all_equal: 12636992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "==" operator producing a scalar boolean. */ 12646992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 12656992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 1266fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 126701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]); 1268ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick 1269ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick /* After the dot-product, the value will be an integer on the 1270ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * range [0,4]. Zero becomes 1.0, and positive values become zero. 1271ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick */ 127201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_dp(ir, result_dst, temp, temp, vector_elements); 1273ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick 1274ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick /* Negating the result of the dot-product gives values on the range 1275ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * [-4, 0]. Zero becomes 1.0, and negative values become zero. This 1276ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * achieved using SGE. 1277ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick */ 1278ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick src_reg sge_src = result_src; 1279ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick sge_src.negate = ~sge_src.negate; 1280ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick emit(ir, OPCODE_SGE, result_dst, sge_src, src_reg_for_float(0.0)); 12816992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 128201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 12836992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 128438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 12854dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_any_nequal: 12866992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "!=" operator producing a scalar boolean. */ 12876992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 12886992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 1289fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 129001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]); 1291e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick 1292e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* After the dot-product, the value will be an integer on the 1293e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * range [0,4]. Zero stays zero, and positive values become 1.0. 1294e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1295e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick ir_to_mesa_instruction *const dp = 1296e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick emit_dp(ir, result_dst, temp, temp, vector_elements); 1297e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 1298e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* The clamping to [0,1] can be done for free in the fragment 1299e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * shader with a saturate. 1300e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1301e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick dp->saturate = true; 1302e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick } else { 1303e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* Negating the result of the dot-product gives values on the range 1304e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * [-4, 0]. Zero stays zero, and negative values become 1.0. This 1305e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * achieved using SLT. 1306e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1307e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick src_reg slt_src = result_src; 1308e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick slt_src.negate = ~slt_src.negate; 1309e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 1310e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick } 13116992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 131201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 13136992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 13146992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt break; 13155e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 131692ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick case ir_unop_any: { 1317ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 131892ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick 131992ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* After the dot-product, the value will be an integer on the 132092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * range [0,4]. Zero stays zero, and positive values become 1.0. 132192ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 132292ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick ir_to_mesa_instruction *const dp = 132392ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick emit_dp(ir, result_dst, op[0], op[0], 132492ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick ir->operands[0]->type->vector_elements); 132592ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 132692ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* The clamping to [0,1] can be done for free in the fragment 132792ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * shader with a saturate. 132892ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 132992ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick dp->saturate = true; 133092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } else { 133192ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* Negating the result of the dot-product gives values on the range 133292ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * [-4, 0]. Zero stays zero, and negative values become 1.0. This 133392ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * is achieved using SLT. 133492ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 133592ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick src_reg slt_src = result_src; 133692ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick slt_src.negate = ~slt_src.negate; 133792ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 133892ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } 13395e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 134092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } 13415e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 13426992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt case ir_binop_logic_xor: 134301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 134438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 134538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 134641f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick case ir_binop_logic_or: { 134741f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* After the addition, the value will be an integer on the 134841f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * range [0,2]. Zero stays zero, and positive values become 1.0. 134941f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 135041f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick ir_to_mesa_instruction *add = 135141f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 135241f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 135341f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* The clamping to [0,1] can be done for free in the fragment 135441f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * shader with a saturate. 135541f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 135641f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick add->saturate = true; 135741f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } else { 135841f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* Negating the result of the addition gives values on the range 135941f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * [-2, 0]. Zero stays zero, and negative values become 1.0. This 136041f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * is achieved using SLT. 136141f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 136241f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick src_reg slt_src = result_src; 136341f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick slt_src.negate = ~slt_src.negate; 136441f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 136541f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } 13664380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 136741f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } 13684380099c98119611ceee684669d00be26195c7d7Eric Anholt 13694380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 13704380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 137101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 13724380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 13734380099c98119611ceee684669d00be26195c7d7Eric Anholt 137484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 1375ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 1376ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type == ir->operands[1]->type); 137701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_dp(ir, result_dst, op[0], op[1], 137801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir->operands[0]->type->vector_elements); 137984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 13809be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 138184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 13824f189b3bf57a6500953dac49105f160af5fa6468Marek Olšák /* sqrt(x) = x * rsq(x). */ 138301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); 138401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, result_src, op[0]); 1385c9039fdb167865547dc9b3828d69b99209344999Brian Paul /* For incoming channels <= 0, set the result to 0. */ 1386c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0].negate = ~op[0].negate; 138701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, result_dst, 1388c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0], result_src, src_reg_for_float(0.0)); 138984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 1390878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 139101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); 1392878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 139350ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 1394006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_u2f: 1395d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 1396d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 1397006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_i2u: 1398006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_u2i: 1399423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 14000161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 140150ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 1402423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 1403fa584c50cf1ddbd96fba4a68563b57c82619e6f4Paul Berry case ir_unop_f2u: 140401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_TRUNC, result_dst, op[0]); 1405423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 14061d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 1407411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 140801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, 140966afcb560771b6ba6ad668156e9f442e86b9a7a2Eric Anholt op[0], src_reg_for_float(0.0)); 14101d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1411e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_f2i: // Ignore these 4, they can't happen here anyway 1412e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_f2u: 1413e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_i2f: 1414e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_u2f: 1415e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert break; 1416c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 141701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_TRUNC, result_dst, op[0]); 1418c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1419c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 14200161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 142101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FLR, result_dst, op[0]); 14220161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 1423c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1424c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 142501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FLR, result_dst, op[0]); 1426c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1427d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 142801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FRC, result_dst, op[0]); 1429d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 1430d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 1431c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 143201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MIN, result_dst, op[0], op[1]); 1433c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1434c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 143501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MAX, result_dst, op[0], op[1]); 1436c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1437904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 143801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_POW, result_dst, op[0], op[1]); 1439904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 1440e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 14411d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt /* GLSL 1.30 integer ops are unsupported in Mesa IR, but since 14421d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt * hardware backends have no way to avoid Mesa IR generation 14431d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt * even if they don't use it, we need to emit "something" and 14441d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt * continue. 14451d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt */ 1446e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 1447e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 1448e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 1449e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 1450e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 14511d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 14521d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt break; 14531d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt 14541d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt case ir_unop_bit_not: 1455d85d25dd1f4fd281bd210ba6ba5135ba1e3b535fKenneth Graunke case ir_unop_round_even: 14561d59de1456ba55d32bbe0c0ae45a9358e31e1cd2Eric Anholt emit(ir, OPCODE_MOV, result_dst, op[0]); 1457e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 145811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 14592ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt case ir_binop_ubo_load: 14602ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt assert(!"not supported"); 14612ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt break; 14622ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt 146311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_quadop_vector: 146411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* This operation should have already been handled. 146511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 146611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 146711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 146884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 1469b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 14700161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 147184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 147284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 147384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 147484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 147584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 147684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1477fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 147884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 147984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 148084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1481b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 1482b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 1483b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 1484b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 148584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 148684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 1487461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 1488461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke assert(src.file != PROGRAM_UNDEFINED); 148984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 149084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 149184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 149284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 149384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 1494461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x); 149584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 149684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 1497461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y); 149884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 149984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 1500461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z); 150184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 150284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 1503461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w); 150484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 150584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 150684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 150784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 150884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 150984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 1510698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 151184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 151284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 151384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1514461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 151584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1516461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke this->result = src; 151784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 151884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 151984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 152084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 152184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1522b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 1523304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul ir_variable *var = ir->var; 152484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15258364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1526304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul switch (var->mode) { 15278364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 1528304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1529304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul var->location); 1530b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 15318364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 15328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 15338364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1534a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1535a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * including deprecated builtins (like gl_Color), 1536a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * user-assigned generic attributes (glBindVertexLocation), 1537a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * and user-defined varyings. 1538a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1539a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1540f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1541304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul assert(var->location != -1); 15422b7be12d5467096362073260911a380c64c772d0Brian Paul entry = new(mem_ctx) variable_storage(var, 15432b7be12d5467096362073260911a380c64c772d0Brian Paul PROGRAM_INPUT, 15442b7be12d5467096362073260911a380c64c772d0Brian Paul var->location); 154586471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul break; 154686471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul case ir_var_out: 154786471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul assert(var->location != -1); 154886471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul entry = new(mem_ctx) variable_storage(var, 154986471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul PROGRAM_OUTPUT, 155086471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul var->location); 15518364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 15527baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul case ir_var_system_value: 15537baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul entry = new(mem_ctx) variable_storage(var, 15547baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul PROGRAM_SYSTEM_VALUE, 15557baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul var->location); 15567baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul break; 15578364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 15587e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1559304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1560b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1561b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1562224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 1563304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul next_temp += type_size(var->type); 15648364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 156584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 15668364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 15678364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1568304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul printf("Failed to make storage for %s\n", var->name); 15698364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1570224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 157184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 157284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1573fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke this->result = src_reg(entry->file, entry->index, var->type); 157484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 157584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 157684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 157784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 157884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1579ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 1580fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 15818258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1582ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1583ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 15844e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 1585ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 1586461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 15874e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 15884d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 1589461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index += index->value.i[0] * element_size; 15904e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 15914d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 15924d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 15934d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 15944d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 15954d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 15968258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 1597fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg index_reg; 15988258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 15994d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 16004d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 16014d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 16024d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1603f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 160401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, dst_reg(index_reg), 160501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke this->result, src_reg_for_float(element_size)); 1606bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 16074d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 1608d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick /* If there was already a relative address register involved, add the 1609d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick * new and the old together to get the new offset. 1610d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick */ 1611d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick if (src.reladdr != NULL) { 1612d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick src_reg accum_reg = get_temp(glsl_type::float_type); 1613d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1614d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick emit(ir, OPCODE_ADD, dst_reg(accum_reg), 1615d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick index_reg, *src.reladdr); 1616d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1617d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick index_reg = accum_reg; 1618d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick } 1619d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1620fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src.reladdr = ralloc(mem_ctx, src_reg); 1621461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke memcpy(src.reladdr, &index_reg, sizeof(index_reg)); 16224e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 162384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 162484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 162585e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 1626461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = swizzle_for_size(ir->type->vector_elements); 162785e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 1628461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = SWIZZLE_NOOP; 162984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1630461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke this->result = src; 163184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 163284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 16332c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 16342c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 16352c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 16362c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 16370161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 16382c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 16392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16400161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 16412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16422c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 16430161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 16442c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 16452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 16462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 16472d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16482d577ee730c30caacf711babde6542766aa0b655Ian Romanick /* If the type is smaller than a vec4, replicate the last channel out. */ 16492d577ee730c30caacf711babde6542766aa0b655Ian Romanick if (ir->type->is_scalar() || ir->type->is_vector()) 16502d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 16512d577ee730c30caacf711babde6542766aa0b655Ian Romanick else 16522d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = SWIZZLE_NOOP; 16532d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16540161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 16552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 16562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 16582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 16592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 16602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 16612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 1662fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkestatic dst_reg 1663fc63e37b971b641dfdff000ba353c4810414c20eIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v) 1664b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 16655a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* The LHS must be a dereference. If the LHS is a variable indexed array 16665a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * access of a vector, it must be separated into a series conditional moves 16675a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * before reaching this point (see ir_vec_index_to_cond_assign). 16685a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 16695a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->as_dereference()); 1670ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1671ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1672ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1673ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1674ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 16750161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 16760161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 16770161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 16782c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 1679cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke return dst_reg(v->result); 1680cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1681cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1682c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick/** 1683c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Process the condition of a conditional assignment 1684c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1685c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Examines the condition of a conditional assignment to generate the optimal 1686c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * first operand of a \c CMP instruction. If the condition is a relational 1687c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 1688c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * used as the source for the \c CMP instruction. Otherwise the comparison 1689c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * is processed to a boolean result, and the boolean result is used as the 1690c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operand to the CMP instruction. 1691c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1692c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickbool 1693c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) 1694c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick{ 1695c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_rvalue *src_ir = ir; 1696c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool negate = true; 1697c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool switch_order = false; 1698c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1699c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_expression *const expr = ir->as_expression(); 1700c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if ((expr != NULL) && (expr->get_num_operands() == 2)) { 1701c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool zero_on_left = false; 1702c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1703c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (expr->operands[0]->is_zero()) { 1704c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[1]; 1705c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = true; 1706c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else if (expr->operands[1]->is_zero()) { 1707c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[0]; 1708c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = false; 1709c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1710c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1711c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* a is - 0 + - 0 + 1712c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a < 0) T F F ( a < 0) T F F 1713c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 < a) F F T (-a < 0) F F T 1714c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 1715c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 1716c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a > 0) F F T (-a < 0) F F T 1717c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 > a) T F F ( a < 0) T F F 1718c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 1719c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 1720c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1721c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Note that exchanging the order of 0 and 'a' in the comparison simply 1722c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * means that the value of 'a' should be negated. 1723c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1724c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (src_ir != ir) { 1725c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch (expr->operation) { 1726c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_less: 1727c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1728c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1729c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1730c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1731c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_greater: 1732c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1733c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1734c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1735c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1736c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_lequal: 1737c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1738c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1739c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1740c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1741c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_gequal: 1742c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1743c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1744c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1745c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1746c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick default: 1747c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* This isn't the right kind of comparison afterall, so make sure 1748c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * the whole condition is visited. 1749c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1750c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = ir; 1751c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1752c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1753c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1754c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1755c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1756c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir->accept(this); 1757c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1758c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 1759c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * condition we produced is 0.0 or 1.0. By flipping the sign, we can 1760c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * choose which value OPCODE_CMP produces without an extra instruction 1761c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * computing the condition. 1762c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1763c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (negate) 1764c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick this->result.negate = ~this->result.negate; 1765c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1766c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick return switch_order; 1767c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick} 1768c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 176984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 177084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 177184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1772fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg l; 1773fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r; 17747d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 177584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 177684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 177784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1778cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1779fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick l = get_assignment_lhs(ir->lhs, this); 1780cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 17815a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This should really set to the correct maximal writemask for each 17825a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: component written (in the loops below). This case can only 17835a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: occur for matrices, arrays, and structures. 17845a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 17855a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick if (ir->write_mask == 0) { 17865a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 17875a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 17885a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else if (ir->lhs->type->is_scalar()) { 1789b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 17905a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: W component of fragment shader output zero, work correctly. 17915a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 17925a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 17935a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else { 1794b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int swizzles[4]; 1795b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int first_enabled_chan = 0; 1796b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int rhs_chan = 0; 1797b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 17985a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->lhs->type->is_vector()); 17995a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = ir->write_mask; 1800b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1801b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1802b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) { 1803b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt first_enabled_chan = GET_SWZ(r.swizzle, i); 1804b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt break; 1805b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1806b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1807b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1808b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* Swizzle a small RHS vector into the channels being written. 1809b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * 1810b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * glsl ir treats write_mask as dictating how many channels are 1811b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * present on the RHS while Mesa IR treats write_mask as just 1812b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * showing which channels of the vec4 RHS get written. 1813b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt */ 1814b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1815b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) 1816b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 1817b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt else 1818b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = first_enabled_chan; 1819b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1820b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 1821b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[2], swizzles[3]); 18225a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } 18235a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick 18240161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 18250161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 182684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1827346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 1828c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick const bool switch_order = this->process_move_condition(ir->condition); 1829fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg condition = this->result; 18302d1789e667c4180777829f96856daf91326721b9Eric Anholt 18317d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 1832c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (switch_order) { 183301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, l, condition, src_reg(l), r); 1834c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else { 183501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, l, condition, r, src_reg(l)); 1836c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1837c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 18387d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 18397d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 18407d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 18412d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 18427d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 184301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 18447d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 18457d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 18467d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1847346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 184884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 184984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 185084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 185184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 185284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 185384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1854fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 18550a46497a4ee3325fab47929cb17cfe2525e1fc33Vinson Lee GLfloat stack_vals[4] = { 0 }; 18560bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 18570bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 185884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 18595b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt /* Unfortunately, 4 floats is all we can get into 18605b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store an 18615b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * aggregate constant and move each constant value into it. If we 18625b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * get lucky, copy propagation will eliminate the extra moves. 18635b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt */ 18645b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18655b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt if (ir->type->base_type == GLSL_TYPE_STRUCT) { 1866fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp_base = get_temp(ir->type); 1867cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg temp = dst_reg(temp_base); 18685b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18695b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt foreach_iter(exec_list_iterator, iter, ir->components) { 18705b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_constant *field_value = (ir_constant *)iter.get(); 18715b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt int size = type_size(field_value->type); 18725b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18735b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt assert(size > 0); 18745b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18755b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt field_value->accept(this); 1876461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 18775b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18785b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt for (i = 0; i < (unsigned int)size; i++) { 187901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, temp, src); 18805b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 1881461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index++; 18825b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt temp.index++; 18835b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18845b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18855b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt this->result = temp_base; 18865b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt return; 18875b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18885b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 188920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (ir->type->is_array()) { 1890fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp_base = get_temp(ir->type); 1891cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg temp = dst_reg(temp_base); 189220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt int size = type_size(ir->type->fields.array); 189320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 189420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt assert(size > 0); 189520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 189620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < ir->type->length; i++) { 189720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir->array_elements[i]->accept(this); 1898461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 189920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (int j = 0; j < size; j++) { 190001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, temp, src); 190120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1902461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index++; 190320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt temp.index++; 190420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 190520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 190620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt this->result = temp_base; 190720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt return; 190820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 190920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1910ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1911fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg mat = get_temp(ir->type); 1912cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg mat_column = dst_reg(mat); 1913ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1914ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1915ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1916ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1917ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1918fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src = src_reg(PROGRAM_CONSTANT, -1, NULL); 1919461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = _mesa_add_unnamed_constant(this->prog->Parameters, 19206d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 19219c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 1922461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke &src.swizzle); 192301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, mat_column, src); 1924ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1925ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1926ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1927ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1928ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1929ebef04011736ea8e13692fed87623d425c4d1b08Eric Anholt return; 1930582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 19310bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 1932461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.file = PROGRAM_CONSTANT; 19330bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 19340bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 19350bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 19360bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19370bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 19380bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19390bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 19400bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19410bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19420bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 19430bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19440bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 19450bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19460bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19470bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 19480bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19490bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 19500bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19510bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19520bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 19530bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 19540bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19550bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 1956fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke this->result = src_reg(PROGRAM_CONSTANT, -1, ir->type); 19579c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, 19586d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 19599c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 19609c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &this->result.swizzle); 196184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 196284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 196384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 196484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 196584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1966781e2d5cfae37c24180c0c622467f656582af9f5Kenneth Graunke assert(!"ir_to_mesa: All function calls should have been inlined by now."); 196784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 196884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 196984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 197084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 197184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 197268074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke src_reg result_src, coord, lod_info, projector, dx, dy; 1973fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg result_dst, coord_dst; 1974d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 1975d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 197684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1977ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke if (ir->op == ir_txs) 1978ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke this->result = src_reg_for_float(0.0); 1979ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke else 1980ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->coordinate->accept(this); 1981d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1982d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 1983d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 1984d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 1985d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 1986d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1987d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 1988cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke coord_dst = dst_reg(coord); 198901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, this->result); 1990d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1991de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 1992de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 1993de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 1994de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 1995de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 1996d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 1997d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 1998d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1999d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 2000cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke result_dst = dst_reg(result_src); 2001d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2002d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 2003d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 2004ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txs: 2005d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 2006d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2007d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 2008d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 2009d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 2010d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2011d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 201230be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke case ir_txf: 201330be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke /* Pretend to be TXL so the sampler, coordinate, lod are available */ 2014d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 2015d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 2016d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 2017d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2018d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2019d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 202068074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke opcode = OPCODE_TXD; 202168074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke ir->lod_info.grad.dPdx->accept(this); 202268074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke dx = this->result; 202368074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke ir->lod_info.grad.dPdy->accept(this); 202468074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke dy = this->result; 202568074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke break; 2026d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2027d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2028da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák const glsl_type *sampler_type = ir->sampler->type; 2029da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 2030d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 2031d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 2032d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 2033d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 203401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, projector); 2035d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2036d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 2037d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 2038fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg coord_w = coord; 2039d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 2040d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2041d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 2042d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 2043d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 2044d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2045d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 204601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_RCP, coord_dst, projector); 2047d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 20489996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* In the case where we have to project the coordinates "by hand," 20499996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * the shadow comparitor value must also be projected. 20509996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 205101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg tmp_src = coord; 20529996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick if (ir->shadow_comparitor) { 20539996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* Slot the shadow value in as the second to last component of the 20549996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * coord. 20559996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 20569996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick ir->shadow_comparitor->accept(this); 20579996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 20589996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_src = get_temp(glsl_type::vec4_type); 205901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg tmp_dst = dst_reg(tmp_src); 20609996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 2061da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák /* Projective division not allowed for array samplers. */ 2062da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák assert(!sampler_type->sampler_array); 2063da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 20649996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_dst.writemask = WRITEMASK_Z; 206501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, tmp_dst, this->result); 20669996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 20679996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_dst.writemask = WRITEMASK_XY; 206801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, tmp_dst, coord); 20699996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick } 20709996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 2071d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 207201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, coord_dst, tmp_src, coord_w); 2073d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2074d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2075d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 2076d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2077d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2078d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 20799996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* If projection is done and the opcode is not OPCODE_TXP, then the shadow 20809996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * comparitor was put in the correct place (and projected) by the code, 20819996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * above, that handles by-hand projection. 20829996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 20839996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick if (ir->shadow_comparitor && (!ir->projector || opcode == OPCODE_TXP)) { 2084b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 2085b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 2086b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 2087b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 2088da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 2089da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák /* XXX This will need to be updated for cubemap array samplers. */ 2090da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D && 2091da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák sampler_type->sampler_array) { 2092da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák coord_dst.writemask = WRITEMASK_W; 2093da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák } else { 2094da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák coord_dst.writemask = WRITEMASK_Z; 2095da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák } 2096da7233840f3eca0ba892ca318081c88e2457cc63Marek Olšák 209701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, this->result); 2098b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2099b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 2100b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2101d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 2102d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 2103d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 210401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, lod_info); 2105d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2106d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2107d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 210868074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke if (opcode == OPCODE_TXD) 210968074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke inst = emit(ir, opcode, result_dst, coord, dx, dy); 211068074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke else 211168074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke inst = emit(ir, opcode, result_dst, coord); 2112d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2113b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 2114b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 2115b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2116a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2117a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->shader_program, 2118a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->prog); 2119c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt 2120c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt switch (sampler_type->sampler_dimensionality) { 2121d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 2122c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 21230a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2124d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2125d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 2126c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 21270a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2128d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2129d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 2130d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 2131d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2132d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 2133d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 2134d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 21350bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick case GLSL_SAMPLER_DIM_RECT: 21360bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick inst->tex_target = TEXTURE_RECT_INDEX; 21370bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick break; 213868772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick case GLSL_SAMPLER_DIM_BUF: 213968772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"FINISHME: Implement ARB_texture_buffer_object"); 214068772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick break; 21410c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu case GLSL_SAMPLER_DIM_EXTERNAL: 21420c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu inst->tex_target = TEXTURE_EXTERNAL_INDEX; 21430c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu break; 2144d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 214568772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"Should not get here."); 2146d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2147d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2148d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 214984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 215084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 215184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 215284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 215384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 2154781e2d5cfae37c24180c0c622467f656582af9f5Kenneth Graunke /* Non-void functions should have been inlined. We may still emit RETs 2155781e2d5cfae37c24180c0c622467f656582af9f5Kenneth Graunke * from main() unless the EmitNoMainReturn option is set. 2156781e2d5cfae37c24180c0c622467f656582af9f5Kenneth Graunke */ 2157781e2d5cfae37c24180c0c622467f656582af9f5Kenneth Graunke assert(!ir->get_value()); 215801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_RET); 215984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 216084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 216116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 216216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 216316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 2164ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák if (ir->condition) { 2165ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák ir->condition->accept(this); 2166ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák this->result.negate = ~this->result.negate; 2167ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_KIL, undef_dst, this->result); 2168ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } else { 216901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_KIL_NV); 2170ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } 217116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 217284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 217384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 217484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 217584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 2176847d397b3415b6705a084013903e1a7e8384e1d2Marek Olšák ir_to_mesa_instruction *cond_inst, *if_inst; 2177cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 2178cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2179cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2180c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2181c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 21820161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 2183c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 21846d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri if (this->options->EmitCondCodes) { 2185854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2186cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2187cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 2188cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 2189cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 2190cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 2191cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 2192fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::bool_type); 219301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke cond_inst = emit(ir->condition, OPCODE_MOV, dst_reg(temp), result); 2194cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 2195854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 2196854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 219701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke if_inst = emit(ir->condition, OPCODE_IF); 2198461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if_inst->dst.cond_mask = COND_NE; 2199854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 2200ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke if_inst = emit(ir->condition, OPCODE_IF, undef_dst, this->result); 2201854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 2202c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2203c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 2204c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2205c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 2206c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2207c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 2208847d397b3415b6705a084013903e1a7e8384e1d2Marek Olšák emit(ir->condition, OPCODE_ELSE); 22090a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 2210c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2211c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 22125d9718f0dbe1bb9b25324c43ed0fa631735c6a51Kenneth Graunke if_inst = emit(ir->condition, OPCODE_ENDIF); 221384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 221484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2215ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 2216ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 22170161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 2218ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 22197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 22207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 2221d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mem_ctx = ralloc_context(NULL); 2222ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 2223ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 2224fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor() 2225fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{ 2226d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(mem_ctx); 2227fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt} 2228fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt 222984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 2230fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkemesa_src_reg_from_ir_src_reg(src_reg reg) 223184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 223284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 223384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 223484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 223550fd99d1723a6c7f3bd2dedffeeadf7d5e33b83bBrian Paul assert(reg.index < (1 << INST_INDEX_BITS)); 223684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 223734195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 2238f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 2239ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 2240285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 2241b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt mesa_reg.HasIndex2 = GL_FALSE; 2242405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.RelAddr2 = 0; 2243405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.Index2 = 0; 224484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 224584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 224684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 224784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2248c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 22497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 22507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 2251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2252c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2253e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 225464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 225564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 225664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 2257c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2258c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 225964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 226064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 2261c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 226264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 226364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 226464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 226564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 226664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 226764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 226864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 226964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 227064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 227164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 227264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 2273c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2274c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2275d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke if_stack = rzalloc_array(v->mem_ctx, int, if_count); 2276d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke loop_stack = rzalloc_array(v->mem_ctx, int, loop_count); 2277c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2278c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2279c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 2280c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 228164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 2282c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 2283c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2284c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 228564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 228664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 2287c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2288c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 228964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 2290c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 2291c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 229264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 229364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 229464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 229564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 229664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 229764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 229864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 229964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 230064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 230164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 230264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 230364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 230464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 230564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 230664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 230764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 230864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 230964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 231064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 231164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 231264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 23137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 23147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 23157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 23167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 23177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 23187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 23197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 23207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 23217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 23227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 23237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 2324c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 2325c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2326c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2327c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2328c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2329c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2330c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 2331c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 2332c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 2333c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2334c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2335c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 2336c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2337748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 2338c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2339c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2340c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 2341c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 2342c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2343748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 2344748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 234564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 2346748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 2347748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2348748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 2349748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 2350748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 2351748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 2352c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 2353c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 2354748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2355748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 2356c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2357c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2358748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 2359748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 2360c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2361c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2362c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 23636437a71d4172273db670b959dd66e3b34c866962Ian Romanickclass add_uniform_to_shader : public uniform_field_visitor { 23646437a71d4172273db670b959dd66e3b34c866962Ian Romanickpublic: 23656437a71d4172273db670b959dd66e3b34c866962Ian Romanick add_uniform_to_shader(struct gl_shader_program *shader_program, 23666437a71d4172273db670b959dd66e3b34c866962Ian Romanick struct gl_program_parameter_list *params) 236710ec14865aa7d0110ae202011be36d6e4a7ba154Vinson Lee : shader_program(shader_program), params(params), idx(-1) 23686437a71d4172273db670b959dd66e3b34c866962Ian Romanick { 23696437a71d4172273db670b959dd66e3b34c866962Ian Romanick /* empty */ 23706437a71d4172273db670b959dd66e3b34c866962Ian Romanick } 23718cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 2372719909698c67c287a393d2380278e7b7495ae018Ian Romanick void process(ir_variable *var) 23736437a71d4172273db670b959dd66e3b34c866962Ian Romanick { 23746437a71d4172273db670b959dd66e3b34c866962Ian Romanick this->idx = -1; 23756437a71d4172273db670b959dd66e3b34c866962Ian Romanick this->uniform_field_visitor::process(var); 23766437a71d4172273db670b959dd66e3b34c866962Ian Romanick 2377719909698c67c287a393d2380278e7b7495ae018Ian Romanick var->location = this->idx; 23786437a71d4172273db670b959dd66e3b34c866962Ian Romanick } 23796437a71d4172273db670b959dd66e3b34c866962Ian Romanick 23806437a71d4172273db670b959dd66e3b34c866962Ian Romanickprivate: 23816437a71d4172273db670b959dd66e3b34c866962Ian Romanick virtual void visit_field(const glsl_type *type, const char *name); 23826437a71d4172273db670b959dd66e3b34c866962Ian Romanick 23836437a71d4172273db670b959dd66e3b34c866962Ian Romanick struct gl_shader_program *shader_program; 23846437a71d4172273db670b959dd66e3b34c866962Ian Romanick struct gl_program_parameter_list *params; 23856437a71d4172273db670b959dd66e3b34c866962Ian Romanick int idx; 23866437a71d4172273db670b959dd66e3b34c866962Ian Romanick}; 23876437a71d4172273db670b959dd66e3b34c866962Ian Romanick 23886437a71d4172273db670b959dd66e3b34c866962Ian Romanickvoid 23896437a71d4172273db670b959dd66e3b34c866962Ian Romanickadd_uniform_to_shader::visit_field(const glsl_type *type, const char *name) 239085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 2391b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick unsigned int size; 239299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 2393b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (type->is_vector() || type->is_scalar()) { 2394b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick size = type->vector_elements; 2395b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } else { 2396b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick size = type_size(type) * 4; 2397b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } 239885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2399b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick gl_register_file file; 2400b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (type->is_sampler() || 2401b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick (type->is_array() && type->fields.array->is_sampler())) { 2402b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick file = PROGRAM_SAMPLER; 2403b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } else { 2404b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick file = PROGRAM_UNIFORM; 2405b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick } 24060924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 24076437a71d4172273db670b959dd66e3b34c866962Ian Romanick int index = _mesa_lookup_parameter_index(params, -1, name); 2408b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (index < 0) { 24096437a71d4172273db670b959dd66e3b34c866962Ian Romanick index = _mesa_add_parameter(params, file, name, size, type->gl_type, 2410b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick NULL, NULL, 0x0); 24110924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2412b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick /* Sampler uniform values are stored in prog->SamplerUnits, 2413b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * and the entry in that array is selected by this index we 2414b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * store in ParameterValues[]. 2415b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick */ 2416b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if (file == PROGRAM_SAMPLER) { 2417719909698c67c287a393d2380278e7b7495ae018Ian Romanick unsigned location; 2418719909698c67c287a393d2380278e7b7495ae018Ian Romanick const bool found = 2419719909698c67c287a393d2380278e7b7495ae018Ian Romanick this->shader_program->UniformHash->get(location, 2420719909698c67c287a393d2380278e7b7495ae018Ian Romanick params->Parameters[index].Name); 2421719909698c67c287a393d2380278e7b7495ae018Ian Romanick assert(found); 2422719909698c67c287a393d2380278e7b7495ae018Ian Romanick 2423719909698c67c287a393d2380278e7b7495ae018Ian Romanick if (!found) 2424719909698c67c287a393d2380278e7b7495ae018Ian Romanick return; 2425719909698c67c287a393d2380278e7b7495ae018Ian Romanick 2426719909698c67c287a393d2380278e7b7495ae018Ian Romanick struct gl_uniform_storage *storage = 2427719909698c67c287a393d2380278e7b7495ae018Ian Romanick &this->shader_program->UniformStorage[location]; 2428719909698c67c287a393d2380278e7b7495ae018Ian Romanick 2429b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick for (unsigned int j = 0; j < size / 4; j++) 2430719909698c67c287a393d2380278e7b7495ae018Ian Romanick params->ParameterValues[index + j][0].f = storage->sampler + j; 243199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 243299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 243399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 24346437a71d4172273db670b959dd66e3b34c866962Ian Romanick /* The first part of the uniform that's processed determines the base 24356437a71d4172273db670b959dd66e3b34c866962Ian Romanick * location of the whole uniform (for structures). 24366437a71d4172273db670b959dd66e3b34c866962Ian Romanick */ 24376437a71d4172273db670b959dd66e3b34c866962Ian Romanick if (this->idx < 0) 24386437a71d4172273db670b959dd66e3b34c866962Ian Romanick this->idx = index; 2439b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick} 24400924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2441b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick/** 2442b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * Generate the program parameters list for the user uniforms in a shader 2443b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * 2444b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * \param shader_program Linked shader program. This is only used to 2445b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * emit possible link errors to the info log. 2446b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * \param sh Shader whose uniforms are to be processed. 2447b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick * \param params Parameter list to be filled in. 2448b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick */ 2449b2572928a50ce42abc2733202d08f5a00733d707Ian Romanickvoid 2450b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program 2451b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick *shader_program, 2452b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick struct gl_shader *sh, 2453b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick struct gl_program_parameter_list 2454b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick *params) 2455b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick{ 24566437a71d4172273db670b959dd66e3b34c866962Ian Romanick add_uniform_to_shader add(shader_program, params); 245785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2458b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick foreach_list(node, sh->ir) { 2459b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick ir_variable *var = ((ir_instruction *) node)->as_variable(); 24600924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2461b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick if ((var == NULL) || (var->mode != ir_var_uniform) 2462af3fc6bb2836ce545c624bce2b47c3fd8cf4f9faEric Anholt || var->uniform_block != -1 || (strncmp(var->name, "gl_", 3) == 0)) 2463b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick continue; 2464aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2465719909698c67c287a393d2380278e7b7495ae018Ian Romanick add.process(var); 246685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 246785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 246885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2469d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanickvoid 2470d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick_mesa_associate_uniform_storage(struct gl_context *ctx, 2471d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick struct gl_shader_program *shader_program, 2472d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick struct gl_program_parameter_list *params) 2473d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick{ 2474d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick /* After adding each uniform to the parameter list, connect the storage for 2475d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick * the parameter with the tracking structure used by the API for the 2476d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick * uniform. 2477d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick */ 2478d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick unsigned last_location = unsigned(~0); 2479d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick for (unsigned i = 0; i < params->NumParameters; i++) { 2480d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick if (params->Parameters[i].Type != PROGRAM_UNIFORM) 2481d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick continue; 2482d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 2483d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick unsigned location; 2484d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick const bool found = 2485d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick shader_program->UniformHash->get(location, params->Parameters[i].Name); 2486d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick assert(found); 2487d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 2488d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick if (!found) 2489d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick continue; 2490d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 2491d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick if (location != last_location) { 2492d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick struct gl_uniform_storage *storage = 2493d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick &shader_program->UniformStorage[location]; 2494d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick enum gl_uniform_driver_format format = uniform_native; 2495d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 2496d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick unsigned columns = 0; 2497d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick switch (storage->type->base_type) { 2498d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick case GLSL_TYPE_UINT: 2499d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick assert(ctx->Const.NativeIntegers); 2500d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick format = uniform_native; 2501d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick columns = 1; 2502d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick break; 2503d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick case GLSL_TYPE_INT: 2504d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick format = 2505d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float; 2506d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick columns = 1; 2507d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick break; 2508d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick case GLSL_TYPE_FLOAT: 2509d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick format = uniform_native; 2510d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick columns = storage->type->matrix_columns; 2511d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick break; 2512d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick case GLSL_TYPE_BOOL: 2513d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick if (ctx->Const.NativeIntegers) { 2514d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick format = (ctx->Const.UniformBooleanTrue == 1) 2515d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick ? uniform_bool_int_0_1 : uniform_bool_int_0_not0; 2516d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick } else { 2517d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick format = uniform_bool_float; 2518d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick } 2519d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick columns = 1; 2520d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick break; 2521d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick case GLSL_TYPE_SAMPLER: 2522d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick format = uniform_native; 2523d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick columns = 1; 2524d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick break; 2525d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick default: 2526d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick assert(!"Should not get here."); 2527d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick break; 2528d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick } 2529d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 2530d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick _mesa_uniform_attach_driver_storage(storage, 2531d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 4 * sizeof(float) * columns, 2532d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 4 * sizeof(float), 2533d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick format, 2534d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick ¶ms->ParameterValues[i]); 2535c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick 2536c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick /* After attaching the driver's storage to the uniform, propagate any 2537c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick * data from the linker's backing store. This will cause values from 2538c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick * initializers in the source code to be copied over. 2539c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick */ 2540c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick _mesa_propagate_uniforms_to_driver_storage(storage, 2541c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick 0, 2542c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick MAX2(1, storage->array_elements)); 2543c343b980d615bb3a159e0adc6e7597f2f9865323Ian Romanick 2544d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick last_location = location; 2545d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick } 2546d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick } 2547d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick} 2548d7a7e4fc99888da424f324d1fc7e066673e804c2Ian Romanick 254934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt/* 255034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * On a basic block basis, tracks available PROGRAM_TEMPORARY register 255134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * channels for copy propagation and updates following instructions to 255234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * use the original versions. 255334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 255434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * The ir_to_mesa_visitor lazily produces code assuming that this pass 255534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * will occur. As an example, a TXP production before this pass: 255634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 255734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 255834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 255934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 256034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 256134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * and after: 256234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 256334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 256434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 256534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 256634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 256734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * which allows for dead code elimination on TEMP[1]'s writes. 256834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 256934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtvoid 257034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtir_to_mesa_visitor::copy_propagate(void) 257134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt{ 2572d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx, 257325beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt ir_to_mesa_instruction *, 257425beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt this->next_temp * 4); 25758902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 25768902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca int level = 0; 257734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 257834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt foreach_iter(exec_list_iterator, iter, this->instructions) { 257934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 258034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2581461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke assert(inst->dst.file != PROGRAM_TEMPORARY 2582461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke || inst->dst.index < this->next_temp); 25835c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick 258434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* First, do any copy propagation possible into the src regs. */ 258534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int r = 0; r < 3; r++) { 258634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *first = NULL; 258734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt bool good = true; 2588461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int acp_base = inst->src[r].index * 4; 258934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2590461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->src[r].file != PROGRAM_TEMPORARY || 2591461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].reladdr) 259234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt continue; 259334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 259434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* See if we can find entries in the ACP consisting of MOVs 259534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * from the same src register for all the swizzled channels 259634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * of this src register reference. 259734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 259834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2599461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(inst->src[r].swizzle, i); 260034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_chan = acp[acp_base + src_chan]; 260134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 260234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!copy_chan) { 260334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 260434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 260534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 260634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 26078902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca assert(acp_level[acp_base + src_chan] <= level); 26088902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 260934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!first) { 261034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt first = copy_chan; 261134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } else { 2612461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (first->src[0].file != copy_chan->src[0].file || 2613461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke first->src[0].index != copy_chan->src[0].index) { 261434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 261534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 261634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 261734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 261834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 261934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 262034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (good) { 262134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* We've now validated that we can copy-propagate to 262234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * replace this src register reference. Do it. 262334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 2624461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].file = first->src[0].file; 2625461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].index = first->src[0].index; 262634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 262734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt int swizzle = 0; 262834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2629461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(inst->src[r].swizzle, i); 263034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_inst = acp[acp_base + src_chan]; 2631461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << 263234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt (3 * i)); 263334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 2634461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].swizzle = swizzle; 263534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 263634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 263734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 263834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt switch (inst->op) { 263934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_BGNLOOP: 264034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_ENDLOOP: 264134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* End of a basic block, clear the ACP entirely. */ 264225beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 264334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 264434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 26458902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_IF: 26468902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca ++level; 26478902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca break; 26488902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 26498902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_ENDIF: 26508902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_ELSE: 26518902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca /* Clear all channels written inside the block from the ACP, but 26528902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca * leaving those that were not touched. 26538902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca */ 26548902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca for (int r = 0; r < this->next_temp; r++) { 26558902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca for (int c = 0; c < 4; c++) { 26568902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (!acp[4 * r + c]) 26578902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca continue; 26588902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 26598902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (acp_level[4 * r + c] >= level) 26608902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca acp[4 * r + c] = NULL; 26618902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca } 26628902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca } 26638902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (inst->op == OPCODE_ENDIF) 26648902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca --level; 26658902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca break; 26668902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 266734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt default: 266834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* Continuing the block, clear any written channels from 266934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * the ACP. 267034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 2671461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { 267276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Any temporary might be written, so no copy propagation 267376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt * across this instruction. 267476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt */ 267576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 2676461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke } else if (inst->dst.file == PROGRAM_OUTPUT && 2677461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.reladdr) { 267876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Any output might be written, so no copy propagation 267976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt * from outputs across this instruction. 268076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt */ 268176857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int r = 0; r < this->next_temp; r++) { 268276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 26833803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick if (!acp[4 * r + c]) 26843803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick continue; 26853803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick 2686461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) 268776857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt acp[4 * r + c] = NULL; 268876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 268976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 2690461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke } else if (inst->dst.file == PROGRAM_TEMPORARY || 2691461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.file == PROGRAM_OUTPUT) { 269276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Clear where it's used as dst. */ 2693461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.file == PROGRAM_TEMPORARY) { 269476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 2695461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.writemask & (1 << c)) { 2696461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * inst->dst.index + c] = NULL; 269776857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 269876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 269976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 270076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 270176857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Clear where it's used as src. */ 270276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int r = 0; r < this->next_temp; r++) { 270376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 270476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt if (!acp[4 * r + c]) 270576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt continue; 270676857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 2707461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); 270876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 2709461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (acp[4 * r + c]->src[0].file == inst->dst.file && 2710461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * r + c]->src[0].index == inst->dst.index && 2711461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask & (1 << src_chan)) 271276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt { 271376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt acp[4 * r + c] = NULL; 271434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 271534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 271634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 271734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 271834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 271934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 272034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 272134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* If this is a copy, add it to the ACP. */ 272234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->op == OPCODE_MOV && 2723461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.file == PROGRAM_TEMPORARY && 2724461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->dst.reladdr && 272534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt !inst->saturate && 2726461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->src[0].reladdr && 2727461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->src[0].negate) { 272834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2729461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.writemask & (1 << i)) { 2730461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * inst->dst.index + i] = inst; 2731461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp_level[4 * inst->dst.index + i] = level; 273234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 273334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 273434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 273534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 27367772a34f3aedfa8ef58ad5f912f56bd5adf27057Vinson Lee 27378902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca ralloc_free(acp_level); 2738d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(acp); 273934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt} 274034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2741f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 2742f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 2743f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Convert a shader's GLSL IR into a Mesa gl_program. 2744f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 27456162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulstatic struct gl_program * 27466162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulget_mesa_program(struct gl_context *ctx, 27476162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul struct gl_shader_program *shader_program, 274895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 274984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 275084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 275184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2752c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 2753c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2754364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 2755364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 2756c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 27576d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri struct gl_shader_compiler_options *options = 27586d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 2759364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2760364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 2761c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 2762c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 2763c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 2764c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2765c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 2766c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 2767c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 2768c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2769903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul case GL_GEOMETRY_SHADER: 2770903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target = GL_GEOMETRY_PROGRAM_NV; 2771903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target_string = "geometry"; 2772903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul break; 2773c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 2774c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 27754841c0a15adcc722e67d7d246987cd686d3f7a17José Fonseca return NULL; 2776364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 277784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 27781124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 27791124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 2780859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 2781364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 2782364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 2783364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 2784364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 2785364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 2786aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt v.shader_program = shader_program; 27876d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri v.options = options; 2788364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2789b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick _mesa_generate_parameters_list_for_uniforms(shader_program, shader, 2790b2572928a50ce42abc2733202d08f5a00733d707Ian Romanick prog->Parameters); 27910924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 27927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 279316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 279401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke v.emit(NULL, OPCODE_END); 279584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2796364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 2797364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 279884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 279984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 280084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 280184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 280284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 280384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 280484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 280584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 2806d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mesa_instruction_annotation = ralloc_array(v.mem_ctx, ir_instruction *, 2807364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 280884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 280934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt v.copy_propagate(); 281034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2811f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Convert ir_mesa_instructions into prog_instructions. 2812f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 281384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 2814c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 281584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 2816f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 2817b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 281884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 2819854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 2820ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (inst->saturate) 2821ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt mesa_inst->SaturateMode = SATURATE_ZERO_ONE; 2822461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.File = inst->dst.file; 2823461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.Index = inst->dst.index; 2824461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.CondMask = inst->dst.cond_mask; 2825461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.WriteMask = inst->dst.writemask; 2826461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.RelAddr = inst->dst.reladdr != NULL; 2827461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src[0]); 2828461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src[1]); 2829461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src[2]); 2830d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 2831d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 2832b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 2833c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 2834aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 28355755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák /* Set IndirectRegisterFiles. */ 28365755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->DstReg.RelAddr) 28375755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; 28385755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 2839f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Update program's bitmask of indirectly accessed register files */ 28405755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák for (unsigned src = 0; src < 3; src++) 28415755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->SrcReg[src].RelAddr) 28425755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; 28435755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 284440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt switch (mesa_inst->Opcode) { 2845322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_IF: 2846488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain if (options->MaxIfDepth == 0) { 2847322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 2848322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't flatten if-statement. " 2849322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 2850322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 2851322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 2852322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 2853322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_BGNLOOP: 2854322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick if (options->EmitNoLoops) { 2855322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 2856322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't unroll loop. " 2857322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 2858322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 2859322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 2860322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 2861322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_CONT: 2862322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick if (options->EmitNoCont) { 2863322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 2864322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't lower continue-statement. " 2865322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 2866322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 2867322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 2868322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 286940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ARL: 2870d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 287140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 287240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt default: 287340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 287440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt } 28757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 287684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 2877c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 28786162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 28796162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) 28806162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 28816162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 28826162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 28836162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) { 2884276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick goto fail_exit; 288584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 2886c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 28877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 2888925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 2889c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2890455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2891455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL IR for linked %s program %d:\n", target_string, 2892455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2893455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt _mesa_print_ir(shader->ir, NULL); 2894455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2895455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2896455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("Mesa IR for linked %s program %d:\n", target_string, 2897455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2898364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 2899364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 2900364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2901364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2902364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 2903364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 2904364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2905276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick /* Setting this to NULL prevents a possible double free in the fail_exit 2906276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick * path (far below). 2907276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick */ 2908276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick mesa_instructions = NULL; 2909276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick 2910cf45949d6a896651a5f3864d3b195e26d59eee74Paul Berry do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER); 29116c0df75803e1944f82a1468dcca47d23de82ea6bIan Romanick 29126c0df75803e1944f82a1468dcca47d23de82ea6bIan Romanick prog->SamplersUsed = shader->active_samplers; 29136c0df75803e1944f82a1468dcca47d23de82ea6bIan Romanick prog->ShadowSamplers = shader->shadow_samplers; 29146c0df75803e1944f82a1468dcca47d23de82ea6bIan Romanick _mesa_update_shader_textures_used(shader_program, prog); 2915925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 2916ec174a424489664626796126f937fbce3e7d8cd8Marek Olšák /* Set the gl_FragDepth layout. */ 2917ec174a424489664626796126f937fbce3e7d8cd8Marek Olšák if (target == GL_FRAGMENT_PROGRAM_ARB) { 2918ec174a424489664626796126f937fbce3e7d8cd8Marek Olšák struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; 2919ec174a424489664626796126f937fbce3e7d8cd8Marek Olšák fp->FragDepthLayout = shader_program->FragDepthLayout; 2920ec174a424489664626796126f937fbce3e7d8cd8Marek Olšák } 2921ec174a424489664626796126f937fbce3e7d8cd8Marek Olšák 292216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 2923364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 292428faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 292528faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 292628faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 292728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 2928719909698c67c287a393d2380278e7b7495ae018Ian Romanick /* This has to be done last. Any operation that can cause 2929719909698c67c287a393d2380278e7b7495ae018Ian Romanick * prog->ParameterValues to get reallocated (e.g., anything that adds a 2930719909698c67c287a393d2380278e7b7495ae018Ian Romanick * program constant) has to happen before creating this linkage. 2931719909698c67c287a393d2380278e7b7495ae018Ian Romanick */ 2932719909698c67c287a393d2380278e7b7495ae018Ian Romanick _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters); 2933719909698c67c287a393d2380278e7b7495ae018Ian Romanick if (!shader_program->LinkStatus) { 2934719909698c67c287a393d2380278e7b7495ae018Ian Romanick goto fail_exit; 2935719909698c67c287a393d2380278e7b7495ae018Ian Romanick } 2936719909698c67c287a393d2380278e7b7495ae018Ian Romanick 2937364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 2938276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick 2939276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanickfail_exit: 2940276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick free(mesa_instructions); 2941276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick _mesa_reference_program(ctx, &shader->Program, NULL); 2942276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick return NULL; 2943364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2944364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 294516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 2946f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 2947f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 2948f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a shader. 2949f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Called via ctx->Driver.LinkShader() 2950f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * This actually involves converting GLSL IR into Mesa gl_programs with 2951f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * code lowering and other optimizations. 2952f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 2953d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean 2954f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 2955d19eecef54384c163af27a470496ed885a5a271bEric Anholt{ 2956d19eecef54384c163af27a470496ed885a5a271bEric Anholt assert(prog->LinkStatus); 2957d19eecef54384c163af27a470496ed885a5a271bEric Anholt 29583322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 29593322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 29603322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 29613322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 2962d19eecef54384c163af27a470496ed885a5a271bEric Anholt bool progress; 2963d19eecef54384c163af27a470496ed885a5a271bEric Anholt exec_list *ir = prog->_LinkedShaders[i]->ir; 2964f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const struct gl_shader_compiler_options *options = 29656d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 2966d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2967d19eecef54384c163af27a470496ed885a5a271bEric Anholt do { 2968d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = false; 2969d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2970d19eecef54384c163af27a470496ed885a5a271bEric Anholt /* Lowering */ 2971d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_mat_op_to_vec(ir); 2972c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 2973478034f34a59969103237eb78bc82f9e70fe81c2Bryan Cain | LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP 2974c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); 2975d19eecef54384c163af27a470496ed885a5a271bEric Anholt 297687708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 297787708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri 29781d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick progress = do_common_optimization(ir, true, true, 29791d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick options->MaxUnrollIterations) 29801d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick || progress; 2981d19eecef54384c163af27a470496ed885a5a271bEric Anholt 298211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick progress = lower_quadop_vector(ir, true) || progress; 298311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 2984488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain if (options->MaxIfDepth == 0) 2985940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke progress = lower_discard(ir) || progress; 2986488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain 2987488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress; 2988d19eecef54384c163af27a470496ed885a5a271bEric Anholt 29892b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick if (options->EmitNoNoise) 29902b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick progress = lower_noise(ir) || progress; 29912b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick 2992a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick /* If there are forms of indirect addressing that the driver 2993a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick * cannot handle, perform the lowering pass. 2994a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick */ 2995a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 2996a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 2997a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick progress = 2998a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick lower_variable_index_to_cond_assign(ir, 2999a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectInput, 3000a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectOutput, 3001a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectTemp, 3002a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectUniform) 3003a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || progress; 3004a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick 3005d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = do_vec_index_to_cond_assign(ir) || progress; 3006d19eecef54384c163af27a470496ed885a5a271bEric Anholt } while (progress); 3007d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3008d19eecef54384c163af27a470496ed885a5a271bEric Anholt validate_ir_tree(ir); 3009d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3010d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30113322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 3012d19eecef54384c163af27a470496ed885a5a271bEric Anholt struct gl_program *linked_prog; 3013d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30143322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 30153322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 30163322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 3017d19eecef54384c163af27a470496ed885a5a271bEric Anholt linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 3018d19eecef54384c163af27a470496ed885a5a271bEric Anholt 30196162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (linked_prog) { 3020e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick static const GLenum targets[] = { 3021e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_VERTEX_PROGRAM_ARB, 3022e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_FRAGMENT_PROGRAM_ARB, 3023e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_GEOMETRY_PROGRAM_NV 3024e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick }; 30256162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 3026e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick if (i == MESA_SHADER_VERTEX) { 30271ad54ae0b1713e399c5db43d0eba87861075b4c7Paul Berry ((struct gl_vertex_program *)linked_prog)->UsesClipDistance 30281ad54ae0b1713e399c5db43d0eba87861075b4c7Paul Berry = prog->Vert.UsesClipDistance; 3029e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick } 3030e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick 3031e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 3032e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick linked_prog); 3033e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick if (!ctx->Driver.ProgramStringNotify(ctx, targets[i], linked_prog)) { 30346162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul return GL_FALSE; 30356162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 3036d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 30376162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 30383cd233eb5714137dccb6218ad78005511bcc02bdEric Anholt _mesa_reference_program(ctx, &linked_prog, NULL); 3039d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3040d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3041276000472abbc34d86fcb628bc3a1990e9581af3Ian Romanick return prog->LinkStatus; 3042d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 304316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 3044f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3045f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3046f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Compile a GLSL shader. Called via glCompileShader(). 3047f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 304816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 3049f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) 3050364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 30512462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 30522462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 30535e18b051c039564d1998818d08caf1bff3983630Ian Romanick 3054153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 3055a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke /* Check if the user called glCompileShader without first calling 3056a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke * glShaderSource. This should fail to compile, but not raise a GL_ERROR. 3057a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke */ 3058a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke if (source == NULL) { 3059a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke shader->CompileStatus = GL_FALSE; 3060a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke return; 3061a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke } 3062a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke 30637cfd42cefe1949af51ecced9891f415eca2c0e66Dave Airlie state->error = glcpp_preprocess(state, &source, &state->info_log, 30647dcfc44b72f00ba5a38cb02123c80113440f0de9Kenneth Graunke &ctx->Extensions, ctx->API); 3065153eca98064252be4daad9cc27746f37c245b627Ian Romanick 30661b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 30679bd7e9c6b29b212a97bd4ca6c62836160b2f7698Eric Anholt printf("GLSL source for %s shader %d:\n", 30689bd7e9c6b29b212a97bd4ca6c62836160b2f7698Eric Anholt _mesa_glsl_shader_target_name(state->target), shader->Name); 30691b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt printf("%s\n", shader->Source); 30701b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt } 30711b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt 3072153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 3073153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 3074153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 3075153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 3076153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 3077364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3078d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(shader->ir); 307916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 3080364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 308116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 3082364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 308316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 3084ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3085ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 30862f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt /* Do some optimization at compile time to reduce shader IR size 30872f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt * and reduce later work if the same shader is linked multiple times 30882f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt */ 30891d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick while (do_common_optimization(shader->ir, false, false, 32)) 30902f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt ; 3091ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 3092ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3093364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3094364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3095364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 3096364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3097364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 3098364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 309925f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 3100d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 3101d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 3102d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 3103c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 3104b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt if (ctx->Shader.Flags & GLSL_LOG) { 3105b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt _mesa_write_shader_to_file(shader); 3106b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt } 3107b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt 31080df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 31090df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->CompileStatus) { 31100df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL IR for shader %d:\n", shader->Name); 31110df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt _mesa_print_ir(shader->ir, NULL); 31120df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("\n\n"); 31130df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } else { 31140df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d failed to compile.\n", shader->Name); 31150df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 31160df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->InfoLog && shader->InfoLog[0] != 0) { 31170df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d info log:\n", shader->Name); 31180df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", shader->InfoLog); 31190df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3120455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt } 3121455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt 3122f609cf782ab5e90ddf045dc4b0da8cebf99be0d1Eric Anholt if (shader->UniformBlocks) 3123f609cf782ab5e90ddf045dc4b0da8cebf99be0d1Eric Anholt ralloc_free(shader->UniformBlocks); 3124f609cf782ab5e90ddf045dc4b0da8cebf99be0d1Eric Anholt shader->NumUniformBlocks = state->num_uniform_blocks; 3125f609cf782ab5e90ddf045dc4b0da8cebf99be0d1Eric Anholt shader->UniformBlocks = state->uniform_blocks; 3126f609cf782ab5e90ddf045dc4b0da8cebf99be0d1Eric Anholt ralloc_steal(shader, shader->UniformBlocks); 3127f609cf782ab5e90ddf045dc4b0da8cebf99be0d1Eric Anholt 3128116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 31294a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt reparent_ir(shader->ir, shader->ir); 3130116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 3131d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(state); 3132d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 3133364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3134f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3135f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3136f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a GLSL shader program. Called via glLinkProgram(). 3137f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 3138364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 3139f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 3140364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 3141364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 3142849e18153cd91d812f694b806a84008498860bc3Eric Anholt 3143364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 3144364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3145849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 3146364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3147364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 3148849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 31498aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(prog, "linking with uncompiled shader"); 3150849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 3151364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3152364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3153364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3154849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 31555d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt link_shaders(ctx, prog); 3156849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 3157364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3158364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 31590df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (!ctx->Driver.LinkShader(ctx, prog)) { 3160d19eecef54384c163af27a470496ed885a5a271bEric Anholt prog->LinkStatus = GL_FALSE; 3161af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3162af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3163af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt 3164af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 3165af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (!prog->LinkStatus) { 31660df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d failed to link\n", prog->Name); 31670df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 31680df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt 31690df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (prog->InfoLog && prog->InfoLog[0] != 0) { 31700df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d info log:\n", prog->Name); 31710df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", prog->InfoLog); 31720df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3173364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3174364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 3175364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3176364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 3177