ir_to_mesa.cpp revision ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6
184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/* 2bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. 3bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Copyright © 2010 Intel Corporation 584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * copy of this software and associated documentation files (the "Software"), 884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to deal in the Software without restriction, including without limitation 984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 1184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software is furnished to do so, subject to the following conditions: 1284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 1384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * The above copyright notice and this permission notice (including the next 1484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * paragraph) shall be included in all copies or substantial portions of the 1584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software. 1684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 1784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * DEALINGS IN THE SOFTWARE. 2484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 2584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/** 2784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * \file ir_to_mesa.cpp 2884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 29f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Translate GLSL IR to Mesa's gl_program representation. 3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 320161515c395c44233529c8d51f823b60050bc7baEric Anholt#include <stdio.h> 33261bbc011d11ab9e390cd5fe9f5151821eefaffaIan Romanick#include "main/compiler.h" 3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h" 3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h" 3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h" 3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h" 3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h" 39364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h" 40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h" 41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h" 42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h" 4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 44aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" { 450a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h" 46658e25987fbec3b826f500baa6d4d936b9552b13Eric Anholt#include "main/shaderapi.h" 47afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h" 48afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/uniforms.h" 49fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h" 50afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h" 51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h" 52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h" 53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h" 54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h" 55afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h" 56a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt#include "program/sampler.h" 57aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt} 5884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 59cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkeclass src_reg; 60cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkeclass dst_reg; 61cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 629c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtstatic int swizzle_for_size(int size); 639c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 64554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/** 65554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with 66554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields. 67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 68fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkeclass src_reg { 69fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkepublic: 70b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke src_reg(gl_register_file file, int index, const glsl_type *type) 719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 72b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke this->file = file; 739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->index = index; 749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) 759c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = swizzle_for_size(type->vector_elements); 769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt else 779c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = SWIZZLE_XYZW; 789c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->negate = 0; 799c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->reladdr = NULL; 809c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 819c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 82fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg() 839c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 849c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->file = PROGRAM_UNDEFINED; 8548c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->index = 0; 8648c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->swizzle = 0; 8748c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->negate = 0; 8848c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->reladdr = NULL; 899c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 909c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 91cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke explicit src_reg(dst_reg reg); 92cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 93caf974c5259f14b50257e8dd9b325a87378259afBrian Paul gl_register_file file; /**< PROGRAM_* from Mesa */ 94554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 95582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int negate; /**< NEGATE_XYZW mask from mesa */ 97f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 98fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg *reladdr; 99fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke}; 100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 101fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkeclass dst_reg { 102fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkepublic: 103b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke dst_reg(gl_register_file file, int writemask) 104cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke { 105cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->file = file; 106cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = 0; 107cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->writemask = writemask; 108cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->cond_mask = COND_TR; 109cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->reladdr = NULL; 110cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke } 111cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 112cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg() 113cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke { 114cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->file = PROGRAM_UNDEFINED; 115cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = 0; 116cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->writemask = 0; 117cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->cond_mask = COND_TR; 118cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->reladdr = NULL; 119cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke } 120cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 121cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke explicit dst_reg(src_reg reg); 122cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 123b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke gl_register_file file; /**< PROGRAM_* from Mesa */ 124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 125554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 126854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLuint cond_mask:4; 127f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 128fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg *reladdr; 129fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke}; 130554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 131cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkesrc_reg::src_reg(dst_reg reg) 132cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke{ 133b4dfb7473efd378c51b955a856eaef69312c1f9fKenneth Graunke this->file = reg.file; 134cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = reg.index; 135cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->swizzle = SWIZZLE_XYZW; 136cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->negate = 0; 137f7cd9a858c043e609fcdbf9ac9dfc1ef7ad002bfIan Romanick this->reladdr = reg.reladdr; 138cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke} 139cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 140cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunkedst_reg::dst_reg(src_reg reg) 141cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke{ 142cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->file = reg.file; 143cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->index = reg.index; 144cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->writemask = WRITEMASK_XYZW; 145cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->cond_mask = COND_TR; 146cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke this->reladdr = reg.reladdr; 147cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke} 148cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke 149554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node { 150554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 151d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke /* Callers of this ralloc-based new need not call delete. It's 152d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke * easier to just ralloc_free 'ctx' (or any of its ancestors). */ 1537406898441bfec937840d575500fb6d43192310dEric Anholt static void* operator new(size_t size, void *ctx) 1547406898441bfec937840d575500fb6d43192310dEric Anholt { 1557406898441bfec937840d575500fb6d43192310dEric Anholt void *node; 1567406898441bfec937840d575500fb6d43192310dEric Anholt 157d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke node = rzalloc_size(ctx, size); 1587406898441bfec937840d575500fb6d43192310dEric Anholt assert(node != NULL); 1597406898441bfec937840d575500fb6d43192310dEric Anholt 1607406898441bfec937840d575500fb6d43192310dEric Anholt return node; 1617406898441bfec937840d575500fb6d43192310dEric Anholt } 1627406898441bfec937840d575500fb6d43192310dEric Anholt 163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op; 164fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst; 165fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src[3]; 166554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** Pointer to the ir source this tree came from for debugging */ 167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_instruction *ir; 168854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLboolean cond_update; 169ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt bool saturate; 170d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler; /**< sampler index */ 171d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int tex_target; /**< One of TEXTURE_*_INDEX */ 172b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt GLboolean tex_shadow; 1737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ 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 2397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *get_function_signature(ir_function_signature *sig); 2407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 241fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg get_temp(const glsl_type *type); 242fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke void reladdr_to_temp(ir_instruction *ir, src_reg *reg, int *num_reladdr); 243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 244fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src_reg_for_float(float val); 245554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 246554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 247554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 248554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 249554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 250554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 251554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 252554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 253554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 254554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 255554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 256554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 257554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 258554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 259554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 260554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 261554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 262554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 263554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 264554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 265554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 266554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 267554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 26816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 269554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 270554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 271554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 272554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 273fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg result; 274554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 275b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 276b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 277554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 2797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 2807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 2817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 282554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 283554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 284554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 28501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op); 28601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 28701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 28801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0); 28901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 29001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 29101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1); 29201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 29301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op, 29401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 29501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg src0, src_reg src1, src_reg src2); 296554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 297ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick /** 298ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick * Emit the correct dot-product instruction for the type of arguments 299ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick */ 3007f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick ir_to_mesa_instruction * emit_dp(ir_instruction *ir, 3017f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick dst_reg dst, 3027f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick src_reg src0, 3037f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick src_reg src1, 3047f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick unsigned elements); 30501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 30601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke void emit_scalar(ir_instruction *ir, enum prog_opcode op, 30701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0); 30801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke 30901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke void emit_scalar(ir_instruction *ir, enum prog_opcode op, 31001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1); 311904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 312f2616e56de8a48360cae8f269727b58490555f4dIan Romanick void emit_scs(ir_instruction *ir, enum prog_opcode op, 313fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst, const src_reg &src); 314f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 3153f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt GLboolean try_emit_mad(ir_expression *ir, 3163f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 317ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick bool try_emit_mad_for_and_not(ir_expression *ir, 318ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick int mul_operand); 319ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt GLboolean try_emit_sat(ir_expression *ir); 3203f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 32111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick void emit_swz(ir_expression *ir); 32211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 323c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool process_move_condition(ir_rvalue *ir); 324c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 32534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt void copy_propagate(void); 32634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 327364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 328554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 329554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 330ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkesrc_reg undef_src = src_reg(PROGRAM_UNDEFINED, 0, NULL); 33184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 332ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkedst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP); 333c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 334ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunkedst_reg address_reg = dst_reg(PROGRAM_ADDRESS, WRITEMASK_X); 3350161515c395c44233529c8d51f823b60050bc7baEric Anholt 336f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulstatic int 337f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paulswizzle_for_size(int size) 3380161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 3390161515c395c44233529c8d51f823b60050bc7baEric Anholt int size_swizzles[4] = { 3400161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 3410161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 3420161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 3430161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 3440161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 3450161515c395c44233529c8d51f823b60050bc7baEric Anholt 3469fea9e5e2115bcb52435648d2ef753638733d7d9Ian Romanick assert((size >= 1) && (size <= 4)); 3470161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 3480161515c395c44233529c8d51f823b60050bc7baEric Anholt} 3490161515c395c44233529c8d51f823b60050bc7baEric Anholt 35084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 35101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 35201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 35301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg src0, src_reg src1, src_reg src2) 35484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 355364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 356f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 357f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 358f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 359f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 360f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 361f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 362f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 363f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 364f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 365f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 366f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 367f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 368f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 369f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 370f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 371f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 372ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_ARL, address_reg, *dst.reladdr); 373f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 374f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 375f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 37684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 37784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 378461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst = dst; 379461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[0] = src0; 380461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[1] = src1; 381461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[2] = src2; 382c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 38384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function = NULL; 3857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3860161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 38784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 38884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 38984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 39084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 39301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 39401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1) 39584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 396ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, dst, src0, src1, undef_src); 39784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 39884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 39984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 40001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op, 40101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0) 402bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 4035a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(dst.writemask != 0); 404ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, dst, src0, undef_src, undef_src); 405bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 406bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 407021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 40801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op) 409021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 410ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); 411021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 412021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 4137f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanickir_to_mesa_instruction * 41401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_dp(ir_instruction *ir, 41501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0, src_reg src1, 41601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke unsigned elements) 417ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick{ 418ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick static const gl_inst_opcode dot_opcodes[] = { 419ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick OPCODE_DP2, OPCODE_DP3, OPCODE_DP4 420ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick }; 421ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 4227f4c65256cc3f4d9f6a214424beabe688a5dd6a2Ian Romanick return emit(ir, dot_opcodes[elements - 2], dst, src0, src1); 423ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick} 424ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick 42512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 42612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 42712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 42812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 42912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 43212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 43312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 43401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op, 43501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, 43601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg orig_src0, src_reg orig_src1) 43712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 43812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 439315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 44012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 44412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 44512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 446582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 44712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 448fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src0 = orig_src0; 449fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src1 = orig_src1; 45012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 45112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 45212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 45312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 45612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 457f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 458f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 459f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 460f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 461904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 462904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 463904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 46412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 46512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 46612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 467904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 468904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 469904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 470904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 47112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 47201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, op, dst, src0, src1); 473461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = this_mask; 47412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 47512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 47612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 47712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 478904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 47901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunkeir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op, 48001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg dst, src_reg src0) 481904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 482ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke src_reg undef = undef_src; 483904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 484904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 485904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 48601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, op, dst, src0, undef); 487904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 488904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 489f2616e56de8a48360cae8f269727b58490555f4dIan Romanick/** 490f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Emit an OPCODE_SCS instruction 491f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 492f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * The \c SCS opcode functions a bit differently than the other Mesa (or 493f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * ARB_fragment_program) opcodes. Instead of splatting its result across all 494f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * four components of the destination, it writes one value to the \c x 495f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * component and another value to the \c y component. 496f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * 497f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param ir IR instruction being processed 498f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which 499f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * value is desired. 500f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param dst Destination register 501f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * \param src Source register 502f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 503f2616e56de8a48360cae8f269727b58490555f4dIan Romanickvoid 504f2616e56de8a48360cae8f269727b58490555f4dIan Romanickir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op, 505fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst, 506fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke const src_reg &src) 507f2616e56de8a48360cae8f269727b58490555f4dIan Romanick{ 508f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Vertex programs cannot use the SCS opcode. 509f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 510f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 51101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, op, dst, src); 512f2616e56de8a48360cae8f269727b58490555f4dIan Romanick return; 513f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 514f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 515f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned component = (op == OPCODE_SIN) ? 0 : 1; 516f2616e56de8a48360cae8f269727b58490555f4dIan Romanick const unsigned scs_mask = (1U << component); 517f2616e56de8a48360cae8f269727b58490555f4dIan Romanick int done_mask = ~dst.writemask; 518fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg tmp; 519f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 520f2616e56de8a48360cae8f269727b58490555f4dIan Romanick assert(op == OPCODE_SIN || op == OPCODE_COS); 521f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 522f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there are compnents in the destination that differ from the component 523f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * that will be written by the SCS instrution, we'll need a temporary. 524f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 525f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (scs_mask != unsigned(dst.writemask)) { 526f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp = get_temp(glsl_type::vec4_type); 527f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 528f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 529f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned i = 0; i < 4; i++) { 530f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned this_mask = (1U << i); 531fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src0 = src; 532f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 533f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if ((done_mask & this_mask) != 0) 534f2616e56de8a48360cae8f269727b58490555f4dIan Romanick continue; 535f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 536f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* The source swizzle specified which component of the source generates 537f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * sine / cosine for the current component in the destination. The SCS 538f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * instruction requires that this value be swizzle to the X component. 539f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * Replace the current swizzle with a swizzle that puts the source in 540f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the X component. 541f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 542f2616e56de8a48360cae8f269727b58490555f4dIan Romanick unsigned src0_swiz = GET_SWZ(src.swizzle, i); 543f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 544f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 545f2616e56de8a48360cae8f269727b58490555f4dIan Romanick src0_swiz, src0_swiz); 546f2616e56de8a48360cae8f269727b58490555f4dIan Romanick for (unsigned j = i + 1; j < 4; j++) { 547f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* If there is another enabled component in the destination that is 548f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * derived from the same inputs, generate its value on this pass as 549f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * well. 550f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 551f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (!(done_mask & (1 << j)) && 552f2616e56de8a48360cae8f269727b58490555f4dIan Romanick GET_SWZ(src0.swizzle, j) == src0_swiz) { 553f2616e56de8a48360cae8f269727b58490555f4dIan Romanick this_mask |= (1 << j); 554f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 555f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 556f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 557f2616e56de8a48360cae8f269727b58490555f4dIan Romanick if (this_mask != scs_mask) { 558f2616e56de8a48360cae8f269727b58490555f4dIan Romanick ir_to_mesa_instruction *inst; 559cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg tmp_dst = dst_reg(tmp); 560f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 561f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction. 562f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 56301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, OPCODE_SCS, tmp_dst, src0); 564461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = scs_mask; 565f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 566f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Move the result of the SCS instruction to the desired location in 567f2616e56de8a48360cae8f269727b58490555f4dIan Romanick * the destination. 568f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 569f2616e56de8a48360cae8f269727b58490555f4dIan Romanick tmp.swizzle = MAKE_SWIZZLE4(component, component, 570f2616e56de8a48360cae8f269727b58490555f4dIan Romanick component, component); 57101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke inst = emit(ir, OPCODE_SCS, dst, tmp); 572461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = this_mask; 573f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } else { 574f2616e56de8a48360cae8f269727b58490555f4dIan Romanick /* Emit the SCS instruction to write directly to the destination. 575f2616e56de8a48360cae8f269727b58490555f4dIan Romanick */ 57601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir_to_mesa_instruction *inst = emit(ir, OPCODE_SCS, dst, src0); 577461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask = scs_mask; 578f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 579f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 580f2616e56de8a48360cae8f269727b58490555f4dIan Romanick done_mask |= this_mask; 581f2616e56de8a48360cae8f269727b58490555f4dIan Romanick } 582f2616e56de8a48360cae8f269727b58490555f4dIan Romanick} 583f2616e56de8a48360cae8f269727b58490555f4dIan Romanick 584fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkestruct src_reg 5850161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 586b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 587fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src(PROGRAM_CONSTANT, -1, NULL); 5881d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 589461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = _mesa_add_unnamed_constant(this->prog->Parameters, 5906d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (const gl_constant_value *)&val, 1, &src.swizzle); 5911d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 592461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke return src; 5931d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 5941d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 5952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 5962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 5972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 5982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 5992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 6002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 6012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 6022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 6032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 6042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 6052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 606a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 6079968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 608a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 609a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 610a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 611a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 612a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 613a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 614a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 615a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 6162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 6175c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick assert(type->length > 0); 6182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 6192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 6202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 6212c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 6222c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 6232c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6242c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 6258d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt case GLSL_TYPE_SAMPLER: 6260924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Samplers take up one slot in UNIFORMS[], but they're baked in 6270924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * at link time. 6288d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt */ 6290924ba0c3496160a134d37cec800f902ae805b9cEric Anholt return 1; 6302c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 6312c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 63219acfa42ed47edb63f5ec3de8051a3102e62e96bJosé Fonseca return 0; 6332c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 6342c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 6352c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 636d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 637d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 638d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 639d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 640d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 641d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 642fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkesrc_reg 643d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 644d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 645fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 646d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 647461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.file = PROGRAM_TEMPORARY; 648461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = next_temp; 649461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.reladdr = NULL; 650d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 651d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 65220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (type->is_array() || type->is_record()) { 653461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = SWIZZLE_NOOP; 65420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } else { 6554c7e215c7bb09f827df630cbfc80e87869351f18Eric Anholt src.swizzle = swizzle_for_size(type->vector_elements); 65620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 657461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.negate = 0; 658d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 659461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke return src; 660d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 661d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 662b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 663a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 66484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 665a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 666b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 66784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 668b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 669b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6710161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 672a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 67384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 67484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 675a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 676a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 67784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 67884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 67984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 68084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 6814a962170d7cf4243d6ae156fca20a6167388925dEric Anholt if (strcmp(ir->name, "gl_FragCoord") == 0) { 6824a962170d7cf4243d6ae156fca20a6167388925dEric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 6834a962170d7cf4243d6ae156fca20a6167388925dEric Anholt 6844a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->OriginUpperLeft = ir->origin_upper_left; 6854a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->PixelCenterInteger = ir->pixel_center_integer; 686a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace 687a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace } else if (strcmp(ir->name, "gl_FragDepth") == 0) { 688a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 689a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace switch (ir->depth_layout) { 690a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_none: 691a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE; 692a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 693a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_any: 694a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY; 695a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 696a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_greater: 697a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER; 698a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 699a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_less: 700a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS; 701a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 702a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace case ir_depth_layout_unchanged: 703a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED; 704a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 705a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace default: 706a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace assert(0); 707a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace break; 708a1b83464ffb1125b77e6f5664e0071f95167055dChad Versace } 7094a962170d7cf4243d6ae156fca20a6167388925dEric Anholt } 7106c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7116c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 7126c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt unsigned int i; 71389d81ab16c05818b290ed735c1343d3abde449bfIan Romanick const ir_state_slot *const slots = ir->state_slots; 71489d81ab16c05818b290ed735c1343d3abde449bfIan Romanick assert(ir->state_slots != NULL); 7156c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7166c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* Check if this statevar's setup in the STATE file exactly 7176c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * matches how we'll want to reference it as a 7186c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * struct/array/whatever. If not, then we need to move it into 7196c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * temporary storage and hope that it'll get copy-propagated 7206c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt * out. 7216c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt */ 72289d81ab16c05818b290ed735c1343d3abde449bfIan Romanick for (i = 0; i < ir->num_state_slots; i++) { 72389d81ab16c05818b290ed735c1343d3abde449bfIan Romanick if (slots[i].swizzle != SWIZZLE_XYZW) { 7246c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt break; 7256c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7266c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7276c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7286c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt struct variable_storage *storage; 729fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg dst; 73089d81ab16c05818b290ed735c1343d3abde449bfIan Romanick if (i == ir->num_state_slots) { 7316c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt /* We'll set the index later. */ 7326c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 7336c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 7346c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 735ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke dst = undef_dst; 7366c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 73789d81ab16c05818b290ed735c1343d3abde449bfIan Romanick /* The variable_storage constructor allocates slots based on the size 73889d81ab16c05818b290ed735c1343d3abde449bfIan Romanick * of the type. However, this had better match the number of state 73989d81ab16c05818b290ed735c1343d3abde449bfIan Romanick * elements that we're going to copy into the new temporary. 74089d81ab16c05818b290ed735c1343d3abde449bfIan Romanick */ 741847f991a87b9549eb89a521edb7cd149005006bbBrian Paul assert((int) ir->num_state_slots == type_size(ir->type)); 74289d81ab16c05818b290ed735c1343d3abde449bfIan Romanick 7436c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 7446c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp); 7456c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->variables.push_tail(storage); 7466c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt this->next_temp += type_size(ir->type); 7476c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 748cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst = dst_reg(src_reg(PROGRAM_TEMPORARY, storage->index, NULL)); 7496c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7506c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 7516c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt 752a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick for (unsigned int i = 0; i < ir->num_state_slots; i++) { 753a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick int index = _mesa_add_state_reference(this->prog->Parameters, 754a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick (gl_state_index *)slots[i].tokens); 755a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick 756a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick if (storage->file == PROGRAM_STATE_VAR) { 757a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick if (storage->index == -1) { 758a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick storage->index = index; 7596c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } else { 760a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick assert(index == storage->index + (int)i); 7616c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 762a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick } else { 763fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src(PROGRAM_STATE_VAR, index, NULL); 764a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick src.swizzle = slots[i].swizzle; 76501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, dst, src); 766a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick /* even a float takes up a whole vec4 reg in a struct/array. */ 767a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick dst.index++; 7686c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7696c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 770a99e80d795f7c6aec0e73369a31d1728577b9727Ian Romanick 7716c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt if (storage->file == PROGRAM_TEMPORARY && 772847f991a87b9549eb89a521edb7cd149005006bbBrian Paul dst.index != storage->index + (int) ir->num_state_slots) { 7738aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(this->shader_program, 7748aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "failed to load builtin uniform `%s' " 7758aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "(%d/%d regs loaded)\n", 7768aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick ir->name, dst.index - storage->index, 7778aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick type_size(ir->type)); 7786c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 7796c0ba32fd1466e8c1700acab3003dc1fe1deb337Eric Anholt } 78084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 78184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 78284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 78384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 78484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 7850f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_dereference_variable *counter = NULL; 7860f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7870f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->counter != NULL) 788dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter = new(mem_ctx) ir_dereference_variable(ir->counter); 7890f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7900f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->from != NULL) { 7910f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick assert(ir->counter != NULL); 7920f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 793dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_assignment *a = 794dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_assignment(counter, ir->from, NULL); 7950f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 7960f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 7970f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 79884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 79901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_BGNLOOP); 8000f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8010f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->to) { 8020f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 803dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type, 804dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter, ir->to); 805dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_if *if_stmt = new(mem_ctx) ir_if(e); 8060f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 807dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_loop_jump *brk = 808dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); 8090f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8100f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->then_instructions.push_tail(brk); 8110f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8120f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if_stmt->accept(this); 8130f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 8140f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 81564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 8160f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8170f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick if (ir->increment) { 8180f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick ir_expression *e = 819dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_expression(ir_binop_add, counter->type, 820dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick counter, ir->increment); 8210f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 822dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick ir_assignment *a = 823dbda466fc05a6262ba857a7887e16347cf3d3e96Ian Romanick new(mem_ctx) ir_assignment(counter, e, NULL); 8240f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 8250f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick a->accept(this); 8260f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick } 8270f4f8c73644a9cc436500d605413207c44cfb4eeIan Romanick 82801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_ENDLOOP); 82984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 83084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 83184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 83284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 83384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 83464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 83564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 83601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_BRK); 83764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 83864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 83901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(NULL, OPCODE_CONT); 84064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 84164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 84284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 84384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 84584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 84684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 84784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 84884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 84984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 85084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 85184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 85284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 85384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 85484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 85584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 85684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 85784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 85884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 86084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 86184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 86384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 86784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 86884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 86984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 87084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 87184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 87284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 87384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 8743f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean 8753f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 8763f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 8773f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 878fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg a, b, c; 8793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8803f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 8813f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 8823f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 8833f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8843f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 8853f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 8863f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 8873f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 8883f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 8893f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 8903f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8913f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 89201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, c); 8933f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 8943f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 8953f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 8963f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 897ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick/** 898ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * Emit OPCODE_MAD(a, -b, a) instead of AND(a, NOT(b)) 899ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 900ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * The logic values are 1.0 for true and 0.0 for false. Logical-and is 901ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * implemented using multiplication, and logical-or is implemented using 902ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * addition. Logical-not can be implemented as (true - x), or (1.0 - x). 903ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * As result, the logical expression (a & !b) can be rewritten as: 904ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 905ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a * !b 906ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a * (1 - b) 907ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - (a * 1) - (a * b) 908ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a + -(a * b) 909ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * - a + (a * -b) 910ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * 911ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * This final expression can be implemented as a single MAD(a, -b, a) 912ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick * instruction. 913ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick */ 914ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanickbool 915ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanickir_to_mesa_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand) 916ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick{ 917ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick const int other_operand = 1 - try_operand; 918ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick src_reg a, b; 919ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 920ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick ir_expression *expr = ir->operands[try_operand]->as_expression(); 921ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (!expr || expr->operation != ir_unop_logic_not) 922ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return false; 923ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 924ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick ir->operands[other_operand]->accept(this); 925ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick a = this->result; 926ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick expr->operands[0]->accept(this); 927ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick b = this->result; 928ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 929ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick b.negate = ~b.negate; 930ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 931ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick this->result = get_temp(ir->type); 932ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, a); 933ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 934ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return true; 935ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick} 936ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 937ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric AnholtGLboolean 938ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholtir_to_mesa_visitor::try_emit_sat(ir_expression *ir) 939ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt{ 940ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt /* Saturates were only introduced to vertex programs in 941ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt * NV_vertex_program3, so don't give them to drivers in the VP. 942ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt */ 943ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 944ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 945ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 946ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 947ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (!sat_src) 948ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return false; 949ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 950ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt sat_src->accept(this); 951fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src = this->result; 952ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 95362722d90af9d43d889af33b080a682f2004e049cEric Anholt /* If we generated an expression instruction into a temporary in 95462722d90af9d43d889af33b080a682f2004e049cEric Anholt * processing the saturate's operand, apply the saturate to that 95562722d90af9d43d889af33b080a682f2004e049cEric Anholt * instruction. Otherwise, generate a MOV to do the saturate. 95662722d90af9d43d889af33b080a682f2004e049cEric Anholt * 95762722d90af9d43d889af33b080a682f2004e049cEric Anholt * Note that we have to be careful to only do this optimization if 95862722d90af9d43d889af33b080a682f2004e049cEric Anholt * the instruction in question was what generated src->result. For 95962722d90af9d43d889af33b080a682f2004e049cEric Anholt * example, ir_dereference_array might generate a MUL instruction 96062722d90af9d43d889af33b080a682f2004e049cEric Anholt * to create the reladdr, and return us a src reg using that 96162722d90af9d43d889af33b080a682f2004e049cEric Anholt * reladdr. That MUL result is not the value we're trying to 96262722d90af9d43d889af33b080a682f2004e049cEric Anholt * saturate. 96362722d90af9d43d889af33b080a682f2004e049cEric Anholt */ 96462722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_expression *sat_src_expr = sat_src->as_expression(); 96562722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_to_mesa_instruction *new_inst; 96662722d90af9d43d889af33b080a682f2004e049cEric Anholt new_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 96762722d90af9d43d889af33b080a682f2004e049cEric Anholt if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul || 96862722d90af9d43d889af33b080a682f2004e049cEric Anholt sat_src_expr->operation == ir_binop_add || 96962722d90af9d43d889af33b080a682f2004e049cEric Anholt sat_src_expr->operation == ir_binop_dot)) { 97062722d90af9d43d889af33b080a682f2004e049cEric Anholt new_inst->saturate = true; 97162722d90af9d43d889af33b080a682f2004e049cEric Anholt } else { 97262722d90af9d43d889af33b080a682f2004e049cEric Anholt this->result = get_temp(ir->type); 97362722d90af9d43d889af33b080a682f2004e049cEric Anholt ir_to_mesa_instruction *inst; 97462722d90af9d43d889af33b080a682f2004e049cEric Anholt inst = emit(ir, OPCODE_MOV, dst_reg(this->result), src); 97562722d90af9d43d889af33b080a682f2004e049cEric Anholt inst->saturate = true; 97662722d90af9d43d889af33b080a682f2004e049cEric Anholt } 977ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 978ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return true; 979ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt} 980ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt 98184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 982f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 983fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg *reg, int *num_reladdr) 984f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 985f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 986f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 987f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 988ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_ARL, address_reg, *reg->reladdr); 989f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 990f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 991fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 992f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 99301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, dst_reg(temp), *reg); 994f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 995f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 996f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 997f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 998f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 999f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 1000f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 100111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickir_to_mesa_visitor::emit_swz(ir_expression *ir) 100211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick{ 100311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Assume that the vector operator is in a form compatible with OPCODE_SWZ. 100411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This means that each of the operands is either an immediate value of -1, 100511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * 0, or 1, or is a component from one source register (possibly with 100611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * negation). 100711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 100811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick uint8_t components[4] = { 0 }; 100911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick bool negate[4] = { false }; 101011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_variable *var = NULL; 101111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick for (unsigned i = 0; i < ir->type->vector_elements; i++) { 101311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_rvalue *op = ir->operands[i]; 101411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 101611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 101711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick while (op != NULL) { 101811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick switch (op->ir_type) { 101911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_constant: { 102011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(op->type->is_scalar()); 102211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 102311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick const ir_constant *const c = op->as_constant(); 102411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (c->is_one()) { 102511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 102611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_zero()) { 102711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ZERO; 102811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else if (c->is_negative_one()) { 102911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_ONE; 103011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 103111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } else { 103211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"SWZ constant must be 0.0 or 1.0."); 103311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 103411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 103611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 103711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 103811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 103911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_dereference_variable: { 104011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 104111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick (ir_dereference_variable *) op; 104211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 104311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert((var == NULL) || (deref->var == var)); 104411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = SWIZZLE_X; 104511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick var = deref->var; 104611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = NULL; 104711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 104811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 104911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_expression: { 105111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_expression *const expr = (ir_expression *) op; 105211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(expr->operation == ir_unop_neg); 105411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick negate[i] = true; 105511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 105611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = expr->operands[0]; 105711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 105811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 105911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_type_swizzle: { 106111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_swizzle *const swiz = (ir_swizzle *) op; 106211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[i] = swiz->mask.x; 106411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick op = swiz->val; 106511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 106611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 106711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 106811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick default: 106911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 107011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 107111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 107211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 107311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 107411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(var != NULL); 107611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 107711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_dereference_variable *const deref = 107811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick new(mem_ctx) ir_dereference_variable(var); 107911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 108011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result.file = PROGRAM_UNDEFINED; 108111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(this); 108211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (this->result.file == PROGRAM_UNDEFINED) { 108311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick ir_print_visitor v; 108411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick printf("Failed to get tree for expression operand:\n"); 108511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick deref->accept(&v); 108611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick exit(1); 108711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 108811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 1089fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 109011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 109111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src = this->result; 109211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.swizzle = MAKE_SWIZZLE4(components[0], 109311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[1], 109411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[2], 109511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick components[3]); 109611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick src.negate = ((unsigned(negate[0]) << 0) 109711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[1]) << 1) 109811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[2]) << 2) 109911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick | (unsigned(negate[3]) << 3)); 110011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 110111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Storage for our result. Ideally for an assignment we'd be using the 110211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * actual storage for the result here, instead. 110311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 1104fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke const src_reg result_src = get_temp(ir->type); 1105cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg result_dst = dst_reg(result_src); 110611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 110711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* Limit writes to the channels that will be used by result_src later. 110811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * This does limit this temp's use as a temporary for multi-instruction 110911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick * sequences. 111011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 111111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick result_dst.writemask = (1 << ir->type->vector_elements) - 1; 111211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 111301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SWZ, result_dst, src); 111411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->result = result_src; 111511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick} 111611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 111711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanickvoid 111884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 111984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 112084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 1121fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg op[Elements(ir->operands)]; 1122fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg result_src; 1123fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg result_dst; 112484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 11253f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 11263f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 11273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 11283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 11293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 11313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 11323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 1133ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 1134ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b)) 1135ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick */ 1136ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (ir->operation == ir_binop_logic_and) { 1137ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (try_emit_mad_for_and_not(ir, 1)) 1138ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return; 1139ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick if (try_emit_mad_for_and_not(ir, 0)) 1140ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick return; 1141ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick } 1142ff2cfb8989cd79218dfe2cd8c3de20f1ca7418e6Ian Romanick 1143ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (try_emit_sat(ir)) 1144ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt return; 11453f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 114611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick if (ir->operation == ir_quadop_vector) { 114711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick this->emit_swz(ir); 114811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick return; 114911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick } 115011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 115184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 11520161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 115384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 11540161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 115584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 115684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 115784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 115884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 115984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 116084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 11618364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 11624ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 11634ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 11644ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 11654ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 116684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 116784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1168eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt int vector_elements = ir->operands[0]->type->vector_elements; 1169eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt if (ir->operands[1]) { 1170eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt vector_elements = MAX2(vector_elements, 1171eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt ir->operands[1]->type->vector_elements); 1172eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt } 1173eaa6bf59db68f97fa32c3395eb4aa6e589f34b26Eric Anholt 11740161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 11750161515c395c44233529c8d51f823b60050bc7baEric Anholt 11760161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 11770161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 11780161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 11798364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 11800161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 1181cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke result_dst = dst_reg(result_src); 11829cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 11839cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 11849cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 11859cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 11869cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 118784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 118884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 11891d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 11906ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick /* Previously 'SEQ dst, src, 0.0' was used for this. However, many 11916ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * older GPUs implement SEQ using multiple instructions (i915 uses two 11926ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * SGE instructions and a MUL instruction). Since our logic values are 11936ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick * 0.0 and 1.0, 1-x also implements !x. 11946ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick */ 11956ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick op[0].negate = ~op[0].negate; 11966ad08989d7c10892919ce1cb9c88c4cf8b73e1dcIan Romanick emit(ir, OPCODE_ADD, result_dst, op[0], src_reg_for_float(1.0)); 11971d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1198c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 11990161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 12000161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 1201c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 1202524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 120301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_ABS, result_dst, op[0]); 1204524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 12053acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 120601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SSG, result_dst, op[0]); 12073acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 12088761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 120901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RCP, result_dst, op[0]); 12108761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 1211524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 12128c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 121301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_EX2, result_dst, op[0]); 12148c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 1215bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt case ir_unop_exp: 12168c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 1217bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 12188c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 12198c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 122001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_LG2, result_dst, op[0]); 12218c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 12223c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 122301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_SIN, result_dst, op[0]); 12243c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 12253c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 122601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_COS, result_dst, op[0]); 12273c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 1228f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_sin_reduced: 1229f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_SIN, result_dst, op[0]); 1230f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1231f2616e56de8a48360cae8f269727b58490555f4dIan Romanick case ir_unop_cos_reduced: 1232f2616e56de8a48360cae8f269727b58490555f4dIan Romanick emit_scs(ir, OPCODE_COS, result_dst, op[0]); 1233f2616e56de8a48360cae8f269727b58490555f4dIan Romanick break; 1234ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 1235ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 123601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_DDX, result_dst, op[0]); 1237ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1238ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 123901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_DDY, result_dst, op[0]); 1240ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 1241ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 12423a5ce85cfa4914711e56c8cf831699242618928eIan Romanick case ir_unop_noise: { 12433a5ce85cfa4914711e56c8cf831699242618928eIan Romanick const enum prog_opcode opcode = 12443a5ce85cfa4914711e56c8cf831699242618928eIan Romanick prog_opcode(OPCODE_NOISE1 12453a5ce85cfa4914711e56c8cf831699242618928eIan Romanick + (ir->operands[0]->type->vector_elements) - 1); 12463a5ce85cfa4914711e56c8cf831699242618928eIan Romanick assert((opcode >= OPCODE_NOISE1) && (opcode <= OPCODE_NOISE4)); 12473a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 124801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, opcode, result_dst, op[0]); 12493a5ce85cfa4914711e56c8cf831699242618928eIan Romanick break; 12503a5ce85cfa4914711e56c8cf831699242618928eIan Romanick } 12513a5ce85cfa4914711e56c8cf831699242618928eIan Romanick 125284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 125301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 125484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 125584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 125601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SUB, result_dst, op[0], op[1]); 125784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 12589b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 125984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 126001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 126184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 126284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 12639a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1264411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 1265411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 1266411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 126738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 126838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 126901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SLT, result_dst, op[0], op[1]); 127038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 127201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SGT, result_dst, op[0], op[1]); 127338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 127501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SLE, result_dst, op[0], op[1]); 127638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 127738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 127801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SGE, result_dst, op[0], op[1]); 127938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 128038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 128101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 12824dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12834dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_nequal: 128401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 12854dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri break; 12864dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_all_equal: 12876992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "==" operator producing a scalar boolean. */ 12886992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 12896992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 1290fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 129101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]); 1292ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick 1293ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick /* After the dot-product, the value will be an integer on the 1294ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * range [0,4]. Zero becomes 1.0, and positive values become zero. 1295ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick */ 129601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_dp(ir, result_dst, temp, temp, vector_elements); 1297ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick 1298ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick /* Negating the result of the dot-product gives values on the range 1299ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * [-4, 0]. Zero becomes 1.0, and negative values become zero. This 1300ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick * achieved using SGE. 1301ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick */ 1302ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick src_reg sge_src = result_src; 1303ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick sge_src.negate = ~sge_src.negate; 1304ba01df11c4d09c65514a8522cb319e29034ab5a8Ian Romanick emit(ir, OPCODE_SGE, result_dst, sge_src, src_reg_for_float(0.0)); 13056992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 130601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 13076992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 130838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 13094dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_any_nequal: 13106992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "!=" operator producing a scalar boolean. */ 13116992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 13126992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 1313fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::vec4_type); 131401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]); 1315e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick 1316e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* After the dot-product, the value will be an integer on the 1317e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * range [0,4]. Zero stays zero, and positive values become 1.0. 1318e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1319e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick ir_to_mesa_instruction *const dp = 1320e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick emit_dp(ir, result_dst, temp, temp, vector_elements); 1321e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 1322e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* The clamping to [0,1] can be done for free in the fragment 1323e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * shader with a saturate. 1324e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1325e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick dp->saturate = true; 1326e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick } else { 1327e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick /* Negating the result of the dot-product gives values on the range 1328e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * [-4, 0]. Zero stays zero, and negative values become 1.0. This 1329e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick * achieved using SLT. 1330e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick */ 1331e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick src_reg slt_src = result_src; 1332e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick slt_src.negate = ~slt_src.negate; 1333e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 1334e7bf096e8b04931996c8c56548ce0b2c0af3a0dcIan Romanick } 13356992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 133601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 13376992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 13386992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt break; 13395e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 134092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick case ir_unop_any: { 1341ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 134292ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick 134392ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* After the dot-product, the value will be an integer on the 134492ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * range [0,4]. Zero stays zero, and positive values become 1.0. 134592ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 134692ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick ir_to_mesa_instruction *const dp = 134792ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick emit_dp(ir, result_dst, op[0], op[0], 134892ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick ir->operands[0]->type->vector_elements); 134992ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 135092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* The clamping to [0,1] can be done for free in the fragment 135192ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * shader with a saturate. 135292ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 135392ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick dp->saturate = true; 135492ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } else { 135592ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick /* Negating the result of the dot-product gives values on the range 135692ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * [-4, 0]. Zero stays zero, and negative values become 1.0. This 135792ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick * is achieved using SLT. 135892ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick */ 135992ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick src_reg slt_src = result_src; 136092ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick slt_src.negate = ~slt_src.negate; 136192ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 136292ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } 13635e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 136492ca560d68e8a6b532998707afcf4f60c0ce2806Ian Romanick } 13655e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 13666992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt case ir_binop_logic_xor: 136701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, op[0], op[1]); 136838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 136938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 137041f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick case ir_binop_logic_or: { 137141f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* After the addition, the value will be an integer on the 137241f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * range [0,2]. Zero stays zero, and positive values become 1.0. 137341f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 137441f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick ir_to_mesa_instruction *add = 137541f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick emit(ir, OPCODE_ADD, result_dst, op[0], op[1]); 137641f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 137741f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* The clamping to [0,1] can be done for free in the fragment 137841f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * shader with a saturate. 137941f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 138041f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick add->saturate = true; 138141f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } else { 138241f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick /* Negating the result of the addition gives values on the range 138341f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * [-2, 0]. Zero stays zero, and negative values become 1.0. This 138441f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick * is achieved using SLT. 138541f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick */ 138641f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick src_reg slt_src = result_src; 138741f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick slt_src.negate = ~slt_src.negate; 138841f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0)); 138941f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } 13904380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 139141f8ffe5e07c4f389eb13d17ecf0ff776890e9bcIan Romanick } 13924380099c98119611ceee684669d00be26195c7d7Eric Anholt 13934380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 13944380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 139501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); 13964380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 13974380099c98119611ceee684669d00be26195c7d7Eric Anholt 139884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 1399ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type->is_vector()); 1400ad8cb131d8f73dee75e7be39dbc004783cd7f350Ian Romanick assert(ir->operands[0]->type == ir->operands[1]->type); 140101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_dp(ir, result_dst, op[0], op[1], 140201e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke ir->operands[0]->type->vector_elements); 140384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 14049be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 140584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 14064f189b3bf57a6500953dac49105f160af5fa6468Marek Olšák /* sqrt(x) = x * rsq(x). */ 140701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); 140801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, result_dst, result_src, op[0]); 1409c9039fdb167865547dc9b3828d69b99209344999Brian Paul /* For incoming channels <= 0, set the result to 0. */ 1410c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0].negate = ~op[0].negate; 141101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, result_dst, 1412c9039fdb167865547dc9b3828d69b99209344999Brian Paul op[0], result_src, src_reg_for_float(0.0)); 141384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 1414878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 141501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); 1416878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 141750ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 1418006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_u2f: 1419d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 1420d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 1421006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_i2u: 1422006d5a1aa4f9e07ceefdbb68324e9806f737a71cKenneth Graunke case ir_unop_u2i: 1423423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 14240161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 142550ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 1426423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 142701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_TRUNC, result_dst, op[0]); 1428423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 14291d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 1430411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 143101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_SNE, result_dst, 143266afcb560771b6ba6ad668156e9f442e86b9a7a2Eric Anholt op[0], src_reg_for_float(0.0)); 14331d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 1434c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 143501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_TRUNC, result_dst, op[0]); 1436c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1437c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 14380161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 143901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FLR, result_dst, op[0]); 14400161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 1441c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1442c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 144301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FLR, result_dst, op[0]); 1444c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 1445d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 144601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_FRC, result_dst, op[0]); 1447d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 1448d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 1449c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 145001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MIN, result_dst, op[0], op[1]); 1451c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1452c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 145301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MAX, result_dst, op[0], op[1]); 1454c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 1455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 145601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit_scalar(ir, OPCODE_POW, result_dst, op[0], op[1]); 1457904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 1458e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 1459e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_bit_not: 1460e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 1461e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 1462e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 1463e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 1464e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 1465d85d25dd1f4fd281bd210ba6ba5135ba1e3b535fKenneth Graunke case ir_unop_round_even: 1466e64a4aaacbc682f24180dff3627b84861844476dEric Anholt assert(!"GLSL 1.30 features unsupported"); 1467e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 146811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 146911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick case ir_quadop_vector: 147011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick /* This operation should have already been handled. 147111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick */ 147211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick assert(!"Should not get here."); 147311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick break; 147484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 1475b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 14760161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 147784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 147884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 147984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 148084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 148184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 148284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1483fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 148484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 148584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 148684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1487b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 1488b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 1489b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 1490b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 149184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 149284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 1493461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 1494461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke assert(src.file != PROGRAM_UNDEFINED); 149584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 149684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 149784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 149884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 149984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 1500461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x); 150184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 150284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 1503461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y); 150484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 150584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 1506461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z); 150784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 150884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 1509461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w); 151084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 151184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 151284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 151384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 151484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 151584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 1516698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 151784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 151884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 151984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1520461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 152184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1522461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke this->result = src; 152384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 152484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 152584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 152684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 152784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1528b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 1529304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul ir_variable *var = ir->var; 153084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15318364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1532304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul switch (var->mode) { 15338364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 1534304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1535304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul var->location); 1536b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 15378364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 15388364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 15398364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1540a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1541a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * including deprecated builtins (like gl_Color), 1542a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * user-assigned generic attributes (glBindVertexLocation), 1543a166720f2d93b090ad1c383c9bd90d0a9e27760dEric Anholt * and user-defined varyings. 1544a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1545a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1546f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1547304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul assert(var->location != -1); 15482b7be12d5467096362073260911a380c64c772d0Brian Paul entry = new(mem_ctx) variable_storage(var, 15492b7be12d5467096362073260911a380c64c772d0Brian Paul PROGRAM_INPUT, 15502b7be12d5467096362073260911a380c64c772d0Brian Paul var->location); 15512b7be12d5467096362073260911a380c64c772d0Brian Paul if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && 15522b7be12d5467096362073260911a380c64c772d0Brian Paul var->location >= VERT_ATTRIB_GENERIC0) { 15537a4345fd83605695dc641af503f6e87b808b48d7Brian Paul _mesa_add_attribute(this->prog->Attributes, 15542b7be12d5467096362073260911a380c64c772d0Brian Paul var->name, 15552b7be12d5467096362073260911a380c64c772d0Brian Paul _mesa_sizeof_glsl_type(var->type->gl_type), 15562b7be12d5467096362073260911a380c64c772d0Brian Paul var->type->gl_type, 15572b7be12d5467096362073260911a380c64c772d0Brian Paul var->location - VERT_ATTRIB_GENERIC0); 155886471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul } 155986471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul break; 156086471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul case ir_var_out: 156186471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul assert(var->location != -1); 156286471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul entry = new(mem_ctx) variable_storage(var, 156386471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul PROGRAM_OUTPUT, 156486471246f0f3c4c122f605fdd56dd0f5864fc307Brian Paul var->location); 15658364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 15667baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul case ir_var_system_value: 15677baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul entry = new(mem_ctx) variable_storage(var, 15687baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul PROGRAM_SYSTEM_VALUE, 15697baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul var->location); 15707baa498ae46668aebf165b9f2b1ddf0f5fe87c07Brian Paul break; 15718364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 15727e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1573304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1574b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1575b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1576224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 1577304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul next_temp += type_size(var->type); 15788364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 157984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 15808364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 15818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 1582304b239869fe5cd57dc87e6fd95c4906d9653b97Brian Paul printf("Failed to make storage for %s\n", var->name); 15838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1584224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 158584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 158684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1587fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke this->result = src_reg(entry->file, entry->index, var->type); 158884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 158984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 159084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 159184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 159284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1593ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 1594fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 15958258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1596ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1597ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 15984e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 1599ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 1600461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 16014e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 16024d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 1603461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index += index->value.i[0] * element_size; 16044e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 16054d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 16064d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 16074d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 16084d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 16094d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 16108258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 1611fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg index_reg; 16128258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 16134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 16144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 16154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 16164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1617f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 161801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, dst_reg(index_reg), 161901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke this->result, src_reg_for_float(element_size)); 1620bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 16214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 1622d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick /* If there was already a relative address register involved, add the 1623d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick * new and the old together to get the new offset. 1624d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick */ 1625d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick if (src.reladdr != NULL) { 1626d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick src_reg accum_reg = get_temp(glsl_type::float_type); 1627d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1628d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick emit(ir, OPCODE_ADD, dst_reg(accum_reg), 1629d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick index_reg, *src.reladdr); 1630d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1631d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick index_reg = accum_reg; 1632d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick } 1633d6e1a8f71437d4a65e65f93271b2892dd62b0d23Ian Romanick 1634fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src.reladdr = ralloc(mem_ctx, src_reg); 1635461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke memcpy(src.reladdr, &index_reg, sizeof(index_reg)); 16364e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 163784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 163884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 163985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 1640461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = swizzle_for_size(ir->type->vector_elements); 164185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 1642461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.swizzle = SWIZZLE_NOOP; 164384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1644461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke this->result = src; 164584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 164684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 16472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 16482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 16492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 16502c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 16510161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 16522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 16532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16540161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 16552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 16570161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 16582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 16592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 16602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 16612d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16622d577ee730c30caacf711babde6542766aa0b655Ian Romanick /* If the type is smaller than a vec4, replicate the last channel out. */ 16632d577ee730c30caacf711babde6542766aa0b655Ian Romanick if (ir->type->is_scalar() || ir->type->is_vector()) 16642d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 16652d577ee730c30caacf711babde6542766aa0b655Ian Romanick else 16662d577ee730c30caacf711babde6542766aa0b655Ian Romanick this->result.swizzle = SWIZZLE_NOOP; 16672d577ee730c30caacf711babde6542766aa0b655Ian Romanick 16680161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 16692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 16702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 16722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 16732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 16742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 16752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 1676fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkestatic dst_reg 1677fc63e37b971b641dfdff000ba353c4810414c20eIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v) 1678b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 16795a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* The LHS must be a dereference. If the LHS is a variable indexed array 16805a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * access of a vector, it must be separated into a series conditional moves 16815a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * before reaching this point (see ir_vec_index_to_cond_assign). 16825a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 16835a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->as_dereference()); 1684ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1685ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1686ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1687ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1688ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 16890161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 16900161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 16910161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 16922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 1693cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke return dst_reg(v->result); 1694cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1695cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1696c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick/** 1697c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Process the condition of a conditional assignment 1698c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1699c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Examines the condition of a conditional assignment to generate the optimal 1700c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * first operand of a \c CMP instruction. If the condition is a relational 1701c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 1702c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * used as the source for the \c CMP instruction. Otherwise the comparison 1703c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * is processed to a boolean result, and the boolean result is used as the 1704c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * operand to the CMP instruction. 1705c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1706c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickbool 1707c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanickir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) 1708c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick{ 1709c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_rvalue *src_ir = ir; 1710c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool negate = true; 1711c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool switch_order = false; 1712c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1713c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick ir_expression *const expr = ir->as_expression(); 1714c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if ((expr != NULL) && (expr->get_num_operands() == 2)) { 1715c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick bool zero_on_left = false; 1716c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1717c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (expr->operands[0]->is_zero()) { 1718c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[1]; 1719c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = true; 1720c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else if (expr->operands[1]->is_zero()) { 1721c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = expr->operands[0]; 1722c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick zero_on_left = false; 1723c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1724c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1725c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* a is - 0 + - 0 + 1726c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a < 0) T F F ( a < 0) T F F 1727c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 < a) F F T (-a < 0) F F T 1728c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 1729c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 1730c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a > 0) F F T (-a < 0) F F T 1731c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 > a) T F F ( a < 0) T F F 1732c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 1733c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 1734c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * 1735c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * Note that exchanging the order of 0 and 'a' in the comparison simply 1736c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * means that the value of 'a' should be negated. 1737c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1738c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (src_ir != ir) { 1739c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch (expr->operation) { 1740c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_less: 1741c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1742c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1743c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1744c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1745c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_greater: 1746c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = false; 1747c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1748c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1749c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1750c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_lequal: 1751c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1752c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = !zero_on_left; 1753c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1754c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1755c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick case ir_binop_gequal: 1756c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick switch_order = true; 1757c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick negate = zero_on_left; 1758c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1759c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1760c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick default: 1761c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* This isn't the right kind of comparison afterall, so make sure 1762c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * the whole condition is visited. 1763c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1764c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir = ir; 1765c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick break; 1766c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1767c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1768c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1769c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1770c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick src_ir->accept(this); 1771c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1772c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 1773c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * condition we produced is 0.0 or 1.0. By flipping the sign, we can 1774c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * choose which value OPCODE_CMP produces without an extra instruction 1775c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick * computing the condition. 1776c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick */ 1777c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (negate) 1778c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick this->result.negate = ~this->result.negate; 1779c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 1780c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick return switch_order; 1781c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick} 1782c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 178384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 178484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 178584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1786fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg l; 1787fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r; 17887d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 178984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 179084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 179184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1792cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1793fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick l = get_assignment_lhs(ir->lhs, this); 1794cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 17955a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This should really set to the correct maximal writemask for each 17965a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: component written (in the loops below). This case can only 17975a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: occur for matrices, arrays, and structures. 17985a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 17995a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick if (ir->write_mask == 0) { 18005a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 18015a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 18025a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else if (ir->lhs->type->is_scalar()) { 1803b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 18045a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: W component of fragment shader output zero, work correctly. 18055a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 18065a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 18075a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else { 1808b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int swizzles[4]; 1809b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int first_enabled_chan = 0; 1810b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt int rhs_chan = 0; 1811b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 18125a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->lhs->type->is_vector()); 18135a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = ir->write_mask; 1814b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1815b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1816b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) { 1817b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt first_enabled_chan = GET_SWZ(r.swizzle, i); 1818b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt break; 1819b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1820b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1821b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt 1822b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt /* Swizzle a small RHS vector into the channels being written. 1823b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * 1824b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * glsl ir treats write_mask as dictating how many channels are 1825b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * present on the RHS while Mesa IR treats write_mask as just 1826b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt * showing which channels of the vec4 RHS get written. 1827b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt */ 1828b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt for (int i = 0; i < 4; i++) { 1829b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt if (l.writemask & (1 << i)) 1830b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 1831b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt else 1832b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[i] = first_enabled_chan; 1833b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt } 1834b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 1835b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt swizzles[2], swizzles[3]); 18365a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } 18375a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick 18380161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 18390161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 184084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1841346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 1842c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick const bool switch_order = this->process_move_condition(ir->condition); 1843fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg condition = this->result; 18442d1789e667c4180777829f96856daf91326721b9Eric Anholt 18457d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 1846c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick if (switch_order) { 184701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, l, condition, src_reg(l), r); 1848c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } else { 184901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_CMP, l, condition, r, src_reg(l)); 1850c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick } 1851c05ccc1ebde177646ac09c1bd6d1b4719e745f82Ian Romanick 18527d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 18537d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 18547d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 18552d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 18567d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 185701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 18587d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 18597d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 18607d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1861346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 186284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 186384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 186484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 186584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 186684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 186784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1868fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg src; 18690a46497a4ee3325fab47929cb17cfe2525e1fc33Vinson Lee GLfloat stack_vals[4] = { 0 }; 18700bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 18710bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 187284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 18735b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt /* Unfortunately, 4 floats is all we can get into 18745b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store an 18755b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * aggregate constant and move each constant value into it. If we 18765b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * get lucky, copy propagation will eliminate the extra moves. 18775b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt */ 18785b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18795b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt if (ir->type->base_type == GLSL_TYPE_STRUCT) { 1880fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp_base = get_temp(ir->type); 1881cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg temp = dst_reg(temp_base); 18825b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18835b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt foreach_iter(exec_list_iterator, iter, ir->components) { 18845b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_constant *field_value = (ir_constant *)iter.get(); 18855b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt int size = type_size(field_value->type); 18865b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18875b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt assert(size > 0); 18885b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18895b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt field_value->accept(this); 1890461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 18915b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 18925b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt for (i = 0; i < (unsigned int)size; i++) { 189301e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, temp, src); 18945b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 1895461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index++; 18965b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt temp.index++; 18975b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18985b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 18995b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt this->result = temp_base; 19005b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt return; 19015b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 19025b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 190320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (ir->type->is_array()) { 1904fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp_base = get_temp(ir->type); 1905cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg temp = dst_reg(temp_base); 190620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt int size = type_size(ir->type->fields.array); 190720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 190820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt assert(size > 0); 190920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 191020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < ir->type->length; i++) { 191120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir->array_elements[i]->accept(this); 1912461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src = this->result; 191320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (int j = 0; j < size; j++) { 191401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, temp, src); 191520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1916461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index++; 191720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt temp.index++; 191820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 191920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 192020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt this->result = temp_base; 192120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt return; 192220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 192320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1924ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1925fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg mat = get_temp(ir->type); 1926cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg mat_column = dst_reg(mat); 1927ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1928ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1929ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1930ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1931ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1932fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src = src_reg(PROGRAM_CONSTANT, -1, NULL); 1933461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.index = _mesa_add_unnamed_constant(this->prog->Parameters, 19346d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 19359c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 1936461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke &src.swizzle); 193701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, mat_column, src); 1938ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1939ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1940ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1941ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1942ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1943ebef04011736ea8e13692fed87623d425c4d1b08Eric Anholt return; 1944582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 19450bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 1946461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke src.file = PROGRAM_CONSTANT; 19470bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 19480bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 19490bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 19500bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19510bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 19520bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19530bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 19540bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19550bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19560bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 19570bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19580bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 19590bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19600bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19610bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 19620bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 19630bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 19640bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19650bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 19660bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 19670bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 19680bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 19690bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 1970fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke this->result = src_reg(PROGRAM_CONSTANT, -1, ir->type); 19719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, 19726d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 19739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 19749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &this->result.swizzle); 197584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 197684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 19777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry * 19787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) 19797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{ 19807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry; 19817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, this->function_signatures) { 19837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = (function_entry *)iter.get(); 19847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig == sig) 19867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 19877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1989d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke entry = ralloc(mem_ctx, function_entry); 19907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig = sig; 19917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig_id = this->next_signature_id++; 19927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = NULL; 19937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Allocate storage for all the parameters. */ 19957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, sig->parameters) { 19967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)iter.get(); 1997b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage; 19987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt storage = find_variable_storage(param); 20007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!storage); 20017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2002b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 2003b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 2004b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(storage); 20057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->next_temp += type_size(param->type); 20077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2009576d01ad8c8b8aa57b4711c98d8e004d4f20fc0bEric Anholt if (!sig->return_type->is_void()) { 20107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = get_temp(sig->return_type); 20117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } else { 2012ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke entry->return_reg = undef_src; 20137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->function_signatures.push_tail(entry); 20167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 20177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt} 201884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 201984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 202084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 202184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 20227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *call_inst; 20237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig = ir->get_callee(); 20247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = get_function_signature(sig); 20257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 20267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process in parameters. */ 20287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list_iterator sig_iter = sig->parameters.iterator(); 20297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 20307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 20317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 20327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_in || 20347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 2035b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 20367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 20377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 2039fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r = this->result; 20407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2041fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg l; 20427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.file = storage->file; 20437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index = storage->index; 20447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.reladdr = NULL; 20457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.writemask = WRITEMASK_XYZW; 20467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.cond_mask = COND_TR; 20477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 204901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 20507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 20517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 20527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 20567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 20587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit call instruction */ 20605d9718f0dbe1bb9b25324c43ed0fa631735c6a51Kenneth Graunke call_inst = emit(ir, OPCODE_CAL); 20617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst->function = entry; 20627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process out parameters. */ 20647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter = sig->parameters.iterator(); 20657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 20667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 20677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 20687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_out || 20707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 2071b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 20727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 20737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2074fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r; 20757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.file = storage->file; 20767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index = storage->index; 20777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.reladdr = NULL; 20787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.swizzle = SWIZZLE_NOOP; 20797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.negate = 0; 20807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 2082cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke dst_reg l = dst_reg(this->result); 20837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 208501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 20867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 20877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 20887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 20927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 20947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process return value. */ 20967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->result = entry->return_reg; 209784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 209884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 209984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 210084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 210184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 210268074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke src_reg result_src, coord, lod_info, projector, dx, dy; 2103fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg result_dst, coord_dst; 2104d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 2105d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 210684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 210784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->coordinate->accept(this); 2108d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2109d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 2110d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 2111d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 2112d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 2113d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2114d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 2115cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke coord_dst = dst_reg(coord); 211601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, this->result); 2117d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2118de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 2119de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 2120de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 2121de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 2122de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 2123d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 2124d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 2125d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 2126d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 2127cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke result_dst = dst_reg(result_src); 2128d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2129d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 2130d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 2131d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 2132d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2133d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 2134d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 2135d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 2136d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2137d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2138d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 2139d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 2140d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 2141d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 2142d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2143d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 214468074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke opcode = OPCODE_TXD; 214568074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke ir->lod_info.grad.dPdx->accept(this); 214668074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke dx = this->result; 214768074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke ir->lod_info.grad.dPdy->accept(this); 214868074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke dy = this->result; 214968074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke break; 2150d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txf: 2151d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"GLSL 1.30 features unsupported"); 2152d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2153d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2154d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2155d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 2156d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 2157d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 2158d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 215901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, projector); 2160d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2161d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 2162d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 2163fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg coord_w = coord; 2164d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 2165d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2166d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 2167d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 2168d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 2169d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2170d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 217101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_RCP, coord_dst, projector); 2172d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 21739996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* In the case where we have to project the coordinates "by hand," 21749996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * the shadow comparitor value must also be projected. 21759996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 217601e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke src_reg tmp_src = coord; 21779996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick if (ir->shadow_comparitor) { 21789996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* Slot the shadow value in as the second to last component of the 21799996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * coord. 21809996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 21819996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick ir->shadow_comparitor->accept(this); 21829996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 21839996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_src = get_temp(glsl_type::vec4_type); 218401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke dst_reg tmp_dst = dst_reg(tmp_src); 21859996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 21869996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_dst.writemask = WRITEMASK_Z; 218701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, tmp_dst, this->result); 21889996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 21899996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick tmp_dst.writemask = WRITEMASK_XY; 219001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, tmp_dst, coord); 21919996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick } 21929996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick 2193d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 219401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MUL, coord_dst, tmp_src, coord_w); 2195d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2196d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2197d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 2198d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2199d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2200d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 22019996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick /* If projection is done and the opcode is not OPCODE_TXP, then the shadow 22029996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * comparitor was put in the correct place (and projected) by the code, 22039996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick * above, that handles by-hand projection. 22049996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick */ 22059996a86085edb2bdbcb165d985203ee8ce6a9b22Ian Romanick if (ir->shadow_comparitor && (!ir->projector || opcode == OPCODE_TXP)) { 2206b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 2207b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 2208b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 2209b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 2210b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_Z; 221101e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, this->result); 2212b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2213b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 2214b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2215d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 2216d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 2217d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 221801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, coord_dst, lod_info); 2219d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2220d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2221d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 222268074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke if (opcode == OPCODE_TXD) 222368074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke inst = emit(ir, opcode, result_dst, coord, dx, dy); 222468074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke else 222568074387a4af74e1b1b42908b23a4a7ca2c1efa4Kenneth Graunke inst = emit(ir, opcode, result_dst, coord); 2226d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2227b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 2228b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 2229b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2230a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2231a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->shader_program, 2232a32893221ce253da7bb465e0ec9d0df5f7208d8fEric Anholt this->prog); 2233c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt 2234aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt const glsl_type *sampler_type = ir->sampler->type; 2235d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2236c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt switch (sampler_type->sampler_dimensionality) { 2237d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 2238c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 22390a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2240d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2241d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 2242c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 22430a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2244d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2245d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 2246d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 2247d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2248d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 2249d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 2250d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 22510bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick case GLSL_SAMPLER_DIM_RECT: 22520bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick inst->tex_target = TEXTURE_RECT_INDEX; 22530bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick break; 225468772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick case GLSL_SAMPLER_DIM_BUF: 225568772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"FINISHME: Implement ARB_texture_buffer_object"); 225668772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick break; 2257d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 225868772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"Should not get here."); 2259d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2260d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2261d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 226284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 226384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 226484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 226584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 226684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 22677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (ir->get_value()) { 2268fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke dst_reg l; 22697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 22707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 227135220fc5981045331b4f048f0fc2e1371a0673edEric Anholt assert(current_function); 227235220fc5981045331b4f048f0fc2e1371a0673edEric Anholt 22737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir->get_value()->accept(this); 2274fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg r = this->result; 227584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2276cb21fa91b8e8f46d7d27604b9cb77fba031567f4Kenneth Graunke l = dst_reg(current_function->return_reg); 22777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 22787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(current_function->sig->return_type); i++) { 227901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_MOV, l, r); 22807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 22817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 22827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 22837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 22847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 228501e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_RET); 228684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 228784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 228816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 228916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 229016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 22919b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 22929b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt 2293ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák if (ir->condition) { 2294ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák ir->condition->accept(this); 2295ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák this->result.negate = ~this->result.negate; 2296ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke emit(ir, OPCODE_KIL, undef_dst, this->result); 2297ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } else { 229801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke emit(ir, OPCODE_KIL_NV); 2299ead2ea89f42b40edc56ddf8c6ce1df4efdcefe2aMarek Olšák } 230016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 23019b075cb9fa9eb6a95d0816283ef01ae72dafa680Eric Anholt fp->UsesKill = GL_TRUE; 230216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 230384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 230484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 230584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 230684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 2307847d397b3415b6705a084013903e1a7e8384e1d2Marek Olšák ir_to_mesa_instruction *cond_inst, *if_inst; 2308cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 2309cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2310cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2311c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2312c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 23130161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 2314c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 23156d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri if (this->options->EmitCondCodes) { 2316854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2317cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2318cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 2319cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 2320cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 2321cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 2322cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 2323fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunke src_reg temp = get_temp(glsl_type::bool_type); 232401e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke cond_inst = emit(ir->condition, OPCODE_MOV, dst_reg(temp), result); 2325cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 2326854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 2327854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 232801e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke if_inst = emit(ir->condition, OPCODE_IF); 2329461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if_inst->dst.cond_mask = COND_NE; 2330854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 2331ce5d969adf4db6e95e7f1abb0a5532311d1c3c28Kenneth Graunke if_inst = emit(ir->condition, OPCODE_IF, undef_dst, this->result); 2332854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 2333c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2334c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 2335c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2336c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 2337c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2338c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 2339847d397b3415b6705a084013903e1a7e8384e1d2Marek Olšák emit(ir->condition, OPCODE_ELSE); 23400a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 2341c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2342c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 23435d9718f0dbe1bb9b25324c43ed0fa631735c6a51Kenneth Graunke if_inst = emit(ir->condition, OPCODE_ENDIF); 234484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 234584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2346ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 2347ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 23480161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 2349ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 23507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 23517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 2352d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mem_ctx = ralloc_context(NULL); 2353ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 2354ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 2355fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor() 2356fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{ 2357d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(mem_ctx); 2358fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt} 2359fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt 236084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 2361fc6b4332c32461d0e092c908a0f3d9d44d1452a9Kenneth Graunkemesa_src_reg_from_ir_src_reg(src_reg reg) 236284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 236384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 236484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 236584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 236650fd99d1723a6c7f3bd2dedffeeadf7d5e33b83bBrian Paul assert(reg.index < (1 << INST_INDEX_BITS)); 236784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 236834195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 2369f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 2370ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 2371285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 2372b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt mesa_reg.HasIndex2 = GL_FALSE; 2373405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.RelAddr2 = 0; 2374405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.Index2 = 0; 237584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 237684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 237784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 237884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2379c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 23807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 23817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 2382c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2383c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2384e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 238564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 238664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 238764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 2388c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2389c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 239064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 239164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 2392c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 239364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 239464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 239564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 239664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 239764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 239864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 239964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 240064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 240164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 240264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 240364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 2404c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2405c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2406d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke if_stack = rzalloc_array(v->mem_ctx, int, if_count); 2407d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke loop_stack = rzalloc_array(v->mem_ctx, int, loop_count); 2408c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2409c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2410c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 2411c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 241264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 2413c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 2414c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2415c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 241664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 241764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 2418c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2419c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 242064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 2421c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 2422c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 242364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 242464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 242564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 242664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 242764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 242864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 242964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 243064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 243164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 243264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 243364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 243464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 243564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 243664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 243764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 243864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 243964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 244064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 244164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 244264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 244364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 24447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 24457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 24467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 24477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 24487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 24507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 24517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 24527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 24537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 24547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 2455c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 2456c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2457c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2458c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2459c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2460c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2461c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 2462c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 2463c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 2464c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2465c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2466c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 2467c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2468748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 2469c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2470c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2471c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 2472c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 2473c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2474748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 2475748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 247664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 2477748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 2478748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2479748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 2480748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 2481748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 2482748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 2483c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 2484c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 2485748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2486748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 2487c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2488c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2489748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 2490748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 2491c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2492c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2493c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 24948cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 24958cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul/** 24968cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * Count resources used by the given gpu program (number of texture 24978cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * samplers, etc). 24988cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul */ 2499ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void 2500ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog) 2501ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{ 2502d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt unsigned int i; 2503d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2504d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed = 0; 2505ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2506ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (i = 0; i < prog->NumInstructions; i++) { 2507ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt struct prog_instruction *inst = &prog->Instructions[i]; 2508d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2509d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (_mesa_is_tex_instruction(inst->Opcode)) { 2510d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplerTargets[inst->TexSrcUnit] = 2511d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt (gl_texture_index)inst->TexSrcTarget; 2512d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed |= 1 << inst->TexSrcUnit; 2513d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (inst->TexShadow) { 2514d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->ShadowSamplers |= 1 << inst->TexSrcUnit; 2515d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2516d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2517ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2518d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2519d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt _mesa_update_shader_textures_used(prog); 2520ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt} 2521ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 25228cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 25238cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul/** 25248cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * Check if the given vertex/fragment/shader program is within the 25258cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * resource limits of the context (number of texture units, etc). 25268cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * If any of those checks fail, record a linker error. 25278cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * 25288cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul * XXX more checks are needed... 25298cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul */ 25308cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paulstatic void 25318cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paulcheck_resources(const struct gl_context *ctx, 25328cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul struct gl_shader_program *shader_program, 25338cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul struct gl_program *prog) 25348cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul{ 25358cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul switch (prog->Target) { 25368cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul case GL_VERTEX_PROGRAM_ARB: 25378cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (_mesa_bitcount(prog->SamplersUsed) > 25388cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul ctx->Const.MaxVertexTextureImageUnits) { 25398aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 25408aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Too many vertex shader texture samplers"); 25418cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25420f84ddad29284b407c6bbef0b731201056d40324Marek Olšák if (prog->Parameters->NumParameters > MAX_UNIFORMS) { 25438aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, "Too many vertex shader constants"); 25448cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25458cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul break; 25468cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul case MESA_GEOMETRY_PROGRAM: 25478cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (_mesa_bitcount(prog->SamplersUsed) > 2548e0e94026a0648d6b33d6b7cf2b9b01429cf945e4Brian Paul ctx->Const.MaxGeometryTextureImageUnits) { 25498aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 25508aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Too many geometry shader texture samplers"); 25518cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25528cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (prog->Parameters->NumParameters > 25530f84ddad29284b407c6bbef0b731201056d40324Marek Olšák MAX_GEOMETRY_UNIFORM_COMPONENTS / 4) { 25548aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, "Too many geometry shader constants"); 25558cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25568cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul break; 25578cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul case GL_FRAGMENT_PROGRAM_ARB: 25588cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul if (_mesa_bitcount(prog->SamplersUsed) > 25598cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul ctx->Const.MaxTextureImageUnits) { 25608aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 25618aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Too many fragment shader texture samplers"); 25628cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25630f84ddad29284b407c6bbef0b731201056d40324Marek Olšák if (prog->Parameters->NumParameters > MAX_UNIFORMS) { 25648aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, "Too many fragment shader constants"); 25658cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25668cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul break; 25678cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul default: 25688cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul _mesa_problem(ctx, "unexpected program type in check_resources()"); 25698cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul } 25708cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul} 25718cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 25728cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 25738cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 257499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholtstruct uniform_sort { 257599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct gl_uniform *u; 257699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt int pos; 257799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt}; 257899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 257999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt/* The shader_program->Uniforms list is almost sorted in increasing 258099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt * uniform->{Frag,Vert}Pos locations, but not quite when there are 258199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt * uniforms shared between targets. We need to add parameters in 258299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt * increasing order for the targets. 258399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt */ 258499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholtstatic int 258599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholtsort_uniforms(const void *a, const void *b) 258699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt{ 258799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct uniform_sort *u1 = (struct uniform_sort *)a; 258899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct uniform_sort *u2 = (struct uniform_sort *)b; 258999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 259099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt return u1->pos - u2->pos; 259199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt} 259299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 25930924ba0c3496160a134d37cec800f902ae805b9cEric Anholt/* Add the uniforms to the parameters. The linker chose locations 25940924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * in our parameters lists (which weren't created yet), which the 25950924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * uniforms code will use to poke values into our parameters list 25960924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * when uniforms are updated. 259785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 259885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void 25990924ba0c3496160a134d37cec800f902ae805b9cEric Anholtadd_uniforms_to_parameters_list(struct gl_shader_program *shader_program, 26000924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_shader *shader, 26010924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_program *prog) 260285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 260385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt unsigned int i; 260499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt unsigned int next_sampler = 0, num_uniforms = 0; 260599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct uniform_sort *sorted_uniforms; 260699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 2607d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke sorted_uniforms = ralloc_array(NULL, struct uniform_sort, 260899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt shader_program->Uniforms->NumUniforms); 260985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 26100924ba0c3496160a134d37cec800f902ae805b9cEric Anholt for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) { 26110924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i; 26120924ba0c3496160a134d37cec800f902ae805b9cEric Anholt int parameter_index = -1; 26130924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 26140924ba0c3496160a134d37cec800f902ae805b9cEric Anholt switch (shader->Type) { 26150924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_VERTEX_SHADER: 26160924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->VertPos; 26170924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 26180924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_FRAGMENT_SHADER: 26190924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->FragPos; 26200924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 26210924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_GEOMETRY_SHADER: 26220924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->GeomPos; 26230924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 26240924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 26250924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 26260924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Only add uniforms used in our target. */ 262799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt if (parameter_index != -1) { 262899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt sorted_uniforms[num_uniforms].pos = parameter_index; 262999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt sorted_uniforms[num_uniforms].u = uniform; 263099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt num_uniforms++; 263199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 263299f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt } 263399f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 263499f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt qsort(sorted_uniforms, num_uniforms, sizeof(struct uniform_sort), 263599f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt sort_uniforms); 263699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 263799f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt for (i = 0; i < num_uniforms; i++) { 263899f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt struct gl_uniform *uniform = sorted_uniforms[i].u; 263999f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt int parameter_index = sorted_uniforms[i].pos; 264099f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt const glsl_type *type = uniform->Type; 264199f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt unsigned int size; 26420924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 26430924ba0c3496160a134d37cec800f902ae805b9cEric Anholt if (type->is_vector() || 26440924ba0c3496160a134d37cec800f902ae805b9cEric Anholt type->is_scalar()) { 26450924ba0c3496160a134d37cec800f902ae805b9cEric Anholt size = type->vector_elements; 26460924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } else { 26470924ba0c3496160a134d37cec800f902ae805b9cEric Anholt size = type_size(type) * 4; 26480924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 26490924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2650aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt gl_register_file file; 26510924ba0c3496160a134d37cec800f902ae805b9cEric Anholt if (type->is_sampler() || 26520924ba0c3496160a134d37cec800f902ae805b9cEric Anholt (type->is_array() && type->fields.array->is_sampler())) { 2653aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt file = PROGRAM_SAMPLER; 2654aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } else { 2655aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt file = PROGRAM_UNIFORM; 2656aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 265785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2658aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, 2659aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt uniform->Name); 26600924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2661aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index < 0) { 2662aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt index = _mesa_add_parameter(prog->Parameters, file, 2663aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt uniform->Name, size, type->gl_type, 2664aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt NULL, NULL, 0x0); 2665aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2666aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt /* Sampler uniform values are stored in prog->SamplerUnits, 2667aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * and the entry in that array is selected by this index we 2668aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * store in ParameterValues[]. 2669aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt */ 2670aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (file == PROGRAM_SAMPLER) { 2671aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt for (unsigned int j = 0; j < size / 4; j++) 26726d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain prog->Parameters->ParameterValues[index + j][0].f = next_sampler++; 2673aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 2674aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2675aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt /* The location chosen in the Parameters list here (returned 2676aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * from _mesa_add_uniform) has to match what the linker chose. 2677aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt */ 2678aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index != parameter_index) { 26798aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 26808aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Allocation of uniform `%s' to target failed " 26818aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "(%d vs %d)\n", 26828aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick uniform->Name, index, parameter_index); 26830924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 268485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 268585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 268699f3c9caa39fbe9dfa7561c919202395720e9472Eric Anholt 2687d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(sorted_uniforms); 268885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 268985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 26902f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 2691f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergset_uniform_initializer(struct gl_context *ctx, void *mem_ctx, 26922f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program, 26932f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const char *name, const glsl_type *type, 26942f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *val) 26952f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 26962f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_record()) { 26972f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *field_constant; 26982f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 26992f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)val->components.get_head(); 27002f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27012f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 27022f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *field_type = type->fields.structure[i].type; 2703d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, 27042f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt type->fields.structure[i].name); 27052f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 27062f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_type, field_constant); 27072f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)field_constant->next; 27082f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27092f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt return; 27102f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27112f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27122f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt int loc = _mesa_get_uniform_location(ctx, shader_program, name); 27132f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27142f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (loc == -1) { 27158aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(shader_program, 27168aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick "Couldn't find uniform for initializer %s\n", name); 2717500e7b75995460537b0e682e5bde4c32eb40b85cEric Anholt return; 27182f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27192f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27202f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 27212f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *element; 27222f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *element_type; 27232f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_array()) { 27242f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val->array_elements[i]; 27252f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type->fields.array; 27262f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 27272f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val; 27282f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type; 27292f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27302f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27312f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *values; 27322f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27332f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->base_type == GLSL_TYPE_BOOL) { 2734d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke int *conv = ralloc_array(mem_ctx, int, element_type->components()); 27352f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int j = 0; j < element_type->components(); j++) { 27362f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt conv[j] = element->value.b[j]; 27372f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27382f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = (void *)conv; 27392f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = glsl_type::get_instance(GLSL_TYPE_INT, 27402f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 27412f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 1); 27422f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 27432f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = &element->value; 27442f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27452f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27462f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->is_matrix()) { 27472f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform_matrix(ctx, shader_program, 27482f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->matrix_columns, 27492f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 27502f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc, 1, GL_FALSE, (GLfloat *)values); 27512f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += element_type->matrix_columns; 27522f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 27532f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 27542f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values, element_type->gl_type); 27552f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += type_size(element_type); 27562f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27572f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27582f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 27592f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27602f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 2761f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergset_uniform_initializers(struct gl_context *ctx, 27622f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program) 27632f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 27642f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *mem_ctx = NULL; 27652f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27663322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { 27672f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader *shader = shader_program->_LinkedShaders[i]; 27683322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 27693322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (shader == NULL) 27703322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 27713322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 27722f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt foreach_iter(exec_list_iterator, iter, *shader->ir) { 27732f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 27742f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_variable *var = ir->as_variable(); 27752f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27762f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!var || var->mode != ir_var_uniform || !var->constant_value) 27772f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt continue; 27782f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27792f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!mem_ctx) 2780d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mem_ctx = ralloc_context(NULL); 27812f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 27822f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, 27832f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt var->type, var->constant_value); 27842f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27852f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 27862f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 2787d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(mem_ctx); 27882f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 27892f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 279034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt/* 279134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * On a basic block basis, tracks available PROGRAM_TEMPORARY register 279234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * channels for copy propagation and updates following instructions to 279334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * use the original versions. 279434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 279534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * The ir_to_mesa_visitor lazily produces code assuming that this pass 279634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * will occur. As an example, a TXP production before this pass: 279734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 279834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 279934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 280034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 280134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 280234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * and after: 280334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 280434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 0: MOV TEMP[1], INPUT[4].xyyy; 280534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 1: MOV TEMP[1].w, INPUT[4].wwww; 280634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 280734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * 280834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * which allows for dead code elimination on TEMP[1]'s writes. 280934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 281034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtvoid 281134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholtir_to_mesa_visitor::copy_propagate(void) 281234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt{ 2813d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx, 281425beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt ir_to_mesa_instruction *, 281525beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt this->next_temp * 4); 28168902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 28178902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca int level = 0; 281834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 281934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt foreach_iter(exec_list_iterator, iter, this->instructions) { 282034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 282134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2822461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke assert(inst->dst.file != PROGRAM_TEMPORARY 2823461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke || inst->dst.index < this->next_temp); 28245c2cec8337c5afc6941cd5c0bcedd27ff99b1bc7Ian Romanick 282534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* First, do any copy propagation possible into the src regs. */ 282634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int r = 0; r < 3; r++) { 282734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *first = NULL; 282834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt bool good = true; 2829461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int acp_base = inst->src[r].index * 4; 283034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2831461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->src[r].file != PROGRAM_TEMPORARY || 2832461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].reladdr) 283334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt continue; 283434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 283534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* See if we can find entries in the ACP consisting of MOVs 283634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * from the same src register for all the swizzled channels 283734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * of this src register reference. 283834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 283934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2840461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(inst->src[r].swizzle, i); 284134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_chan = acp[acp_base + src_chan]; 284234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 284334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!copy_chan) { 284434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 284534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 284634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 284734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 28488902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca assert(acp_level[acp_base + src_chan] <= level); 28498902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 285034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (!first) { 285134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt first = copy_chan; 285234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } else { 2853461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (first->src[0].file != copy_chan->src[0].file || 2854461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke first->src[0].index != copy_chan->src[0].index) { 285534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt good = false; 285634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 285734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 285834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 285934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 286034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 286134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (good) { 286234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* We've now validated that we can copy-propagate to 286334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * replace this src register reference. Do it. 286434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 2865461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].file = first->src[0].file; 2866461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].index = first->src[0].index; 286734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 286834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt int swizzle = 0; 286934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2870461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(inst->src[r].swizzle, i); 287134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt ir_to_mesa_instruction *copy_inst = acp[acp_base + src_chan]; 2872461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << 287334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt (3 * i)); 287434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 2875461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->src[r].swizzle = swizzle; 287634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 287734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 287834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 287934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt switch (inst->op) { 288034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_BGNLOOP: 288134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt case OPCODE_ENDLOOP: 288234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* End of a basic block, clear the ACP entirely. */ 288325beab10cd39a400a0a6d2495cf814d22f346e81Eric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 288434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 288534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 28868902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_IF: 28878902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca ++level; 28888902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca break; 28898902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 28908902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_ENDIF: 28918902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca case OPCODE_ELSE: 28928902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca /* Clear all channels written inside the block from the ACP, but 28938902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca * leaving those that were not touched. 28948902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca */ 28958902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca for (int r = 0; r < this->next_temp; r++) { 28968902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca for (int c = 0; c < 4; c++) { 28978902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (!acp[4 * r + c]) 28988902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca continue; 28998902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 29008902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (acp_level[4 * r + c] >= level) 29018902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca acp[4 * r + c] = NULL; 29028902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca } 29038902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca } 29048902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca if (inst->op == OPCODE_ENDIF) 29058902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca --level; 29068902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca break; 29078902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca 290834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt default: 290934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* Continuing the block, clear any written channels from 291034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt * the ACP. 291134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt */ 2912461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { 291376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Any temporary might be written, so no copy propagation 291476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt * across this instruction. 291576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt */ 291676857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 2917461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke } else if (inst->dst.file == PROGRAM_OUTPUT && 2918461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.reladdr) { 291976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Any output might be written, so no copy propagation 292076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt * from outputs across this instruction. 292176857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt */ 292276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int r = 0; r < this->next_temp; r++) { 292376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 29243803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick if (!acp[4 * r + c]) 29253803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick continue; 29263803295fc2b9c517e80aa46f2338308e23e64e4aIan Romanick 2927461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) 292876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt acp[4 * r + c] = NULL; 292976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 293076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 2931461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke } else if (inst->dst.file == PROGRAM_TEMPORARY || 2932461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.file == PROGRAM_OUTPUT) { 293376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Clear where it's used as dst. */ 2934461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.file == PROGRAM_TEMPORARY) { 293576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 2936461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.writemask & (1 << c)) { 2937461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * inst->dst.index + c] = NULL; 293876857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 293976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 294076857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt } 294176857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 294276857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt /* Clear where it's used as src. */ 294376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int r = 0; r < this->next_temp; r++) { 294476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt for (int c = 0; c < 4; c++) { 294576857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt if (!acp[4 * r + c]) 294676857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt continue; 294776857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 2948461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); 294976857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt 2950461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (acp[4 * r + c]->src[0].file == inst->dst.file && 2951461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * r + c]->src[0].index == inst->dst.index && 2952461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.writemask & (1 << src_chan)) 295376857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt { 295476857e8954484d5bf8758d7bfc87f264f95a0ebdEric Anholt acp[4 * r + c] = NULL; 295534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 295634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 295734a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 295834a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 295934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt break; 296034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 296134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 296234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt /* If this is a copy, add it to the ACP. */ 296334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt if (inst->op == OPCODE_MOV && 2964461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke inst->dst.file == PROGRAM_TEMPORARY && 2965461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->dst.reladdr && 296634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt !inst->saturate && 2967461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->src[0].reladdr && 2968461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke !inst->src[0].negate) { 296934a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt for (int i = 0; i < 4; i++) { 2970461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke if (inst->dst.writemask & (1 << i)) { 2971461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp[4 * inst->dst.index + i] = inst; 2972461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke acp_level[4 * inst->dst.index + i] = level; 297334a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 297434a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 297534a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 297634a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt } 29777772a34f3aedfa8ef58ad5f912f56bd5adf27057Vinson Lee 29788902c42db4fd72568cfa071987cfa10e7a366c2eJosé Fonseca ralloc_free(acp_level); 2979d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(acp); 298034a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt} 298134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 2982f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 2983f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 2984f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Convert a shader's GLSL IR into a Mesa gl_program. 2985f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 29866162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulstatic struct gl_program * 29876162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paulget_mesa_program(struct gl_context *ctx, 29886162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul struct gl_shader_program *shader_program, 298995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 299084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 299184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 299284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2993c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 2994c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2995364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 2996364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 2997c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 29987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt GLboolean progress; 29996d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri struct gl_shader_compiler_options *options = 30006d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 3001364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3002364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 3003c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 3004c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 3005c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 3006c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 3007c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 3008c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 3009c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 3010c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 3011903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul case GL_GEOMETRY_SHADER: 3012903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target = GL_GEOMETRY_PROGRAM_NV; 3013903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul target_string = "geometry"; 3014903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul break; 3015c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 3016c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 30174841c0a15adcc722e67d7d246987cd686d3f7a17José Fonseca return NULL; 3018364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 301984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30201124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 30211124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 3022859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 3023364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 3024364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 3025364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 3026364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 3027364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Attributes = _mesa_new_parameter_list(); 3028364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 3029364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 3030aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt v.shader_program = shader_program; 30316d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri v.options = options; 3032364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 30330924ba0c3496160a134d37cec800f902ae805b9cEric Anholt add_uniforms_to_parameters_list(shader_program, shader, prog); 30340924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 30357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 303616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 303701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke v.emit(NULL, OPCODE_END); 303884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Now emit bodies for any functions that were used. */ 30407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt do { 30417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_FALSE; 30427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 30437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v.function_signatures) { 30447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 30457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 30467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (!entry->bgn_inst) { 30477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt v.current_function = entry; 30487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 304901e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke entry->bgn_inst = v.emit(NULL, OPCODE_BGNSUB); 30507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst->function = entry; 30517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 30527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt visit_exec_list(&entry->sig->body, &v); 30537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3054806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt ir_to_mesa_instruction *last; 3055806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt last = (ir_to_mesa_instruction *)v.instructions.get_tail(); 3056806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt if (last->op != OPCODE_RET) 305701e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke v.emit(NULL, OPCODE_RET); 3058806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt 305940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt ir_to_mesa_instruction *end; 306001e19fcf1f36cea40cc5efc48796d4e153a20f2fKenneth Graunke end = v.emit(NULL, OPCODE_ENDSUB); 306140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end->function = entry; 306240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt 30637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_TRUE; 30647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 30657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 30667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } while (progress); 30677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3068364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 3069364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 307084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 307184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 307284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 307384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 307484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 307584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 307684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 307784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 3078d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mesa_instruction_annotation = ralloc_array(v.mem_ctx, ir_instruction *, 3079364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 308084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 308134a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt v.copy_propagate(); 308234a9da4eb4dd41dc874f1a175e993e42d4ff4b2aEric Anholt 3083f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Convert ir_mesa_instructions into prog_instructions. 3084f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 308584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 3086c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 308784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 3088f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 3089b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 309084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 3091854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 3092ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt if (inst->saturate) 3093ac89a90401f08df945248fcc96da59ba0e2bbfa9Eric Anholt mesa_inst->SaturateMode = SATURATE_ZERO_ONE; 3094461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.File = inst->dst.file; 3095461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.Index = inst->dst.index; 3096461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.CondMask = inst->dst.cond_mask; 3097461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.WriteMask = inst->dst.writemask; 3098461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->DstReg.RelAddr = inst->dst.reladdr != NULL; 3099461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src[0]); 3100461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src[1]); 3101461273e9105b8d0d53c26854ac5ba68814c31a67Kenneth Graunke mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src[2]); 3102d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 3103d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 3104b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 3105c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 3106aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 31075755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák /* Set IndirectRegisterFiles. */ 31085755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->DstReg.RelAddr) 31095755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; 31105755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 3111f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul /* Update program's bitmask of indirectly accessed register files */ 31125755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák for (unsigned src = 0; src < 3; src++) 31135755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->SrcReg[src].RelAddr) 31145755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; 31155755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 311640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt switch (mesa_inst->Opcode) { 3117322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_IF: 3118322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick if (options->EmitNoIfs) { 3119322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 3120322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't flatten if-statement. " 3121322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 3122322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 3123322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 3124322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 3125322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_BGNLOOP: 3126322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick if (options->EmitNoLoops) { 3127322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 3128322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't unroll loop. " 3129322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 3130322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 3131322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 3132322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 3133322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick case OPCODE_CONT: 3134322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick if (options->EmitNoCont) { 3135322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick linker_warning(shader_program, 3136322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "Couldn't lower continue-statement. " 3137322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "This will likely result in software " 3138322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick "rasterization.\n"); 3139322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick } 3140322c3bf9dc4c6edbf5a8793475ce1307e1c0186bIan Romanick break; 314140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_BGNSUB: 31427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function->inst = i; 314340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 314440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 314540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ENDSUB: 314640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 314740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 314840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_CAL: 31497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ 315040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 315140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ARL: 3152d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 315340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 315440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt default: 315540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 315640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt } 31577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 315884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 3159c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 31606162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 31616162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) 31626162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 31636162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 31646162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 31656162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!shader_program->LinkStatus) { 31666162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul free(mesa_instructions); 31676162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul _mesa_reference_program(ctx, &shader->Program, NULL); 31686162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul return NULL; 316984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 3170c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 31717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 3172925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 3173c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 3174455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 3175455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL IR for linked %s program %d:\n", target_string, 3176455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 3177455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt _mesa_print_ir(shader->ir, NULL); 3178455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 3179455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 3180455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("Mesa IR for linked %s program %d:\n", target_string, 3181455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 3182364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 3183364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 3184364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3185364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3186364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 3187364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 3188364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3189925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt do_set_program_inouts(shader->ir, prog); 3190925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt count_resources(prog); 3191925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 31928cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul check_resources(ctx, shader_program, prog); 31938cc84b3e454cf03c71282322e988f03bc4a1baa3Brian Paul 319416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 3195364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 319628faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 319728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 319828faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 319928faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 3200364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 3201364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 3202364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 320316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 3204f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3205f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3206f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a shader. 3207f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Called via ctx->Driver.LinkShader() 3208f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * This actually involves converting GLSL IR into Mesa gl_programs with 3209f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * code lowering and other optimizations. 3210f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 3211d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean 3212f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 3213d19eecef54384c163af27a470496ed885a5a271bEric Anholt{ 3214d19eecef54384c163af27a470496ed885a5a271bEric Anholt assert(prog->LinkStatus); 3215d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32163322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 32173322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 32183322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 32193322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 3220d19eecef54384c163af27a470496ed885a5a271bEric Anholt bool progress; 3221d19eecef54384c163af27a470496ed885a5a271bEric Anholt exec_list *ir = prog->_LinkedShaders[i]->ir; 3222f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul const struct gl_shader_compiler_options *options = 32236d3a2c97f4a78e85545286e0e126cd3a27bd1cbdLuca Barbieri &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 3224d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3225d19eecef54384c163af27a470496ed885a5a271bEric Anholt do { 3226d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = false; 3227d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3228d19eecef54384c163af27a470496ed885a5a271bEric Anholt /* Lowering */ 3229d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_mat_op_to_vec(ir); 3230c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 3231c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick | LOG_TO_LOG2 3232c4285be9a5bd1adaa89050989374b95a9a601cdcIan Romanick | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); 3233d19eecef54384c163af27a470496ed885a5a271bEric Anholt 323487708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 323587708e8c90220cc1997cef9de9b394c04d952be9Luca Barbieri 3236e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress; 3237d19eecef54384c163af27a470496ed885a5a271bEric Anholt 323811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick progress = lower_quadop_vector(ir, true) || progress; 323911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick 3240940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke if (options->EmitNoIfs) { 3241940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke progress = lower_discard(ir) || progress; 32429ac6a9b2fa45debac63f2e2b20d78c4776d06e37Kenneth Graunke progress = lower_if_to_cond_assign(ir) || progress; 3243940df10100d740ef27fa39026fd51c3199ed3d62Kenneth Graunke } 3244d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32452b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick if (options->EmitNoNoise) 32462b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick progress = lower_noise(ir) || progress; 32472b70dbfe091af5ae7c788e16275e1af2cb1c284cIan Romanick 3248a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick /* If there are forms of indirect addressing that the driver 3249a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick * cannot handle, perform the lowering pass. 3250a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick */ 3251a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 3252a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 3253a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick progress = 3254a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick lower_variable_index_to_cond_assign(ir, 3255a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectInput, 3256a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectOutput, 3257a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectTemp, 3258a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick options->EmitNoIndirectUniform) 3259a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick || progress; 3260a6ecd1c3724a78b76ab9e81ea39632f1279021f8Ian Romanick 3261d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = do_vec_index_to_cond_assign(ir) || progress; 3262d19eecef54384c163af27a470496ed885a5a271bEric Anholt } while (progress); 3263d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3264d19eecef54384c163af27a470496ed885a5a271bEric Anholt validate_ir_tree(ir); 3265d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3266d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32673322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 3268d19eecef54384c163af27a470496ed885a5a271bEric Anholt struct gl_program *linked_prog; 3269d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32703322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick if (prog->_LinkedShaders[i] == NULL) 32713322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick continue; 32723322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick 3273d19eecef54384c163af27a470496ed885a5a271bEric Anholt linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 3274d19eecef54384c163af27a470496ed885a5a271bEric Anholt 32756162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (linked_prog) { 32766162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul bool ok = true; 32776162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 32786162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul switch (prog->_LinkedShaders[i]->Type) { 32796162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul case GL_VERTEX_SHADER: 32806162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul _mesa_reference_vertprog(ctx, &prog->VertexProgram, 32816162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul (struct gl_vertex_program *)linked_prog); 32826162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 32836162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul linked_prog); 32846162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 32856162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul case GL_FRAGMENT_SHADER: 32866162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul _mesa_reference_fragprog(ctx, &prog->FragmentProgram, 32876162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul (struct gl_fragment_program *)linked_prog); 32886162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 32896162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul linked_prog); 32906162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul break; 3291903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul case GL_GEOMETRY_SHADER: 3292903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul _mesa_reference_geomprog(ctx, &prog->GeometryProgram, 3293903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul (struct gl_geometry_program *)linked_prog); 3294903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul ok = ctx->Driver.ProgramStringNotify(ctx, GL_GEOMETRY_PROGRAM_NV, 3295903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul linked_prog); 3296903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul break; 32976162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 32986162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul if (!ok) { 32996162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul return GL_FALSE; 33006162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul } 3301d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 33026162773ea4b0e84c3ab9c9952fb5e838519c2564Brian Paul 33033cd233eb5714137dccb6218ad78005511bcc02bdEric Anholt _mesa_reference_program(ctx, &linked_prog, NULL); 3304d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 3305d19eecef54384c163af27a470496ed885a5a271bEric Anholt 3306d19eecef54384c163af27a470496ed885a5a271bEric Anholt return GL_TRUE; 3307d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 330816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 3309f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3310f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3311f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Compile a GLSL shader. Called via glCompileShader(). 3312f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 331316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 3314f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) 3315364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 33162462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 33172462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 33185e18b051c039564d1998818d08caf1bff3983630Ian Romanick 3319153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 3320a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke /* Check if the user called glCompileShader without first calling 3321a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke * glShaderSource. This should fail to compile, but not raise a GL_ERROR. 3322a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke */ 3323a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke if (source == NULL) { 3324a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke shader->CompileStatus = GL_FALSE; 3325a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke return; 3326a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke } 3327a09a8ec12d76e1fb1583fa99cf9f48246c108d7bKenneth Graunke 332806143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick state->error = preprocess(state, &source, &state->info_log, 33297dcfc44b72f00ba5a38cb02123c80113440f0de9Kenneth Graunke &ctx->Extensions, ctx->API); 3330153eca98064252be4daad9cc27746f37c245b627Ian Romanick 33311b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 33329bd7e9c6b29b212a97bd4ca6c62836160b2f7698Eric Anholt printf("GLSL source for %s shader %d:\n", 33339bd7e9c6b29b212a97bd4ca6c62836160b2f7698Eric Anholt _mesa_glsl_shader_target_name(state->target), shader->Name); 33341b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt printf("%s\n", shader->Source); 33351b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt } 33361b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt 3337153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 3338153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 3339153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 3340153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 3341153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 3342364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3343d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(shader->ir); 334416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 3345364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 334616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 3347364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 334816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 3349ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3350ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 33512f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt /* Do some optimization at compile time to reduce shader IR size 33522f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt * and reduce later work if the same shader is linked multiple times 33532f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt */ 3354e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri while (do_common_optimization(shader->ir, false, 32)) 33552f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt ; 3356ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 3357ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 3358364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3359364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3360364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 3361364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3362364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 3363364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 336425f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 3365d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 3366d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 3367d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 3368c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 3369b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt if (ctx->Shader.Flags & GLSL_LOG) { 3370b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt _mesa_write_shader_to_file(shader); 3371b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt } 3372b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt 33730df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 33740df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->CompileStatus) { 33750df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL IR for shader %d:\n", shader->Name); 33760df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt _mesa_print_ir(shader->ir, NULL); 33770df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("\n\n"); 33780df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } else { 33790df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d failed to compile.\n", shader->Name); 33800df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 33810df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->InfoLog && shader->InfoLog[0] != 0) { 33820df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d info log:\n", shader->Name); 33830df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", shader->InfoLog); 33840df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3385455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt } 3386455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt 3387116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 33884a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt reparent_ir(shader->ir, shader->ir); 3389116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 3390d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(state); 3391d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 3392364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3393f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul 3394f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul/** 3395f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul * Link a GLSL shader program. Called via glLinkProgram(). 3396f1c1ee11d34f4aa5975641a615c7fd2edb32e1c0Brian Paul */ 3397364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 3398f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 3399364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 3400364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 3401849e18153cd91d812f694b806a84008498860bc3Eric Anholt 3402364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 3403364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3404849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 3405364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3406364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 3407849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 34088aadd89d07d750aadd10989fa9c81f8a2fdd98e2Ian Romanick linker_error(prog, "linking with uncompiled shader"); 3409849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 3410364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3411364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3412364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3413364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 3414364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); 3415364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); 3416903ead0b26e4fc55474b652adf9470247283e7aaBrian Paul _mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL); 3417364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3418849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 34195d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt link_shaders(ctx, prog); 3420849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 3421364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3422364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 34230df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (!ctx->Driver.LinkShader(ctx, prog)) { 3424d19eecef54384c163af27a470496ed885a5a271bEric Anholt prog->LinkStatus = GL_FALSE; 3425af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3426af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 3427af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt 34282f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializers(ctx, prog); 34292f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 3430af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 3431af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (!prog->LinkStatus) { 34320df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d failed to link\n", prog->Name); 34330df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 34340df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt 34350df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (prog->InfoLog && prog->InfoLog[0] != 0) { 34360df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d info log:\n", prog->Name); 34370df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", prog->InfoLog); 34380df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 3439364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 3440364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 3441364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 3442364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 3443