brw_fs_visitor.cpp revision 07e621c52329cd17b97051a26493626228d043b9
1d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* 2d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Copyright © 2010 Intel Corporation 3d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 4d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 5d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * copy of this software and associated documentation files (the "Software"), 6d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * to deal in the Software without restriction, including without limitation 7d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 9d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Software is furnished to do so, subject to the following conditions: 10d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 11d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * The above copyright notice and this permission notice (including the next 12d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * paragraph) shall be included in all copies or substantial portions of the 13d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Software. 14d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 15d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * IN THE SOFTWARE. 22d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 23d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 24d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** @file brw_fs_visitor.cpp 25d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 26d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * This file supports generating the FS LIR from the GLSL IR. The LIR 27d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * makes it easier to do backend-specific optimizations than doing so 28d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * in the GLSL IR or in the native code. 29d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 30d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtextern "C" { 31d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 32d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include <sys/types.h> 33d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 34d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/macros.h" 35d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/shaderobj.h" 36d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/uniforms.h" 37d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_parameter.h" 38d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_print.h" 39d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_optimize.h" 40d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/register_allocate.h" 41d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/sampler.h" 42d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/hash_table.h" 43d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_context.h" 44d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_eu.h" 45d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_wm.h" 46d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 47d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_shader.h" 48d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_fs.h" 492f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/glsl_types.h" 502f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir_optimization.h" 512f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir_print_visitor.h" 52d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 53d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 54d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_variable *ir) 55d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 56d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg *reg = NULL; 57d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 58d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (variable_storage(ir)) 59d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 60d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 61d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->mode == ir_var_in) { 62d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!strcmp(ir->name, "gl_FragCoord")) { 63d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_fragcoord_interpolation(ir); 64d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (!strcmp(ir->name, "gl_FrontFacing")) { 65d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_frontfacing_interpolation(ir); 66d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 67d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_general_interpolation(ir); 68d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 69d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(reg); 70d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt hash_table_insert(this->variable_ht, reg, ir); 71d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 726d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else if (ir->mode == ir_var_out) { 736d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt reg = new(this->mem_ctx) fs_reg(this, ir->type); 74d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 756d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt if (ir->location == FRAG_RESULT_COLOR) { 766d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* Writing gl_FragColor outputs to all color regions. */ 7751e5a266c1e1c12c4f0d82bee3caff008a41c9fdEric Anholt for (int i = 0; i < MAX2(c->key.nr_color_regions, 1); i++) { 786d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt this->outputs[i] = *reg; 796d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } 806d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else if (ir->location == FRAG_RESULT_DEPTH) { 816d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt this->frag_depth = ir; 826d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else { 836d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* gl_FragData or a user-defined FS output */ 846d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt assert(ir->location >= FRAG_RESULT_DATA0 && 856d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt ir->location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS); 866d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt 876d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* General color output. */ 886d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt for (unsigned int i = 0; i < MAX2(1, ir->type->length); i++) { 896d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt int output = ir->location - FRAG_RESULT_DATA0 + i; 906d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt this->outputs[output] = *reg; 916d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt this->outputs[output].reg_offset += 4 * i; 926d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } 936d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } 946d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else if (ir->mode == ir_var_uniform) { 95d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int param_index = c->prog_data.nr_params; 96d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 97d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 98d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!variable_storage(ir)) { 99d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Failed to find uniform '%s' in 16-wide\n", ir->name); 100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!strncmp(ir->name, "gl_", 3)) { 105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt setup_builtin_uniform_values(ir); 106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt setup_uniform_values(ir->location, ir->type); 108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index); 111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg->type = brw_type_for_base_type(ir->type); 112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!reg) 115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = new(this->mem_ctx) fs_reg(this, ir->type); 116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt hash_table_insert(this->variable_ht, reg, ir); 118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_variable *ir) 122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg *reg = variable_storage(ir->var); 124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = *reg; 125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_record *ir) 129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const glsl_type *struct_type = ir->record->type; 131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->record->accept(this); 133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt unsigned int offset = 0; 135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < struct_type->length; i++) { 136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt offset += type_size(struct_type->fields.structure[i].type); 139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += offset; 141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.type = brw_type_for_base_type(ir->type); 142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 145d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_array *ir) 146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_constant *index; 148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int element_size; 149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->array->accept(this); 151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt index = ir->array_index->as_constant(); 152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt element_size = type_size(ir->type); 154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.type = brw_type_for_base_type(ir->type); 155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (index) { 157b76378d46a211521582cfab56dc05031a57502a6Eric Anholt assert(this->result.file == UNIFORM || this->result.file == GRF); 158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += index->value.i[0] * element_size; 159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME: non-constant array element"); 161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* Instruction selection: Produce a MOV.sat instead of 165d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * MIN(MAX(val, 0), 1) when possible. 166d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 167d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtbool 168d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::try_emit_saturate(ir_expression *ir) 169d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 170d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_rvalue *sat_val = ir->as_rvalue_to_saturate(); 171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!sat_val) 173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return false; 174d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 175d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sat_val->accept(this); 176d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src = this->result; 177d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = fs_reg(this, ir->type); 179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, this->result, src); 180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->saturate = true; 181d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 182d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return true; 183d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_expression *ir) 187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt unsigned int operand; 189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2], temp; 190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->get_num_operands() <= 2); 193d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (try_emit_saturate(ir)) 195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 196d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->operands[operand]->accept(this); 199d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (this->result.file == BAD_FILE) { 200d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_print_visitor v; 201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Failed to get tree for expression operand:\n"); 202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->operands[operand]->accept(&v); 203d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 204d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[operand] = this->result; 205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Matrix expression operands should have been broken down to vector 207d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * operations already. 208d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 209d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->operands[operand]->type->is_matrix()); 210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* And then those vector operands should have been broken down to scalar. 211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->operands[operand]->type->is_vector()); 213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 215d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke /* Storage for our result. If our result goes into an assignment, it will 216d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke * just get copy-propagated out, so no worries. 217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 218d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke this->result = fs_reg(this, ir->type); 219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 220d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->operation) { 221d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 222d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Note that BRW_OPCODE_NOT is not appropriate here, since it is 223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * ones complement of the whole register, not just bit 0. 224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 225d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_XOR, this->result, op[0], fs_reg(1)); 226d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_neg: 228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = !op[0].negate; 229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = op[0]; 230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_abs: 232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].abs = true; 233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = false; 234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = op[0]; 235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sign: 237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = fs_reg(this, ir->type); 238d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 239d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f)); 240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 241d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)); 242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_G; 243d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(1.0f)); 244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 245d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)); 247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 248d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f)); 249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_rcp: 25365b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->result, op[0]); 254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_exp2: 25765b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_EXP2, this->result, op[0]); 258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_log2: 26065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_LOG2, this->result, op[0]); 261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_exp: 263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_log: 264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sin: 267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sin_reduced: 26865b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_SIN, this->result, op[0]); 269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_cos: 271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_cos_reduced: 27265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_COS, this->result, op[0]); 273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_dFdx: 276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DDX, this->result, op[0]); 277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_dFdy: 279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DDY, this->result, op[0]); 280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_add: 283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, this->result, op[0], op[1]); 284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_sub: 286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by ir_sub_to_add_neg"); 287d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 288d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_mul: 2903f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt if (ir->type->is_integer()) { 2913f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt /* For integer multiplication, the MUL uses the low 16 bits 2923f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * of one of the operands (src0 on gen6, src1 on gen7). The 2933f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * MACH accumulates in the contribution of the upper 16 bits 2943f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * of that operand. 2953f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * 2963f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * FINISHME: Emit just the MUL if we know an operand is small 2973f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * enough. 2983f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt */ 2993f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D); 3003f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt 3013f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MUL, acc, op[0], op[1]); 3023f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]); 3033f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MOV, this->result, fs_reg(acc)); 3043f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt } else { 3053f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MUL, this->result, op[0], op[1]); 3063f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt } 307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_div: 30983dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt if (intel->gen >= 7 && c->dispatch_width == 16) 31083dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt fail("16-wide INTDIV unsupported\n"); 31183dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt 312ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke /* Floating point should be lowered by DIV_TO_MUL_RCP in the compiler. */ 313ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke assert(ir->type->is_integer()); 314ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]); 315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_mod: 31783dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt if (intel->gen >= 7 && c->dispatch_width == 16) 31883dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt fail("16-wide INTDIV unsupported\n"); 31983dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt 320ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */ 321ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke assert(ir->type->is_integer()); 322ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke emit_math(SHADER_OPCODE_INT_REMAINDER, this->result, op[0], op[1]); 323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = this->result; 334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* original gen4 does implicit conversion before comparison. */ 335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen < 5) 336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp.type = op[0].type; 337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 33873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[0]); 33973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[1]); 34073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]); 342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = brw_conditional_for_comparison(ir->operation); 343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)); 344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_XOR, this->result, op[0], op[1]); 348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_OR, this->result, op[0], op[1]); 352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_AND, this->result, op[0], op[1]); 356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_dot: 359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_any: 360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by brw_fs_channel_expressions"); 361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 363d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_noise: 364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by lower_noise"); 365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_quadop_vector: 368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by lower_quadop_vector"); 369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sqrt: 37265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_SQRT, this->result, op[0]); 373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_rsq: 37665b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RSQ, this->result, op[0]); 377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 379b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke case ir_unop_i2u: 380b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke op[0].type = BRW_REGISTER_TYPE_UD; 381b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke this->result = op[0]; 382b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke break; 383b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke case ir_unop_u2i: 384b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke op[0].type = BRW_REGISTER_TYPE_D; 385b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke this->result = op[0]; 386b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke break; 387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2f: 3884bc5bfb641bce931bf35f0e78ec2b44263d152baKenneth Graunke case ir_unop_u2f: 389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_b2f: 390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_b2i: 391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2i: 392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->result, op[0]); 393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = this->result; 397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* original gen4 does implicit conversion before comparison. */ 398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen < 5) 399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp.type = op[0].type; 400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 40173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[0]); 40273b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, temp, op[0], fs_reg(0.0f)); 404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1)); 406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_trunc: 409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_RNDZ, this->result, op[0]); 410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_ceil: 412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = !op[0].negate; 413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_RNDD, this->result, op[0]); 414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.negate = true; 415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_floor: 417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_RNDD, this->result, op[0]); 418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_fract: 420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_FRC, this->result, op[0]); 421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_round_even: 423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_RNDE, this->result, op[0]); 424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_min: 42773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[0]); 42873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[1]); 42973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 430c331b3123ecda127919458e24848b7c1596525acEric Anholt if (intel->gen >= 6) { 431c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 432c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 433c331b3123ecda127919458e24848b7c1596525acEric Anholt } else { 434c331b3123ecda127919458e24848b7c1596525acEric Anholt /* Unalias the destination */ 435c331b3123ecda127919458e24848b7c1596525acEric Anholt this->result = fs_reg(this, ir->type); 436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 437c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); 438c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 440c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 441c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->predicated = true; 442c331b3123ecda127919458e24848b7c1596525acEric Anholt } 443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_max: 44573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[0]); 44673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[1]); 44773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 448c331b3123ecda127919458e24848b7c1596525acEric Anholt if (intel->gen >= 6) { 449c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 450c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_GE; 451c331b3123ecda127919458e24848b7c1596525acEric Anholt } else { 452c331b3123ecda127919458e24848b7c1596525acEric Anholt /* Unalias the destination */ 453c331b3123ecda127919458e24848b7c1596525acEric Anholt this->result = fs_reg(this, ir->type); 454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 455c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); 456c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_G; 457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 458c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 459c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->predicated = true; 460c331b3123ecda127919458e24848b7c1596525acEric Anholt } 461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_pow: 46465b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]); 465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_bit_not: 468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_NOT, this->result, op[0]); 469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_and: 471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, this->result, op[0], op[1]); 472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_xor: 474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_XOR, this->result, op[0], op[1]); 475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_or: 477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_OR, this->result, op[0], op[1]); 478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lshift: 4817de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt inst = emit(BRW_OPCODE_SHL, this->result, op[0], op[1]); 4827de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt break; 4837de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt 484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_rshift: 4857de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt if (ir->type->base_type == GLSL_TYPE_INT) 4867de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt inst = emit(BRW_OPCODE_ASR, this->result, op[0], op[1]); 4877de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt else 4887de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt inst = emit(BRW_OPCODE_SHR, this->result, op[0], op[1]); 489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r, 495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const glsl_type *type, bool predicated) 496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (type->base_type) { 498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_FLOAT: 499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_UINT: 500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_INT: 501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_BOOL: 502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->components(); i++) { 503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.type = brw_type_for_base_type(type); 504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.type = brw_type_for_base_type(type); 505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (predicated || !l.equals(&r)) { 507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, l, r); 508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = predicated; 509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset++; 512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.reg_offset++; 513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_ARRAY: 516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, type->fields.array, predicated); 518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_STRUCT: 522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, type->fields.structure[i].type, 524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt predicated); 525d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 526d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_SAMPLER: 529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 537dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke/* If the RHS processing resulted in an instruction generating a 538dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * temporary value, and it would be easy to rewrite the instruction to 539dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * generate its result right into the LHS instead, do so. This ends 540dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * up reliably removing instructions where it can be tricky to do so 541dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * later without real UD chain information. 542dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke */ 543dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkebool 544dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkefs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir, 545dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_reg dst, 546dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_reg src, 547dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *pre_rhs_inst, 548dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *last_rhs_inst) 549dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke{ 550dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (pre_rhs_inst == last_rhs_inst) 551dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; /* No instructions generated to work with. */ 552dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 553dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Only attempt if we're doing a direct assignment. */ 554dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (ir->condition || 555dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke !(ir->lhs->type->is_scalar() || 556dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke (ir->lhs->type->is_vector() && 557dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1))) 558dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; 559dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 560dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Make sure the last instruction generated our source reg. */ 561dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (last_rhs_inst->predicated || 562dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke last_rhs_inst->force_uncompressed || 563dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke last_rhs_inst->force_sechalf || 564dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke !src.equals(&last_rhs_inst->dst)) 565dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; 566dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 567dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Success! Rewrite the instruction. */ 568dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke last_rhs_inst->dst = dst; 569dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 570dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return true; 571dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke} 572dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_assignment *ir) 575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 576eb86bb55f5faef67c21604db19210c6788592679Kenneth Graunke fs_reg l, r; 577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* FINISHME: arrays on the lhs */ 580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lhs->accept(this); 581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l = this->result; 582d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 583dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail(); 584dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->rhs->accept(this); 586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r = this->result; 587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 588dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail(); 589dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(l.file != BAD_FILE); 591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(r.file != BAD_FILE); 592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 593dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst)) 594dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return; 595dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->condition) { 597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_bool_to_cond_code(ir->condition); 598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->lhs->type->is_scalar() || 601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lhs->type->is_vector()) { 602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->lhs->type->vector_elements; i++) { 603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->write_mask & (1 << i)) { 604d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke inst = emit(BRW_OPCODE_MOV, l, r); 605d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke if (ir->condition) 606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.reg_offset++; 608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset++; 610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, ir->lhs->type, ir->condition != NULL); 613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, 618d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int sampler) 619d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen; 621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 1; 622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool simd16 = false; 623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg orig_dst; 624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* g0 header. */ 626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = 1; 627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 6286430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && ir->op != ir_txd) { 629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 63007e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); 631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* gen4's SIMD8 sampler always has the slots for u,v,r present. */ 634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 3; 635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->op == ir_tex) { 637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* There's no plain shadow compare message, so we use shadow 638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * compare with a bias of 0.0. 639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f)); 641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_txb) { 643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->op == ir_txl); 648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->shadow_comparitor->accept(this); 654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_tex) { 657d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 65807e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); 659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* gen4's SIMD8 sampler always has the slots for u,v,r present. */ 662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 3; 663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_txd) { 6646c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke ir->lod_info.grad.dPdx->accept(this); 6656c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke fs_reg dPdx = this->result; 6666c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6676c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke ir->lod_info.grad.dPdy->accept(this); 6686c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke fs_reg dPdy = this->result; 6696c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6706c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 6716c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); 6726c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke coordinate.reg_offset++; 6736c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 6746c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke /* the slots for u and v are always present, but r is optional */ 6756c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke mlen += MAX2(ir->coordinate->type->vector_elements, 2); 6766c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6776c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke /* P = u, v, r 6786c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx = dudx, dvdx, drdx 6796c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdy = dudy, dvdy, drdy 6806c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 6813e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke * 1-arg: Does not exist. 6823e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke * 6836c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 2-arg: dudx dvdx dudy dvdy 6846c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx.x dPdx.y dPdy.x dPdy.y 6856c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * m4 m5 m6 m7 6866c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 6876c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 3-arg: dudx dvdx drdx dudy dvdy drdy 6886c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z 6896c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * m5 m6 m7 m8 m9 m10 6906c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke */ 6916c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { 6926c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); 6936c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke dPdx.reg_offset++; 6946c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 6953e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke mlen += MAX2(ir->lod_info.grad.dPdx->type->vector_elements, 2); 6966c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6976c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) { 6986c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); 6996c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke dPdy.reg_offset++; 7006c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 7013e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2); 7024eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke } else if (ir->op == ir_txs) { 7034eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke /* There's no SIMD8 resinfo message on Gen4. Use SIMD16 instead. */ 7044eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke simd16 = true; 7054eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke ir->lod_info.lod->accept(this); 7064eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result); 7074eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke mlen += 2; 708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Oh joy. gen4 doesn't have SIMD8 non-shadow-compare bias/lod 710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instructions. We'll need to do SIMD16 here. 711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 7124eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke simd16 = true; 71347b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke assert(ir->op == ir_txb || ir->op == ir_txl || ir->op == ir_txf); 714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 71607e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type), 71707e621c52329cd17b97051a26493626228d043b9Eric Anholt coordinate); 718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 72147b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke /* Initialize the rest of u/v/r with 0.0. Empirically, this seems to 72247b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke * be necessary for TXF (ld), but seems wise to do for all messages. 72347b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke */ 72447b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke for (int i = ir->coordinate->type->vector_elements; i < 3; i++) { 72547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f)); 72647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke } 72747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke 728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* lod/bias appears after u/v/r. */ 729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 6; 730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->op == ir_txb) { 732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 73747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, this->result.type), 73847b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke this->result); 739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The unused upper half. */ 743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 7444eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke } 745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 7464eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke if (simd16) { 747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Now, since we're doing simd16, the return is 2 interleaved 748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * vec4s where the odd-indexed ones are junk. We'll need to move 749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * this weirdness around to the expected layout. 750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt orig_dst = dst; 7524eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke const glsl_type *vec_type = 7534eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke glsl_type::get_instance(ir->type->base_type, 4, 1); 7544eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2)); 7554eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type) 7564eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke : BRW_REGISTER_TYPE_F; 757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 762febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TEX, dst); 763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXB, dst); 766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 768febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXL, dst); 769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txd: 771febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXD, dst); 772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 7731e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 774febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXS, dst); 7754eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke break; 7764eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke case ir_txf: 777febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXF, dst); 778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = true; 783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (simd16) { 785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < 4; i++) { 786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, orig_dst, dst); 787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt orig_dst.reg_offset++; 788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst.reg_offset += 2; 789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* gen5's sampler has slots for u, v, r, array index, then optional 796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters like shadow comparitor or LOD bias. If optional 797d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters aren't present, those base slots are optional and don't 798d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * need to be included in the message. 799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * We don't fill in the unnecessary slots regardless, which may look 801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * surprising in the disassembly. 802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 804d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, 805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int sampler) 806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen = 0; 808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 2; 809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool header_present = false; 811ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke const int vector_elements = 812ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->coordinate ? ir->coordinate->type->vector_elements : 0; 813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset) { 815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The offsets set up by the ir_texture visitor are in the 816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m1 header, so we can't go headerless. 817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = true; 819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt base_mrf--; 821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 823ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke for (int i = 0; i < vector_elements; i++) { 82407e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, 82507e621c52329cd17b97051a26493626228d043b9Eric Anholt fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type), 82607e621c52329cd17b97051a26493626228d043b9Eric Anholt coordinate); 827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 829ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += vector_elements * reg_width; 830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 8316430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && ir->op != ir_txd) { 832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->shadow_comparitor->accept(this); 835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 836d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 837d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 839d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 840d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 842febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TEX, dst); 843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 844d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 845d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 846d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 847d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 848d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 850d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXB, dst); 851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 859febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXL, dst); 860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 8612f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke case ir_txd: { 8622f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke ir->lod_info.grad.dPdx->accept(this); 8632f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke fs_reg dPdx = this->result; 8642f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8652f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke ir->lod_info.grad.dPdy->accept(this); 8662f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke fs_reg dPdy = this->result; 8672f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8682f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */ 8692f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8702f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke /** 8712f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * P = u, v, r 8722f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * dPdx = dudx, dvdx, drdx 8732f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * dPdy = dudy, dvdy, drdy 8742f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * 8752f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * Load up these values: 8762f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * - dudx dudy dvdx dvdy drdx drdy 8772f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z 8782f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke */ 8792f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { 8802f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); 8812f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke dPdx.reg_offset++; 8822f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen += reg_width; 8832f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8842f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); 8852f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke dPdy.reg_offset++; 8862f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen += reg_width; 8872f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke } 8882f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 889febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXD, dst); 8902f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke break; 8912f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke } 8921e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 893ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->lod_info.lod->accept(this); 894ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result); 895ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += reg_width; 896febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXS, dst); 897ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke break; 898ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txf: 89930be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke mlen = header_present + 4 * reg_width; 90030be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke 90130be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke ir->lod_info.lod->accept(this); 90230be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke emit(BRW_OPCODE_MOV, 90330be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD), 90430be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke this->result); 905febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXF, dst); 906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (mlen > 11) { 913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Message length >11 disallowed by hardware\n"); 914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, 921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int sampler) 922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen = 0; 924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 2; 925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool header_present = false; 927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset) { 929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The offsets set up by the ir_texture visitor are in the 930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m1 header, so we can't go headerless. 931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = true; 933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt base_mrf--; 935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 9376430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && ir->op != ir_txd) { 938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->shadow_comparitor->accept(this); 939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Set up the LOD info */ 944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 945d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 947d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 948d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 949d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 950d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 951d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 9573fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke case ir_txd: { 9583fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke if (c->dispatch_width == 16) 9593fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode."); 9603fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9613fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke ir->lod_info.grad.dPdx->accept(this); 9623fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fs_reg dPdx = this->result; 9633fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9643fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke ir->lod_info.grad.dPdy->accept(this); 9653fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fs_reg dPdy = this->result; 9663fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9673fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke /* Load dPdx and the coordinate together: 9683fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z 9693fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke */ 9703fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 97107e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate); 9723fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate.reg_offset++; 9733fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 9743fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9753fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); 9763fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke dPdx.reg_offset++; 9773fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 9783fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9793fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); 9803fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke dPdy.reg_offset++; 9813fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 9823fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 9833fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke break; 9843fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 9851e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 986ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->lod_info.lod->accept(this); 987ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result); 988ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += reg_width; 989ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke break; 990ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txf: 9910edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */ 992c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt emit(BRW_OPCODE_MOV, 993c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate); 9940edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke coordinate.reg_offset++; 9950edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 9960edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke 9970edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke ir->lod_info.lod->accept(this); 9980edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), this->result); 9990edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 10000edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke 10010edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke for (int i = 1; i < ir->coordinate->type->vector_elements; i++) { 1002c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt emit(BRW_OPCODE_MOV, 1003c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate); 10040edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke coordinate.reg_offset++; 10050edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 10060edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke } 1007d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1008d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1009d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 10100edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke /* Set up the coordinate (except for cases where it was done above) */ 10110edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf) { 10123fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 101307e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate); 10143fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate.reg_offset++; 10153fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 10163fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 1017d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1018d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1019d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Generate the SEND */ 1020d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 1021d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 1022febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst); break; 1023d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break; 1024febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst); break; 1025febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst); break; 1026febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst); break; 1027febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break; 1028d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1029d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 1030d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 1031d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1032d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1033d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (mlen > 11) { 1034d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Message length >11 disallowed by hardware\n"); 1035d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1036d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1037d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 1038d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1039d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1040d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1041d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_texture *ir) 1042d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1043d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 1044d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1045f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base); 1046f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke sampler = fp->Base.SamplerUnits[sampler]; 1047f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke 10486430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* Our hardware doesn't have a sample_d_c message, so shadow compares 10496430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke * for textureGrad/TXD need to be emulated with instructions. 10506430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke */ 10516430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke bool hw_compare_supported = ir->op != ir_txd; 10526430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && !hw_compare_supported) { 10531b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke assert(c->key.tex.compare_funcs[sampler] != GL_NONE); 10546430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */ 10551b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke if (c->key.tex.compare_funcs[sampler] == GL_ALWAYS) 10566430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke return swizzle_result(ir, fs_reg(1.0f), sampler); 10571b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke else if (c->key.tex.compare_funcs[sampler] == GL_NEVER) 10586430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke return swizzle_result(ir, fs_reg(0.0f), sampler); 10596430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 10606430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 1061ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke if (ir->coordinate) 1062ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->coordinate->accept(this); 1063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg coordinate = this->result; 1064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset != NULL) { 1066475d70d6ef5feb94efab3923e5607e625f2aee67Kenneth Graunke uint32_t offset_bits = brw_texture_offset(ir->offset->as_constant()); 1067d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1068d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Explicitly set up the message header by copying g0 to msg reg m1. */ 1069d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD), 1070512431b3575eb5f2c27d8795c5e2191047ebb5edKenneth Graunke fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD))); 1071d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Then set the offset bits in DWord 2 of the message header. */ 1073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, 1074d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, 1, 2), 1075d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt BRW_REGISTER_TYPE_UD)), 1076d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_uw(offset_bits))); 1077d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1078d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1079d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Should be lowered by do_lower_texture_projection */ 1080d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->projector); 1081d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1082d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The 965 requires the EU to do the normalization of GL rectangle 1083d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * texture coordinates. We use the program parameter state 1084d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * tracking to get the scaling factor. 1085d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 10869d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt if (intel->gen < 6 && 10879d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) { 1088d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt struct gl_program_parameter_list *params = c->fp->program.Base.Parameters; 1089d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int tokens[STATE_LENGTH] = { 1090d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt STATE_INTERNAL, 1091d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt STATE_TEXRECT_SCALE, 1092d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sampler, 1093d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 0, 1094d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 0 1095d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt }; 1096d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1097d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 1098d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("rectangle scale uniform setup not supported on 16-wide\n"); 1099d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = fs_reg(this, ir->type); 1100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.param_convert[c->prog_data.nr_params] = 1104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt PARAM_NO_CONVERT; 1105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.param_convert[c->prog_data.nr_params + 1] = 1106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt PARAM_NO_CONVERT; 1107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg scale_x = fs_reg(UNIFORM, c->prog_data.nr_params); 1109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1); 1110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt GLuint index = _mesa_add_state_reference(params, 1111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt (gl_state_index *)tokens); 1112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_index[c->prog_data.nr_params] = index; 1114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_offset[c->prog_data.nr_params] = 0; 1115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.nr_params++; 1116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_index[c->prog_data.nr_params] = index; 1117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_offset[c->prog_data.nr_params] = 1; 1118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.nr_params++; 1119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg dst = fs_reg(this, ir->coordinate->type); 1121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src = coordinate; 1122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate = dst; 1123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MUL, dst, src, scale_x); 1125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst.reg_offset++; 1126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src.reg_offset++; 1127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MUL, dst, src, scale_y); 1128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 112907e621c52329cd17b97051a26493626228d043b9Eric Anholt 113007e621c52329cd17b97051a26493626228d043b9Eric Anholt if (ir->coordinate) { 113107e621c52329cd17b97051a26493626228d043b9Eric Anholt for (int i = 0; i < MIN2(ir->coordinate->type->vector_elements, 3); i++) { 113207e621c52329cd17b97051a26493626228d043b9Eric Anholt if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) { 113307e621c52329cd17b97051a26493626228d043b9Eric Anholt fs_reg chan = coordinate; 113407e621c52329cd17b97051a26493626228d043b9Eric Anholt chan.reg_offset += i; 113507e621c52329cd17b97051a26493626228d043b9Eric Anholt 113607e621c52329cd17b97051a26493626228d043b9Eric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, chan, chan); 113707e621c52329cd17b97051a26493626228d043b9Eric Anholt inst->saturate = true; 113807e621c52329cd17b97051a26493626228d043b9Eric Anholt } 113907e621c52329cd17b97051a26493626228d043b9Eric Anholt } 114007e621c52329cd17b97051a26493626228d043b9Eric Anholt } 1141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Writemasking doesn't eliminate channels on SIMD8 texture 1143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * samples, so don't worry about them. 1144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1145b6bdcf2a908889532ef6d5eb643791176dffcb9dKenneth Graunke fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1)); 1146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 7) { 1148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit_texture_gen7(ir, dst, coordinate, sampler); 1149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (intel->gen >= 5) { 1150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit_texture_gen5(ir, dst, coordinate, sampler); 1151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit_texture_gen4(ir, dst, coordinate, sampler); 1153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* If there's an offset, we already set up m1. To avoid the implied move, 1156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * use the null register. Otherwise, we want an implied move from g0. 1157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset != NULL || !inst->header_present) 1159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->src[0] = reg_undef; 1160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt else 1161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); 1162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->sampler = sampler; 1164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 11656430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor) { 11666430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (hw_compare_supported) { 11676430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst->shadow_compare = true; 11686430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } else { 11696430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke ir->shadow_comparitor->accept(this); 11706430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke fs_reg ref = this->result; 11716430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11726430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke fs_reg value = dst; 11736430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke dst = fs_reg(this, glsl_type::vec4_type); 11746430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11756430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* FINISHME: This needs to be done pre-filtering. */ 11766430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11776430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke uint32_t conditional = 0; 11781b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke switch (c->key.tex.compare_funcs[sampler]) { 11796430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* GL_ALWAYS and GL_NEVER were handled at the top of the function */ 11806430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_LESS: conditional = BRW_CONDITIONAL_L; break; 11816430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_GREATER: conditional = BRW_CONDITIONAL_G; break; 11826430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_LEQUAL: conditional = BRW_CONDITIONAL_LE; break; 11836430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_GEQUAL: conditional = BRW_CONDITIONAL_GE; break; 11846430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_EQUAL: conditional = BRW_CONDITIONAL_EQ; break; 11856430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_NOTEQUAL: conditional = BRW_CONDITIONAL_NEQ; break; 11866430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke default: assert(!"Should not get here: bad shadow compare function"); 11876430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 11886430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11896430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* Use conditional moves to load 0 or 1 as the result */ 11906430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke this->current_annotation = "manual shadow comparison"; 11916430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke for (int i = 0; i < 4; i++) { 11926430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst = emit(BRW_OPCODE_MOV, dst, fs_reg(0.0f)); 11936430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11946430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst = emit(BRW_OPCODE_CMP, reg_null_f, ref, value); 11956430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst->conditional_mod = conditional; 11966430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11976430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst = emit(BRW_OPCODE_MOV, dst, fs_reg(1.0f)); 11986430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst->predicated = true; 11996430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 12006430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke dst.reg_offset++; 12016430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke value.reg_offset++; 12026430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 12036430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke dst.reg_offset = 0; 12046430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 12056430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 1206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 120701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke swizzle_result(ir, dst, sampler); 120801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke} 120901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke 121001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke/** 121101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * Swizzle the result of a texture result. This is necessary for 121201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons. 121301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke */ 121401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkevoid 121501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkefs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler) 121601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke{ 121701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke this->result = orig_val; 121801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke 1219c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke if (ir->op == ir_txs) 1220c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke return; 1221c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke 1222d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type == glsl_type::float_type) { 1223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Ignore DEPTH_TEXTURE_MODE swizzling. */ 1224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->sampler->type->sampler_shadow); 12251b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke } else if (c->key.tex.swizzles[sampler] != SWIZZLE_NOOP) { 122601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type); 1227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < 4; i++) { 12291b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke int swiz = GET_SWZ(c->key.tex.swizzles[sampler], i); 123001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg l = swizzled_result; 1231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset += i; 1232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (swiz == SWIZZLE_ZERO) { 1234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, fs_reg(0.0f)); 1235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (swiz == SWIZZLE_ONE) { 1236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, fs_reg(1.0f)); 1237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 123801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg r = orig_val; 12391b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke r.reg_offset += GET_SWZ(c->key.tex.swizzles[sampler], i); 1240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, r); 1241d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 124301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke this->result = swizzled_result; 1244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1245d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1248d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_swizzle *ir) 1249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->val->accept(this); 1251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg val = this->result; 1252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type->vector_elements == 1) { 1254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += ir->mask.x; 1255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg result = fs_reg(this, ir->type); 1259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = result; 1260d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < ir->type->vector_elements; i++) { 1262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg channel = val; 1263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int swiz = 0; 1264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (i) { 1266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 0: 1267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.x; 1268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 1: 1270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.y; 1271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 2: 1273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.z; 1274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 3: 1276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.w; 1277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt channel.reg_offset += swiz; 1281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, result, channel); 1282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt result.reg_offset++; 1283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1287d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_discard *ir) 1288d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->condition == NULL); /* FINISHME */ 1290d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1291d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DISCARD); 1292d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt kill_emitted = true; 1293d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1294d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_constant *ir) 1297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Set this->result to reg at the bottom of the function because some code 1299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * paths will cause this visitor to be applied to other fields. This will 1300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * cause the value stored in this->result to be modified. 1301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 1302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Make reg constant so that it doesn't get accidentally modified along the 1303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * way. Yes, I actually had this problem. :( 1304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const fs_reg reg(this, ir->type); 1306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg dst_reg = reg; 1307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type->is_array()) { 1309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(ir->type->fields.array); 1310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < ir->type->length; i++) { 1312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->array_elements[i]->accept(this); 1313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src_reg = this->result; 1314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.type = src_reg.type; 1316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned j = 0; j < size; j++) { 1317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, src_reg); 1318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src_reg.reg_offset++; 1319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->type->is_record()) { 1323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt foreach_list(node, &ir->components) { 1324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_instruction *const field = (ir_instruction *) node; 1325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(field->type); 1326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt field->accept(this); 1328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src_reg = this->result; 1329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.type = src_reg.type; 1331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned j = 0; j < size; j++) { 1332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, src_reg); 1333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src_reg.reg_offset++; 1334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(ir->type); 1339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1340d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < size; i++) { 1341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->type->base_type) { 1342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_FLOAT: 1343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.f[i])); 1344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_UINT: 1346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.u[i])); 1347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_INT: 1349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.i[i])); 1350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_BOOL: 1352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg((int)ir->value.b[i])); 1353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"Non-float/uint/int/bool constant"); 1356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = reg; 1362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1363d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_bool_to_cond_code(ir_rvalue *ir) 1366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_expression *expr = ir->as_expression(); 1368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (expr) { 1370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2]; 1371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1372d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->get_num_operands() <= 2); 1374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < expr->get_num_operands(); i++) { 1375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->operands[i]->type->is_scalar()); 1376d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt expr->operands[i]->accept(this); 1378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[i] = this->result; 137973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 138073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[i]); 1381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (expr->operation) { 1384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 1385d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1)); 1386d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_Z; 1387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 1390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_XOR, reg_null_d, op[0], op[1]); 1391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 1395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_OR, reg_null_d, op[0], op[1]); 1396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 1400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], op[1]); 1401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 1405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0.0f)); 1407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, reg_null_f, op[0]); 1409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 1414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0)); 1416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, reg_null_d, op[0]); 1418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 1423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 1424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 1425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 1426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 1427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 1428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 1429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 1430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]); 1431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = 1432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt brw_conditional_for_comparison(expr->operation); 1433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("bad cond code\n"); 1438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_AND, reg_null_d, this->result, fs_reg(1)); 1447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, reg_null_d, this->result); 1450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** 1455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Emit a gen6 IF statement with the comparison folded into the IF 1456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instruction. 1457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_if_gen6(ir_if *ir) 1460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_expression *expr = ir->condition->as_expression(); 1462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (expr) { 1464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2]; 1465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg temp; 1467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->get_num_operands() <= 2); 1469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < expr->get_num_operands(); i++) { 1470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->operands[i]->type->is_scalar()); 1471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt expr->operands[i]->accept(this); 1473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[i] = this->result; 1474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (expr->operation) { 1477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 1478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, temp, op[0], fs_reg(0)); 1479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_Z; 1480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 1483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]); 1484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 1488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = fs_reg(this, glsl_type::bool_type); 1489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_OR, temp, op[0], op[1]); 1490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0)); 1491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 1495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = fs_reg(this, glsl_type::bool_type); 1496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_AND, temp, op[0], op[1]); 1497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0)); 1498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 1502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0)); 1503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 1507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0)); 1508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 1512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 1513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 1514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 1515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 1516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 1517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 1518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 1519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]); 1520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = 1521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt brw_conditional_for_comparison(expr->operation); 1522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1525d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0)); 1526d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("bad condition\n"); 1528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->condition->accept(this); 1534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_IF, reg_null_d, this->result, fs_reg(0)); 1536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1537d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1538d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_if *ir) 1541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1543d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 154479cba4c2b17456e2b25ac555c45e1c106b4e3f6bKenneth Graunke if (intel->gen < 6 && c->dispatch_width == 16) { 1545d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Can't support (non-uniform) control flow on 16-wide\n"); 1546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Don't point the annotation at the if statement, because then it plus 1549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * the then and else blocks get printed. 1550d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->condition; 1552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen == 6) { 1554d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_if_gen6(ir); 1555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1556d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_bool_to_cond_code(ir->condition); 1557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF); 1559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 1560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 156244ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->then_instructions) { 156344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1565d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1566d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!ir->else_instructions.is_empty()) { 1570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ELSE); 1571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 157244ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->else_instructions) { 157344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1575d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ENDIF); 1581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1582d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop *ir) 1585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg counter = reg_undef; 1587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 1589d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Can't support (non-uniform) control flow on 16-wide\n"); 1590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->counter) { 1593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->counter; 1594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->counter->accept(this); 1595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt counter = *(variable_storage(ir->counter)); 1596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->from) { 1598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->from; 1599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->from->accept(this); 1600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1601d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke emit(BRW_OPCODE_MOV, counter, this->result); 1602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_DO); 1606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->to) { 1608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->to; 1609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->to->accept(this); 1610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result); 1612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = brw_conditional_for_comparison(ir->cmp); 1613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_BREAK); 1615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 1616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 161844ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->body_instructions) { 161944ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->increment) { 1626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->increment; 1627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->increment->accept(this); 1628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, counter, counter, this->result); 1629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_WHILE); 1632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop_jump *ir) 1636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->mode) { 1638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_loop_jump::jump_break: 1639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_BREAK); 1640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_loop_jump::jump_continue: 1642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_CONTINUE); 1643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_call *ir) 1649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME"); 1651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_return *ir) 1655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME"); 1657d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1658d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function *ir) 1661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 1663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 1664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (strcmp(ir->name, "main") == 0) { 1666d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const ir_function_signature *sig; 1667d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt exec_list empty; 1668d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1669d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sig = ir->matching_signature(&empty); 1670d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1671d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(sig); 1672d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 167344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &sig->body) { 167444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1675d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1676d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1680d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1681d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function_signature *ir) 1684d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1685d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1686d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt (void)ir; 1687d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 1690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit(fs_inst inst) 1691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *list_inst = new(mem_ctx) fs_inst; 1693d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *list_inst = inst; 1694d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1695d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (force_uncompressed_stack > 0) 1696d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->force_uncompressed = true; 1697d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt else if (force_sechalf_stack > 0) 1698d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->force_sechalf = true; 1699d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->annotation = this->current_annotation; 1701d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->ir = this->base_ir; 1702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->instructions.push_tail(list_inst); 1704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return list_inst; 1706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits a dummy fragment shader consisting of magenta for bringup purposes. */ 1709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_dummy_fs() 1711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Everyone's favorite color. */ 1713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 2), fs_reg(1.0f)); 1714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 3), fs_reg(0.0f)); 1715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 4), fs_reg(1.0f)); 1716d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 5), fs_reg(0.0f)); 1717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *write; 1719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0)); 17206750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky write->base_mrf = 2; 1721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* The register location here is relative to the start of the URB 1724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * data. It will get adjusted to be a real location before 1725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * generate_code() time. 1726d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1727d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtstruct brw_reg 1728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::interp_reg(int location, int channel) 1729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int regnr = urb_setup[location] * 2 + channel / 2; 1731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int stride = (channel & 1) * 4; 1732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(urb_setup[location] != -1); 1734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return brw_vec1_grf(regnr, stride); 1736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */ 1739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen4() 1741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel centers"; 1743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x = fs_reg(this, glsl_type::uint_type); 1744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y = fs_reg(this, glsl_type::uint_type); 1745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x.type = BRW_REGISTER_TYPE_UW; 1746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y.type = BRW_REGISTER_TYPE_UW; 1747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_PIXEL_X, this->pixel_x); 1749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_PIXEL_Y, this->pixel_y); 1750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel deltas from v0"; 1752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (brw->has_pln) { 1753e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1754e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry fs_reg(this, glsl_type::vec2_type); 1755e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1756e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC]; 1757e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg_offset++; 1758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1759e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1760e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry fs_reg(this, glsl_type::float_type); 1761e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1762e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry fs_reg(this, glsl_type::float_type); 1763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1764e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry emit(BRW_OPCODE_ADD, this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0)))); 1766e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry emit(BRW_OPCODE_ADD, this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1)))); 1768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pos.w and 1/pos.w"; 1770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Compute wpos.w. It's always in our setup, since it's needed to 1771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * interpolate the other attributes. 1772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->wpos_w = fs_reg(this, glsl_type::float_type); 1774e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry emit(FS_OPCODE_LINTERP, wpos_w, 1775e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1776e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt interp_reg(FRAG_ATTRIB_WPOS, 3)); 1778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Compute the pixel 1/W value from wpos.w. */ 1779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_w = fs_reg(this, glsl_type::float_type); 178065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w); 1781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */ 1785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen6() 1787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW); 1789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* If the pixel centers end up used, the setup is the same as for gen4. */ 1791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel centers"; 1792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg int_pixel_x = fs_reg(this, glsl_type::uint_type); 1793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg int_pixel_y = fs_reg(this, glsl_type::uint_type); 1794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_x.type = BRW_REGISTER_TYPE_UW; 1795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_y.type = BRW_REGISTER_TYPE_UW; 1796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, 1797d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_x, 1798d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)), 1799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_v(0x10101010))); 1800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, 1801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_y, 1802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)), 1803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_v(0x11001100))); 1804d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* As of gen6, we can no longer mix float and int sources. We have 1806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * to turn the integer pixel centers into floats for their actual 1807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * use. 1808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x = fs_reg(this, glsl_type::float_type); 1810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y = fs_reg(this, glsl_type::float_type); 1811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->pixel_x, int_pixel_x); 1812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->pixel_y, int_pixel_y); 1813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pos.w"; 1815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0)); 1816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->wpos_w = fs_reg(this, glsl_type::float_type); 181765b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w); 1818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1819e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry for (int i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) { 1820e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry uint8_t reg = c->barycentric_coord_reg[i]; 1821e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[i] = fs_reg(brw_vec8_grf(reg, 0)); 1822e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[i] = fs_reg(brw_vec8_grf(reg + 1, 0)); 1823e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry } 1824d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1825d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1826d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 18296d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholtfs_visitor::emit_color_write(int target, int index, int first_color_mrf) 1830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 18324fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt fs_inst *inst; 18336d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt fs_reg color = outputs[target]; 18346d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt fs_reg mrf; 18356d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt 18366d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* If there's no color data to be written, skip it. */ 18376d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt if (color.file == BAD_FILE) 18386d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt return; 18396d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt 18406d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt color.reg_offset += index; 1841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 184283df7fbe62be2798d557142a47e01af86ec9e2e2Kenneth Graunke if (c->dispatch_width == 8 || intel->gen >= 6) { 1843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* SIMD8 write looks like: 1844d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1845d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: r1 1846d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: g0 1847d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: g1 1848d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 1849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * gen6 SIMD16 DP write looks like: 1850d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: r1 1852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: g0 1853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: g1 1854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 4: b0 1855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 5: b1 1856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 6: a0 1857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 7: a1 1858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 18594fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, 1860e988d816e16f9c0844424472d689486a833931c3Eric Anholt fs_reg(MRF, first_color_mrf + index * reg_width, color.type), 18614fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18624fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* pre-gen6 SIMD16 single source DP write looks like: 1865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: g0 1867d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: b0 1868d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: a0 1869d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 4: r1 1870d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 5: g1 1871d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 6: b1 1872d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 7: a1 1873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (brw->has_compr4) { 1875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* By setting the high bit of the MRF register number, we 1876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * indicate that we want COMPR4 mode - instead of doing the 1877d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * usual destination + 1 for the second half we get 1878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * destination + 4. 1879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 18804fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, 1881e988d816e16f9c0844424472d689486a833931c3Eric Anholt fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index, 1882e988d816e16f9c0844424472d689486a833931c3Eric Anholt color.type), 18834fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18844fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_uncompressed(); 1887e988d816e16f9c0844424472d689486a833931c3Eric Anholt inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index, 1888e988d816e16f9c0844424472d689486a833931c3Eric Anholt color.type), 18894fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18904fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_uncompressed(); 1892d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_sechalf(); 1894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.sechalf = true; 1895e988d816e16f9c0844424472d689486a833931c3Eric Anholt inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4, 1896e988d816e16f9c0844424472d689486a833931c3Eric Anholt color.type), 18974fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18984fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_sechalf(); 1900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.sechalf = false; 1901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_fb_writes() 1907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "FB write header"; 19092e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke bool header_present = true; 1910eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke int base_mrf = 2; 1911eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke int nr = base_mrf; 1912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 1913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6 && 1915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt !this->kill_emitted && 1916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->key.nr_color_regions == 1) { 1917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = false; 1918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (header_present) { 19216750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky /* m2, m3 header */ 1922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += 2; 1923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->aa_dest_stencil_reg) { 1926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_uncompressed(); 1927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr++), 1928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->aa_dest_stencil_reg, 0))); 1929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_uncompressed(); 1930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Reserve space for color. It'll be filled in per MRT below. */ 1933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int color_mrf = nr; 1934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += 4 * reg_width; 1935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->source_depth_to_render_target) { 1937d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen == 6 && c->dispatch_width == 16) { 1938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* For outputting oDepth on gen6, SIMD8 writes have to be 1939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * used. This would require 8-wide moves of each half to 1940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * message regs, kind of like pre-gen5 SIMD16 FB writes. 1941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Just bail on doing so for now. 1942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Missing support for simd16 depth writes on gen6\n"); 1944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1945d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->computes_depth) { 1947d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Hand over gl_FragDepth. */ 1948d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(this->frag_depth); 1949d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg depth = *(variable_storage(this->frag_depth)); 1950d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1951d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), depth); 1952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Pass through the payload depth. */ 1954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), 1955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->source_depth_reg, 0))); 1956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1957d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += reg_width; 1958d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1960d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dest_depth_reg) { 1961d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), 1962d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->dest_depth_reg, 0))); 1963d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += reg_width; 1964d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1965d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1966d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int target = 0; target < c->key.nr_color_regions; target++) { 1967d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = ralloc_asprintf(this->mem_ctx, 1968d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt "FB write target %d", 1969d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt target); 19706d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt for (int i = 0; i < 4; i++) 19716d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt emit_color_write(target, i, color_mrf); 1972d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(FS_OPCODE_FB_WRITE); 1974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->target = target; 1975eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->base_mrf = base_mrf; 1976eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->mlen = nr - base_mrf; 1977d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (target == c->key.nr_color_regions - 1) 1978d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->eot = true; 1979d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1980d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1981d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1982d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->key.nr_color_regions == 0) { 19836d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt if (c->key.alpha_test) { 1984d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* If the alpha test is enabled but there's no color buffer, 1985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * we still need to send alpha out the pipeline to our null 1986d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * renderbuffer. 1987d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 19886d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt emit_color_write(0, 3, color_mrf); 1989d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1990d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1991d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(FS_OPCODE_FB_WRITE); 1992eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->base_mrf = base_mrf; 1993eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->mlen = nr - base_mrf; 1994d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->eot = true; 1995d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1996d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1997d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1998d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1999d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 200073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 200173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtvoid 200273b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtfs_visitor::resolve_ud_negate(fs_reg *reg) 200373b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt{ 200473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt if (reg->type != BRW_REGISTER_TYPE_UD || 200573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt !reg->negate) 200673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt return; 200773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 200873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt fs_reg temp = fs_reg(this, glsl_type::uint_type); 200973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt emit(BRW_OPCODE_MOV, temp, *reg); 201073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt *reg = temp; 201173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt} 2012