brw_fs_visitor.cpp revision 79cba4c2b17456e2b25ac555c45e1c106b4e3f6b
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 (strcmp(ir->name, "gl_FragColor") == 0) { 62d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->frag_color = ir; 63d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (strcmp(ir->name, "gl_FragData") == 0) { 64d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->frag_data = ir; 65d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (strcmp(ir->name, "gl_FragDepth") == 0) { 66d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->frag_depth = ir; 67d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 68d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 69d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->mode == ir_var_in) { 70d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!strcmp(ir->name, "gl_FragCoord")) { 71d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_fragcoord_interpolation(ir); 72d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (!strcmp(ir->name, "gl_FrontFacing")) { 73d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_frontfacing_interpolation(ir); 74d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 75d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_general_interpolation(ir); 76d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 77d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(reg); 78d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt hash_table_insert(this->variable_ht, reg, ir); 79d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 80d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 81d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 82d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->mode == ir_var_uniform) { 83d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int param_index = c->prog_data.nr_params; 84d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 85d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 86d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!variable_storage(ir)) { 87d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Failed to find uniform '%s' in 16-wide\n", ir->name); 88d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 89d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 90d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 91d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 92d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!strncmp(ir->name, "gl_", 3)) { 93d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt setup_builtin_uniform_values(ir); 94d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 95d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt setup_uniform_values(ir->location, ir->type); 96d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 97d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 98d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index); 99d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg->type = brw_type_for_base_type(ir->type); 100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!reg) 103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = new(this->mem_ctx) fs_reg(this, ir->type); 104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt hash_table_insert(this->variable_ht, reg, ir); 106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_variable *ir) 110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg *reg = variable_storage(ir->var); 112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = *reg; 113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_record *ir) 117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const glsl_type *struct_type = ir->record->type; 119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->record->accept(this); 121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt unsigned int offset = 0; 123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < struct_type->length; i++) { 124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt offset += type_size(struct_type->fields.structure[i].type); 127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += offset; 129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.type = brw_type_for_base_type(ir->type); 130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_array *ir) 134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_constant *index; 136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int element_size; 137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->array->accept(this); 139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt index = ir->array_index->as_constant(); 140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt element_size = type_size(ir->type); 142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.type = brw_type_for_base_type(ir->type); 143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (index) { 145b76378d46a211521582cfab56dc05031a57502a6Eric Anholt assert(this->result.file == UNIFORM || this->result.file == GRF); 146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += index->value.i[0] * element_size; 147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME: non-constant array element"); 149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* Instruction selection: Produce a MOV.sat instead of 153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * MIN(MAX(val, 0), 1) when possible. 154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtbool 156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::try_emit_saturate(ir_expression *ir) 157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_rvalue *sat_val = ir->as_rvalue_to_saturate(); 159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!sat_val) 161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return false; 162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sat_val->accept(this); 164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src = this->result; 165d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 166d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = fs_reg(this, ir->type); 167d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, this->result, src); 168d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->saturate = true; 169d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 170d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return true; 171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 174d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_expression *ir) 175d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 176d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt unsigned int operand; 177d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2], temp; 178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->get_num_operands() <= 2); 181d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 182d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (try_emit_saturate(ir)) 183d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->operands[operand]->accept(this); 187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (this->result.file == BAD_FILE) { 188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_print_visitor v; 189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Failed to get tree for expression operand:\n"); 190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->operands[operand]->accept(&v); 191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[operand] = this->result; 193d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Matrix expression operands should have been broken down to vector 195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * operations already. 196d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->operands[operand]->type->is_matrix()); 198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* And then those vector operands should have been broken down to scalar. 199d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 200d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->operands[operand]->type->is_vector()); 201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 203d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke /* Storage for our result. If our result goes into an assignment, it will 204d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke * just get copy-propagated out, so no worries. 205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 206d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke this->result = fs_reg(this, ir->type); 207d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 208d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->operation) { 209d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Note that BRW_OPCODE_NOT is not appropriate here, since it is 211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * ones complement of the whole register, not just bit 0. 212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_XOR, this->result, op[0], fs_reg(1)); 214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_neg: 216d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = !op[0].negate; 217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = op[0]; 218d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_abs: 220d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].abs = true; 221d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = false; 222d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = op[0]; 223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sign: 225d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = fs_reg(this, ir->type); 226d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f)); 228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)); 230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_G; 231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(1.0f)); 232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)); 235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f)); 237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 238d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 239d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_rcp: 24165b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->result, op[0]); 242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 243d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_exp2: 24565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_EXP2, this->result, op[0]); 246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_log2: 24865b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_LOG2, this->result, op[0]); 249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_exp: 251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_log: 252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sin: 255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sin_reduced: 25665b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_SIN, this->result, op[0]); 257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_cos: 259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_cos_reduced: 26065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_COS, this->result, op[0]); 261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_dFdx: 264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DDX, this->result, op[0]); 265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_dFdy: 267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DDY, this->result, op[0]); 268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_add: 271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, this->result, op[0], op[1]); 272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_sub: 274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by ir_sub_to_add_neg"); 275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_mul: 2783f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt if (ir->type->is_integer()) { 2793f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt /* For integer multiplication, the MUL uses the low 16 bits 2803f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * of one of the operands (src0 on gen6, src1 on gen7). The 2813f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * MACH accumulates in the contribution of the upper 16 bits 2823f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * of that operand. 2833f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * 2843f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * FINISHME: Emit just the MUL if we know an operand is small 2853f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * enough. 2863f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt */ 2873f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D); 2883f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt 2893f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MUL, acc, op[0], op[1]); 2903f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]); 2913f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MOV, this->result, fs_reg(acc)); 2923f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt } else { 2933f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MUL, this->result, op[0], op[1]); 2943f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt } 295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_div: 297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_mod: 300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = this->result; 312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* original gen4 does implicit conversion before comparison. */ 313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen < 5) 314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp.type = op[0].type; 315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]); 317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = brw_conditional_for_comparison(ir->operation); 318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)); 319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_XOR, this->result, op[0], op[1]); 323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_OR, this->result, op[0], op[1]); 327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_AND, this->result, op[0], op[1]); 331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_dot: 334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_any: 335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by brw_fs_channel_expressions"); 336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_noise: 339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by lower_noise"); 340d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_quadop_vector: 343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by lower_quadop_vector"); 344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sqrt: 34765b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_SQRT, this->result, op[0]); 348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_rsq: 35165b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RSQ, this->result, op[0]); 352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 354b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke case ir_unop_i2u: 355b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke op[0].type = BRW_REGISTER_TYPE_UD; 356b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke this->result = op[0]; 357b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke break; 358b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke case ir_unop_u2i: 359b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke op[0].type = BRW_REGISTER_TYPE_D; 360b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke this->result = op[0]; 361b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke break; 362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2f: 3634bc5bfb641bce931bf35f0e78ec2b44263d152baKenneth Graunke case ir_unop_u2f: 364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_b2f: 365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_b2i: 366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2i: 367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->result, op[0]); 368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = this->result; 372d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* original gen4 does implicit conversion before comparison. */ 373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen < 5) 374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp.type = op[0].type; 375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 376d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, temp, op[0], fs_reg(0.0f)); 377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1)); 379d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 380d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_trunc: 382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_RNDZ, this->result, op[0]); 383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_ceil: 385d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = !op[0].negate; 386d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_RNDD, this->result, op[0]); 387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.negate = true; 388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_floor: 390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_RNDD, this->result, op[0]); 391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_fract: 393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_FRC, this->result, op[0]); 394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_round_even: 396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_RNDE, this->result, op[0]); 397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_min: 400c331b3123ecda127919458e24848b7c1596525acEric Anholt if (intel->gen >= 6) { 401c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 402c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 403c331b3123ecda127919458e24848b7c1596525acEric Anholt } else { 404c331b3123ecda127919458e24848b7c1596525acEric Anholt /* Unalias the destination */ 405c331b3123ecda127919458e24848b7c1596525acEric Anholt this->result = fs_reg(this, ir->type); 406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 407c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); 408c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 410c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 411c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->predicated = true; 412c331b3123ecda127919458e24848b7c1596525acEric Anholt } 413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_max: 415c331b3123ecda127919458e24848b7c1596525acEric Anholt if (intel->gen >= 6) { 416c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 417c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_GE; 418c331b3123ecda127919458e24848b7c1596525acEric Anholt } else { 419c331b3123ecda127919458e24848b7c1596525acEric Anholt /* Unalias the destination */ 420c331b3123ecda127919458e24848b7c1596525acEric Anholt this->result = fs_reg(this, ir->type); 421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 422c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); 423c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_G; 424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 425c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 426c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->predicated = true; 427c331b3123ecda127919458e24848b7c1596525acEric Anholt } 428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_pow: 43165b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]); 432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_bit_not: 435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_NOT, this->result, op[0]); 436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_and: 438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, this->result, op[0], op[1]); 439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_xor: 441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_XOR, this->result, op[0], op[1]); 442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_or: 444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_OR, this->result, op[0], op[1]); 445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lshift: 448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_rshift: 449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"GLSL 1.30 features unsupported"); 450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r, 456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const glsl_type *type, bool predicated) 457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (type->base_type) { 459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_FLOAT: 460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_UINT: 461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_INT: 462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_BOOL: 463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->components(); i++) { 464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.type = brw_type_for_base_type(type); 465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.type = brw_type_for_base_type(type); 466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (predicated || !l.equals(&r)) { 468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, l, r); 469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = predicated; 470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset++; 473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.reg_offset++; 474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_ARRAY: 477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, type->fields.array, predicated); 479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_STRUCT: 483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, type->fields.structure[i].type, 485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt predicated); 486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_SAMPLER: 490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 498dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke/* If the RHS processing resulted in an instruction generating a 499dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * temporary value, and it would be easy to rewrite the instruction to 500dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * generate its result right into the LHS instead, do so. This ends 501dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * up reliably removing instructions where it can be tricky to do so 502dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * later without real UD chain information. 503dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke */ 504dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkebool 505dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkefs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir, 506dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_reg dst, 507dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_reg src, 508dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *pre_rhs_inst, 509dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *last_rhs_inst) 510dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke{ 511dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (pre_rhs_inst == last_rhs_inst) 512dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; /* No instructions generated to work with. */ 513dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 514dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Only attempt if we're doing a direct assignment. */ 515dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (ir->condition || 516dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke !(ir->lhs->type->is_scalar() || 517dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke (ir->lhs->type->is_vector() && 518dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1))) 519dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; 520dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 521dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Make sure the last instruction generated our source reg. */ 522dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (last_rhs_inst->predicated || 523dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke last_rhs_inst->force_uncompressed || 524dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke last_rhs_inst->force_sechalf || 525dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke !src.equals(&last_rhs_inst->dst)) 526dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; 527dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 528dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Success! Rewrite the instruction. */ 529dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke last_rhs_inst->dst = dst; 530dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 531dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return true; 532dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke} 533dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_assignment *ir) 536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 537eb86bb55f5faef67c21604db19210c6788592679Kenneth Graunke fs_reg l, r; 538d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* FINISHME: arrays on the lhs */ 541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lhs->accept(this); 542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l = this->result; 543d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 544dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail(); 545dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->rhs->accept(this); 547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r = this->result; 548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 549dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail(); 550dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(l.file != BAD_FILE); 552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(r.file != BAD_FILE); 553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 554dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst)) 555dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return; 556dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->condition) { 558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_bool_to_cond_code(ir->condition); 559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->lhs->type->is_scalar() || 562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lhs->type->is_vector()) { 563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->lhs->type->vector_elements; i++) { 564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->write_mask & (1 << i)) { 565d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke inst = emit(BRW_OPCODE_MOV, l, r); 566d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke if (ir->condition) 567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.reg_offset++; 569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset++; 571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, ir->lhs->type, ir->condition != NULL); 574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, 579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int sampler) 580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen; 582d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 1; 583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool simd16 = false; 584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg orig_dst; 585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* g0 header. */ 587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = 1; 588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 5896430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && ir->op != ir_txd) { 590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, 592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(MRF, base_mrf + mlen + i), coordinate); 593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) 594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->saturate = true; 595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* gen4's SIMD8 sampler always has the slots for u,v,r present. */ 599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 3; 600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->op == ir_tex) { 602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* There's no plain shadow compare message, so we use shadow 603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * compare with a bias of 0.0. 604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f)); 606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_txb) { 608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->op == ir_txl); 613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 618d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->shadow_comparitor->accept(this); 619d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_tex) { 622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), 624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate); 625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) 626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->saturate = true; 627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* gen4's SIMD8 sampler always has the slots for u,v,r present. */ 630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 3; 631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_txd) { 6326c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke ir->lod_info.grad.dPdx->accept(this); 6336c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke fs_reg dPdx = this->result; 6346c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6356c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke ir->lod_info.grad.dPdy->accept(this); 6366c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke fs_reg dPdy = this->result; 6376c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6386c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 6396c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); 6406c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke coordinate.reg_offset++; 6416c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 6426c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke /* the slots for u and v are always present, but r is optional */ 6436c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke mlen += MAX2(ir->coordinate->type->vector_elements, 2); 6446c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6456c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke /* P = u, v, r 6466c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx = dudx, dvdx, drdx 6476c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdy = dudy, dvdy, drdy 6486c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 6493e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke * 1-arg: Does not exist. 6503e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke * 6516c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 2-arg: dudx dvdx dudy dvdy 6526c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx.x dPdx.y dPdy.x dPdy.y 6536c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * m4 m5 m6 m7 6546c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 6556c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 3-arg: dudx dvdx drdx dudy dvdy drdy 6566c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z 6576c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * m5 m6 m7 m8 m9 m10 6586c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke */ 6596c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { 6606c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); 6616c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke dPdx.reg_offset++; 6626c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 6633e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke mlen += MAX2(ir->lod_info.grad.dPdx->type->vector_elements, 2); 6646c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 6656c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) { 6666c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); 6676c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke dPdy.reg_offset++; 6686c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 6693e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2); 6704eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke } else if (ir->op == ir_txs) { 6714eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke /* There's no SIMD8 resinfo message on Gen4. Use SIMD16 instead. */ 6724eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke simd16 = true; 6734eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke ir->lod_info.lod->accept(this); 6744eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result); 6754eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke mlen += 2; 676d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Oh joy. gen4 doesn't have SIMD8 non-shadow-compare bias/lod 678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instructions. We'll need to do SIMD16 here. 679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 6804eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke simd16 = true; 68147b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke assert(ir->op == ir_txb || ir->op == ir_txl || ir->op == ir_txf); 682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 684d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, 68547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke base_mrf + mlen + i * 2, 68647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke coordinate.type), 687d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate); 688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) 689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->saturate = true; 690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 69347b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke /* Initialize the rest of u/v/r with 0.0. Empirically, this seems to 69447b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke * be necessary for TXF (ld), but seems wise to do for all messages. 69547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke */ 69647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke for (int i = ir->coordinate->type->vector_elements; i < 3; i++) { 69747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f)); 69847b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke } 69947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke 700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* lod/bias appears after u/v/r. */ 701d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 6; 702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->op == ir_txb) { 704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 70947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, this->result.type), 71047b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke this->result); 711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The unused upper half. */ 715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 7164eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke } 717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 7184eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke if (simd16) { 719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Now, since we're doing simd16, the return is 2 interleaved 720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * vec4s where the odd-indexed ones are junk. We'll need to move 721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * this weirdness around to the expected layout. 722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt orig_dst = dst; 7244eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke const glsl_type *vec_type = 7254eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke glsl_type::get_instance(ir->type->base_type, 4, 1); 7264eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2)); 7274eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type) 7284eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke : BRW_REGISTER_TYPE_F; 729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TEX, dst); 735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXB, dst); 738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXL, dst); 741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txd: 743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXD, dst); 744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 7451e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 7464eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke inst = emit(FS_OPCODE_TXS, dst); 7474eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke break; 7484eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke case ir_txf: 74947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke inst = emit(FS_OPCODE_TXF, dst); 750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 754d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = true; 755d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (simd16) { 757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < 4; i++) { 758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, orig_dst, dst); 759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt orig_dst.reg_offset++; 760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst.reg_offset += 2; 761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* gen5's sampler has slots for u, v, r, array index, then optional 768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters like shadow comparitor or LOD bias. If optional 769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters aren't present, those base slots are optional and don't 770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * need to be included in the message. 771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * We don't fill in the unnecessary slots regardless, which may look 773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * surprising in the disassembly. 774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 775d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 776d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, 777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int sampler) 778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen = 0; 780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 2; 781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool header_present = false; 783ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke const int vector_elements = 784ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->coordinate ? ir->coordinate->type->vector_elements : 0; 785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset) { 787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The offsets set up by the ir_texture visitor are in the 788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m1 header, so we can't go headerless. 789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = true; 791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt base_mrf--; 793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 795ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke for (int i = 0; i < vector_elements; i++) { 796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, 79730be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke fs_reg(MRF, base_mrf + mlen + i * reg_width, 79830be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke coordinate.type), 799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate); 800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) 801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->saturate = true; 802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 804ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += vector_elements * reg_width; 805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 8066430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && ir->op != ir_txd) { 807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->shadow_comparitor->accept(this); 810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TEX, dst); 818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 823d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 824d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 825d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXB, dst); 826d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 829d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXL, dst); 835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 8362f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke case ir_txd: { 8372f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke ir->lod_info.grad.dPdx->accept(this); 8382f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke fs_reg dPdx = this->result; 8392f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8402f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke ir->lod_info.grad.dPdy->accept(this); 8412f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke fs_reg dPdy = this->result; 8422f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8432f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */ 8442f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8452f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke /** 8462f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * P = u, v, r 8472f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * dPdx = dudx, dvdx, drdx 8482f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * dPdy = dudy, dvdy, drdy 8492f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * 8502f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * Load up these values: 8512f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * - dudx dudy dvdx dvdy drdx drdy 8522f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z 8532f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke */ 8542f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { 8552f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); 8562f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke dPdx.reg_offset++; 8572f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen += reg_width; 8582f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8592f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); 8602f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke dPdy.reg_offset++; 8612f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen += reg_width; 8622f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke } 8632f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 8642f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke inst = emit(FS_OPCODE_TXD, dst); 8652f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke break; 8662f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke } 8671e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 868ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->lod_info.lod->accept(this); 869ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result); 870ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += reg_width; 871ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke inst = emit(FS_OPCODE_TXS, dst); 872ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke break; 873ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txf: 87430be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke mlen = header_present + 4 * reg_width; 87530be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke 87630be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke ir->lod_info.lod->accept(this); 87730be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke emit(BRW_OPCODE_MOV, 87830be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD), 87930be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke this->result); 88030be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke inst = emit(FS_OPCODE_TXF, dst); 881d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 882d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 883d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 884d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 887d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (mlen > 11) { 888d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Message length >11 disallowed by hardware\n"); 889d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 890d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 892d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, 896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int sampler) 897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen = 0; 899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 2; 900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool header_present = false; 902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset) { 904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The offsets set up by the ir_texture visitor are in the 905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m1 header, so we can't go headerless. 906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = true; 908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt base_mrf--; 910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 9126430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && ir->op != ir_txd) { 913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->shadow_comparitor->accept(this); 914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Set up the LOD info */ 919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.bias->accept(this); 924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lod_info.lod->accept(this); 929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); 930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 9323fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke case ir_txd: { 9333fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke if (c->dispatch_width == 16) 9343fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode."); 9353fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9363fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke ir->lod_info.grad.dPdx->accept(this); 9373fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fs_reg dPdx = this->result; 9383fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9393fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke ir->lod_info.grad.dPdy->accept(this); 9403fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fs_reg dPdy = this->result; 9413fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9423fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke /* Load dPdx and the coordinate together: 9433fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z 9443fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke */ 9453fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 9463fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), 9473fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate); 9483fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) 9493fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke inst->saturate = true; 9503fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate.reg_offset++; 9513fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 9523fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9533fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); 9543fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke dPdx.reg_offset++; 9553fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 9563fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 9573fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); 9583fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke dPdy.reg_offset++; 9593fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 9603fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 9613fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke break; 9623fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 9631e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 964ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->lod_info.lod->accept(this); 965ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result); 966ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += reg_width; 967ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke break; 968ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txf: 9690edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */ 970c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt emit(BRW_OPCODE_MOV, 971c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate); 9720edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke coordinate.reg_offset++; 9730edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 9740edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke 9750edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke ir->lod_info.lod->accept(this); 9760edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), this->result); 9770edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 9780edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke 9790edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke for (int i = 1; i < ir->coordinate->type->vector_elements; i++) { 980c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt emit(BRW_OPCODE_MOV, 981c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate); 9820edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke coordinate.reg_offset++; 9830edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 9840edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke } 985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 986d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 987d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 9880edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke /* Set up the coordinate (except for cases where it was done above) */ 9890edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf) { 9903fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 9913fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), 9923fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate); 9933fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) 9943fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke inst->saturate = true; 9953fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate.reg_offset++; 9963fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 9973fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 998d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 999d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1000d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Generate the SEND */ 1001d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 1002d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 1003d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: inst = emit(FS_OPCODE_TEX, dst); break; 1004d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break; 1005d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: inst = emit(FS_OPCODE_TXL, dst); break; 1006d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txd: inst = emit(FS_OPCODE_TXD, dst); break; 10070edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke case ir_txf: inst = emit(FS_OPCODE_TXF, dst); break; 1008ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txs: inst = emit(FS_OPCODE_TXS, dst); break; 1009d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1010d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 1011d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 1012d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1013d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1014d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (mlen > 11) { 1015d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Message length >11 disallowed by hardware\n"); 1016d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1017d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1018d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 1019d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1020d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1021d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1022d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_texture *ir) 1023d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1024d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 1025d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1026f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base); 1027f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke sampler = fp->Base.SamplerUnits[sampler]; 1028f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke 10296430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* Our hardware doesn't have a sample_d_c message, so shadow compares 10306430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke * for textureGrad/TXD need to be emulated with instructions. 10316430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke */ 10326430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke bool hw_compare_supported = ir->op != ir_txd; 10336430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor && !hw_compare_supported) { 10346430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke assert(c->key.compare_funcs[sampler] != GL_NONE); 10356430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */ 10366430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (c->key.compare_funcs[sampler] == GL_ALWAYS) 10376430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke return swizzle_result(ir, fs_reg(1.0f), sampler); 10386430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke else if (c->key.compare_funcs[sampler] == GL_NEVER) 10396430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke return swizzle_result(ir, fs_reg(0.0f), sampler); 10406430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 10416430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 1042ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke if (ir->coordinate) 1043ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->coordinate->accept(this); 1044d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg coordinate = this->result; 1045d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1046d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset != NULL) { 1047d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_constant *offset = ir->offset->as_constant(); 1048d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(offset != NULL); 1049d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1050d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt signed char offsets[3]; 1051d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < ir->offset->type->vector_elements; i++) 1052d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt offsets[i] = (signed char) offset->value.i[i]; 1053d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1054d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Combine all three offsets into a single unsigned dword: 1055d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 1056d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * bits 11:8 - U Offset (X component) 1057d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * bits 7:4 - V Offset (Y component) 1058d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * bits 3:0 - R Offset (Z component) 1059d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1060d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt unsigned offset_bits = 0; 1061d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < ir->offset->type->vector_elements; i++) { 1062d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned shift = 4 * (2 - i); 1063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt offset_bits |= (offsets[i] << shift) & (0xF << shift); 1064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1066d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Explicitly set up the message header by copying g0 to msg reg m1. */ 1067d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD), 1068d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(GRF, 0, BRW_REGISTER_TYPE_UD)); 1069d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1070d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Then set the offset bits in DWord 2 of the message header. */ 1071d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, 1072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, 1, 2), 1073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt BRW_REGISTER_TYPE_UD)), 1074d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_uw(offset_bits))); 1075d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1076d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1077d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Should be lowered by do_lower_texture_projection */ 1078d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->projector); 1079d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1080d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The 965 requires the EU to do the normalization of GL rectangle 1081d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * texture coordinates. We use the program parameter state 1082d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * tracking to get the scaling factor. 1083d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 10849d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt if (intel->gen < 6 && 10859d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) { 1086d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt struct gl_program_parameter_list *params = c->fp->program.Base.Parameters; 1087d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int tokens[STATE_LENGTH] = { 1088d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt STATE_INTERNAL, 1089d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt STATE_TEXRECT_SCALE, 1090d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sampler, 1091d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 0, 1092d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 0 1093d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt }; 1094d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1095d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 1096d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("rectangle scale uniform setup not supported on 16-wide\n"); 1097d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = fs_reg(this, ir->type); 1098d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1099d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.param_convert[c->prog_data.nr_params] = 1102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt PARAM_NO_CONVERT; 1103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.param_convert[c->prog_data.nr_params + 1] = 1104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt PARAM_NO_CONVERT; 1105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg scale_x = fs_reg(UNIFORM, c->prog_data.nr_params); 1107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1); 1108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt GLuint index = _mesa_add_state_reference(params, 1109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt (gl_state_index *)tokens); 1110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_index[c->prog_data.nr_params] = index; 1112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_offset[c->prog_data.nr_params] = 0; 1113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.nr_params++; 1114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_index[c->prog_data.nr_params] = index; 1115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_offset[c->prog_data.nr_params] = 1; 1116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.nr_params++; 1117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg dst = fs_reg(this, ir->coordinate->type); 1119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src = coordinate; 1120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate = dst; 1121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MUL, dst, src, scale_x); 1123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst.reg_offset++; 1124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src.reg_offset++; 1125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MUL, dst, src, scale_y); 1126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Writemasking doesn't eliminate channels on SIMD8 texture 1129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * samples, so don't worry about them. 1130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1131b6bdcf2a908889532ef6d5eb643791176dffcb9dKenneth Graunke fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1)); 1132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 7) { 1134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit_texture_gen7(ir, dst, coordinate, sampler); 1135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (intel->gen >= 5) { 1136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit_texture_gen5(ir, dst, coordinate, sampler); 1137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit_texture_gen4(ir, dst, coordinate, sampler); 1139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* If there's an offset, we already set up m1. To avoid the implied move, 1142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * use the null register. Otherwise, we want an implied move from g0. 1143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->offset != NULL || !inst->header_present) 1145d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->src[0] = reg_undef; 1146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt else 1147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); 1148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->sampler = sampler; 1150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 11516430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (ir->shadow_comparitor) { 11526430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke if (hw_compare_supported) { 11536430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst->shadow_compare = true; 11546430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } else { 11556430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke ir->shadow_comparitor->accept(this); 11566430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke fs_reg ref = this->result; 11576430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11586430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke fs_reg value = dst; 11596430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke dst = fs_reg(this, glsl_type::vec4_type); 11606430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11616430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* FINISHME: This needs to be done pre-filtering. */ 11626430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11636430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke uint32_t conditional = 0; 11646430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke switch (c->key.compare_funcs[sampler]) { 11656430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* GL_ALWAYS and GL_NEVER were handled at the top of the function */ 11666430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_LESS: conditional = BRW_CONDITIONAL_L; break; 11676430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_GREATER: conditional = BRW_CONDITIONAL_G; break; 11686430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_LEQUAL: conditional = BRW_CONDITIONAL_LE; break; 11696430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_GEQUAL: conditional = BRW_CONDITIONAL_GE; break; 11706430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_EQUAL: conditional = BRW_CONDITIONAL_EQ; break; 11716430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke case GL_NOTEQUAL: conditional = BRW_CONDITIONAL_NEQ; break; 11726430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke default: assert(!"Should not get here: bad shadow compare function"); 11736430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 11746430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11756430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke /* Use conditional moves to load 0 or 1 as the result */ 11766430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke this->current_annotation = "manual shadow comparison"; 11776430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke for (int i = 0; i < 4; i++) { 11786430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst = emit(BRW_OPCODE_MOV, dst, fs_reg(0.0f)); 11796430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11806430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst = emit(BRW_OPCODE_CMP, reg_null_f, ref, value); 11816430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst->conditional_mod = conditional; 11826430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11836430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst = emit(BRW_OPCODE_MOV, dst, fs_reg(1.0f)); 11846430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke inst->predicated = true; 11856430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke 11866430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke dst.reg_offset++; 11876430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke value.reg_offset++; 11886430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 11896430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke dst.reg_offset = 0; 11906430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 11916430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke } 1192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 119301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke swizzle_result(ir, dst, sampler); 119401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke} 119501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke 119601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke/** 119701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * Swizzle the result of a texture result. This is necessary for 119801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons. 119901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke */ 120001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkevoid 120101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkefs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler) 120201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke{ 120301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke this->result = orig_val; 120401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke 1205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type == glsl_type::float_type) { 1206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Ignore DEPTH_TEXTURE_MODE swizzling. */ 1207d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->sampler->type->sampler_shadow); 120801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) { 120901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type); 1210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < 4; i++) { 121201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i); 121301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg l = swizzled_result; 1214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset += i; 1215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1216d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (swiz == SWIZZLE_ZERO) { 1217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, fs_reg(0.0f)); 1218d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (swiz == SWIZZLE_ONE) { 1219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, fs_reg(1.0f)); 1220d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 122101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg r = orig_val; 122201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i); 1223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, r); 1224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1225d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 122601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke this->result = swizzled_result; 1227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_swizzle *ir) 1232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->val->accept(this); 1234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg val = this->result; 1235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type->vector_elements == 1) { 1237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += ir->mask.x; 1238d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1239d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1241d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg result = fs_reg(this, ir->type); 1242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = result; 1243d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < ir->type->vector_elements; i++) { 1245d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg channel = val; 1246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int swiz = 0; 1247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1248d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (i) { 1249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 0: 1250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.x; 1251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 1: 1253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.y; 1254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 2: 1256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.z; 1257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 3: 1259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.w; 1260d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt channel.reg_offset += swiz; 1264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, result, channel); 1265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt result.reg_offset++; 1266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_discard *ir) 1271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->condition == NULL); /* FINISHME */ 1273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DISCARD); 1275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt kill_emitted = true; 1276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_constant *ir) 1280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Set this->result to reg at the bottom of the function because some code 1282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * paths will cause this visitor to be applied to other fields. This will 1283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * cause the value stored in this->result to be modified. 1284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 1285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Make reg constant so that it doesn't get accidentally modified along the 1286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * way. Yes, I actually had this problem. :( 1287d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1288d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const fs_reg reg(this, ir->type); 1289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg dst_reg = reg; 1290d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1291d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type->is_array()) { 1292d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(ir->type->fields.array); 1293d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1294d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < ir->type->length; i++) { 1295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->array_elements[i]->accept(this); 1296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src_reg = this->result; 1297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.type = src_reg.type; 1299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned j = 0; j < size; j++) { 1300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, src_reg); 1301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src_reg.reg_offset++; 1302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->type->is_record()) { 1306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt foreach_list(node, &ir->components) { 1307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_instruction *const field = (ir_instruction *) node; 1308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(field->type); 1309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt field->accept(this); 1311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src_reg = this->result; 1312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.type = src_reg.type; 1314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned j = 0; j < size; j++) { 1315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, src_reg); 1316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src_reg.reg_offset++; 1317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(ir->type); 1322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < size; i++) { 1324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->type->base_type) { 1325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_FLOAT: 1326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.f[i])); 1327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_UINT: 1329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.u[i])); 1330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_INT: 1332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.i[i])); 1333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_BOOL: 1335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg((int)ir->value.b[i])); 1336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"Non-float/uint/int/bool constant"); 1339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1340d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = reg; 1345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_bool_to_cond_code(ir_rvalue *ir) 1349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_expression *expr = ir->as_expression(); 1351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (expr) { 1353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2]; 1354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->get_num_operands() <= 2); 1357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < expr->get_num_operands(); i++) { 1358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->operands[i]->type->is_scalar()); 1359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt expr->operands[i]->accept(this); 1361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[i] = this->result; 1362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1363d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (expr->operation) { 1365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 1366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1)); 1367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_Z; 1368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 1371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_XOR, reg_null_d, op[0], op[1]); 1372d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 1376d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_OR, reg_null_d, op[0], op[1]); 1377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1379d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1380d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 1381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], op[1]); 1382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1385d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 1386d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0.0f)); 1388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, reg_null_f, op[0]); 1390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 1395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0)); 1397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, reg_null_d, op[0]); 1399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 1404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 1405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 1406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 1407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 1408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 1409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 1410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 1411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]); 1412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = 1413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt brw_conditional_for_comparison(expr->operation); 1414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("bad cond code\n"); 1419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_AND, reg_null_d, this->result, fs_reg(1)); 1428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, reg_null_d, this->result); 1431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** 1436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Emit a gen6 IF statement with the comparison folded into the IF 1437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instruction. 1438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_if_gen6(ir_if *ir) 1441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_expression *expr = ir->condition->as_expression(); 1443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (expr) { 1445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2]; 1446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg temp; 1448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->get_num_operands() <= 2); 1450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < expr->get_num_operands(); i++) { 1451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->operands[i]->type->is_scalar()); 1452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt expr->operands[i]->accept(this); 1454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[i] = this->result; 1455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (expr->operation) { 1458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 1459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, temp, op[0], fs_reg(0)); 1460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_Z; 1461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 1464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]); 1465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 1469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = fs_reg(this, glsl_type::bool_type); 1470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_OR, temp, op[0], op[1]); 1471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0)); 1472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 1476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = fs_reg(this, glsl_type::bool_type); 1477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_AND, temp, op[0], op[1]); 1478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0)); 1479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 1483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0)); 1484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 1488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0)); 1489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 1493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 1494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 1495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 1496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 1497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 1498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 1499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 1500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]); 1501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = 1502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt brw_conditional_for_comparison(expr->operation); 1503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0)); 1507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("bad condition\n"); 1509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->condition->accept(this); 1515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_IF, reg_null_d, this->result, fs_reg(0)); 1517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_if *ir) 1522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 152579cba4c2b17456e2b25ac555c45e1c106b4e3f6bKenneth Graunke if (intel->gen < 6 && c->dispatch_width == 16) { 1526d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Can't support (non-uniform) control flow on 16-wide\n"); 1527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Don't point the annotation at the if statement, because then it plus 1530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * the then and else blocks get printed. 1531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->condition; 1533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen == 6) { 1535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_if_gen6(ir); 1536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1537d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_bool_to_cond_code(ir->condition); 1538d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF); 1540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 1541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 154344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->then_instructions) { 154444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1545d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1546d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1550d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!ir->else_instructions.is_empty()) { 1551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ELSE); 1552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 155344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->else_instructions) { 155444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1556d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ENDIF); 1562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1565d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop *ir) 1566d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg counter = reg_undef; 1568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 1570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Can't support (non-uniform) control flow on 16-wide\n"); 1571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->counter) { 1574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->counter; 1575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->counter->accept(this); 1576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt counter = *(variable_storage(ir->counter)); 1577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->from) { 1579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->from; 1580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->from->accept(this); 1581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1582d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke emit(BRW_OPCODE_MOV, counter, this->result); 1583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_DO); 1587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->to) { 1589d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->to; 1590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->to->accept(this); 1591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result); 1593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = brw_conditional_for_comparison(ir->cmp); 1594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_BREAK); 1596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 1597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 159944ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->body_instructions) { 160044ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->increment) { 1607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->increment; 1608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->increment->accept(this); 1609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, counter, counter, this->result); 1610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_WHILE); 1613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop_jump *ir) 1617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1618d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->mode) { 1619d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_loop_jump::jump_break: 1620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_BREAK); 1621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_loop_jump::jump_continue: 1623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_CONTINUE); 1624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_call *ir) 1630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME"); 1632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_return *ir) 1636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME"); 1638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function *ir) 1642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 1644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 1645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (strcmp(ir->name, "main") == 0) { 1647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const ir_function_signature *sig; 1648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt exec_list empty; 1649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sig = ir->matching_signature(&empty); 1651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(sig); 1653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 165444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &sig->body) { 165544ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1657d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1658d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function_signature *ir) 1665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1666d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1667d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt (void)ir; 1668d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1669d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1670d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 1671d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit(fs_inst inst) 1672d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1673d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *list_inst = new(mem_ctx) fs_inst; 1674d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *list_inst = inst; 1675d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1676d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (force_uncompressed_stack > 0) 1677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->force_uncompressed = true; 1678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt else if (force_sechalf_stack > 0) 1679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->force_sechalf = true; 1680d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1681d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->annotation = this->current_annotation; 1682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->ir = this->base_ir; 1683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1684d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->instructions.push_tail(list_inst); 1685d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1686d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return list_inst; 1687d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits a dummy fragment shader consisting of magenta for bringup purposes. */ 1690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_dummy_fs() 1692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1693d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Everyone's favorite color. */ 1694d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 2), fs_reg(1.0f)); 1695d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 3), fs_reg(0.0f)); 1696d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 4), fs_reg(1.0f)); 1697d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, 5), fs_reg(0.0f)); 1698d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1699d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *write; 1700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0)); 17016750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky write->base_mrf = 2; 1702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* The register location here is relative to the start of the URB 1705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * data. It will get adjusted to be a real location before 1706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * generate_code() time. 1707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtstruct brw_reg 1709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::interp_reg(int location, int channel) 1710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int regnr = urb_setup[location] * 2 + channel / 2; 1712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int stride = (channel & 1) * 4; 1713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(urb_setup[location] != -1); 1715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1716d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return brw_vec1_grf(regnr, stride); 1717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */ 1720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen4() 1722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel centers"; 1724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x = fs_reg(this, glsl_type::uint_type); 1725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y = fs_reg(this, glsl_type::uint_type); 1726d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x.type = BRW_REGISTER_TYPE_UW; 1727d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y.type = BRW_REGISTER_TYPE_UW; 1728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_PIXEL_X, this->pixel_x); 1730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_PIXEL_Y, this->pixel_y); 1731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel deltas from v0"; 1733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (brw->has_pln) { 1734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->delta_x = fs_reg(this, glsl_type::vec2_type); 1735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->delta_y = this->delta_x; 1736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->delta_y.reg_offset++; 1737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->delta_x = fs_reg(this, glsl_type::float_type); 1739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->delta_y = fs_reg(this, glsl_type::float_type); 1740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, this->delta_x, 1742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0)))); 1743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, this->delta_y, 1744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1)))); 1745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pos.w and 1/pos.w"; 1747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Compute wpos.w. It's always in our setup, since it's needed to 1748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * interpolate the other attributes. 1749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->wpos_w = fs_reg(this, glsl_type::float_type); 1751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_LINTERP, wpos_w, this->delta_x, this->delta_y, 1752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt interp_reg(FRAG_ATTRIB_WPOS, 3)); 1753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Compute the pixel 1/W value from wpos.w. */ 1754d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_w = fs_reg(this, glsl_type::float_type); 175565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w); 1756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */ 1760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen6() 1762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW); 1764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* If the pixel centers end up used, the setup is the same as for gen4. */ 1766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel centers"; 1767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg int_pixel_x = fs_reg(this, glsl_type::uint_type); 1768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg int_pixel_y = fs_reg(this, glsl_type::uint_type); 1769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_x.type = BRW_REGISTER_TYPE_UW; 1770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_y.type = BRW_REGISTER_TYPE_UW; 1771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, 1772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_x, 1773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)), 1774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_v(0x10101010))); 1775d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, 1776d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_y, 1777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)), 1778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_v(0x11001100))); 1779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* As of gen6, we can no longer mix float and int sources. We have 1781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * to turn the integer pixel centers into floats for their actual 1782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * use. 1783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x = fs_reg(this, glsl_type::float_type); 1785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y = fs_reg(this, glsl_type::float_type); 1786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->pixel_x, int_pixel_x); 1787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->pixel_y, int_pixel_y); 1788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pos.w"; 1790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0)); 1791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->wpos_w = fs_reg(this, glsl_type::float_type); 179265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w); 1793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->delta_x = fs_reg(brw_vec8_grf(2, 0)); 1795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->delta_y = fs_reg(brw_vec8_grf(3, 0)); 1796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1797d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1798d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_color_write(int index, int first_color_mrf, fs_reg color) 1802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 18044fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt fs_inst *inst; 1805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 8 || intel->gen == 6) { 1807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* SIMD8 write looks like: 1808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: r1 1810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: g0 1811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: g1 1812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 1813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * gen6 SIMD16 DP write looks like: 1814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: r1 1816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: g0 1817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: g1 1818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 4: b0 1819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 5: b1 1820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 6: a0 1821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 7: a1 1822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 18234fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, 18244fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt fs_reg(MRF, first_color_mrf + index * reg_width), 18254fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18264fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* pre-gen6 SIMD16 single source DP write looks like: 1829d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: g0 1831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: b0 1832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: a0 1833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 4: r1 1834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 5: g1 1835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 6: b1 1836d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 7: a1 1837d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (brw->has_compr4) { 1839d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* By setting the high bit of the MRF register number, we 1840d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * indicate that we want COMPR4 mode - instead of doing the 1841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * usual destination + 1 for the second half we get 1842d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * destination + 4. 1843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 18444fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, 18454fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index), 18464fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18474fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1848d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_uncompressed(); 18504fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index), 18514fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18524fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_uncompressed(); 1854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_sechalf(); 1856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.sechalf = true; 18574fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4), 18584fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 18594fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_sechalf(); 1861d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.sechalf = false; 1862d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1867d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_fb_writes() 1868d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1869d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "FB write header"; 1870d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt GLboolean header_present = GL_TRUE; 1871eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke int base_mrf = 2; 1872eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke int nr = base_mrf; 1873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 1874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6 && 1876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt !this->kill_emitted && 1877d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->key.nr_color_regions == 1) { 1878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = false; 1879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1880d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1881d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (header_present) { 18826750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky /* m2, m3 header */ 1883d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += 2; 1884d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->aa_dest_stencil_reg) { 1887d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_uncompressed(); 1888d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr++), 1889d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->aa_dest_stencil_reg, 0))); 1890d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_uncompressed(); 1891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1892d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Reserve space for color. It'll be filled in per MRT below. */ 1894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int color_mrf = nr; 1895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += 4 * reg_width; 1896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->source_depth_to_render_target) { 1898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen == 6 && c->dispatch_width == 16) { 1899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* For outputting oDepth on gen6, SIMD8 writes have to be 1900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * used. This would require 8-wide moves of each half to 1901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * message regs, kind of like pre-gen5 SIMD16 FB writes. 1902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Just bail on doing so for now. 1903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Missing support for simd16 depth writes on gen6\n"); 1905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->computes_depth) { 1908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Hand over gl_FragDepth. */ 1909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(this->frag_depth); 1910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg depth = *(variable_storage(this->frag_depth)); 1911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), depth); 1913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Pass through the payload depth. */ 1915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), 1916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->source_depth_reg, 0))); 1917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += reg_width; 1919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dest_depth_reg) { 1922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), 1923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->dest_depth_reg, 0))); 1924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += reg_width; 1925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg color = reg_undef; 1928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (this->frag_color) 1929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color = *(variable_storage(this->frag_color)); 1930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt else if (this->frag_data) { 1931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color = *(variable_storage(this->frag_data)); 1932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.type = BRW_REGISTER_TYPE_F; 1933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int target = 0; target < c->key.nr_color_regions; target++) { 1936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = ralloc_asprintf(this->mem_ctx, 1937d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt "FB write target %d", 1938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt target); 1939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (this->frag_color || this->frag_data) { 1940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < 4; i++) { 1941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_color_write(i, color_mrf, color); 1942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.reg_offset++; 1943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1945d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (this->frag_color) 1947d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.reg_offset -= 4; 1948d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1949d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(FS_OPCODE_FB_WRITE); 1950d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->target = target; 1951eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->base_mrf = base_mrf; 1952eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->mlen = nr - base_mrf; 1953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (target == c->key.nr_color_regions - 1) 1954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->eot = true; 1955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1957d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1958d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->key.nr_color_regions == 0) { 1959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->key.alpha_test && (this->frag_color || this->frag_data)) { 1960d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* If the alpha test is enabled but there's no color buffer, 1961d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * we still need to send alpha out the pipeline to our null 1962d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * renderbuffer. 1963d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1964d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.reg_offset += 3; 1965d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_color_write(3, color_mrf, color); 1966d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1967d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1968d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(FS_OPCODE_FB_WRITE); 1969eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->base_mrf = base_mrf; 1970eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->mlen = nr - base_mrf; 1971d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->eot = true; 1972d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1975d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1976d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1977