1d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* 2d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Copyright © 2010 Intel Corporation 3d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 4d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 5d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * copy of this software and associated documentation files (the "Software"), 6d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * to deal in the Software without restriction, including without limitation 7d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 9d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Software is furnished to do so, subject to the following conditions: 10d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 11d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * The above copyright notice and this permission notice (including the next 12d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * paragraph) shall be included in all copies or substantial portions of the 13d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Software. 14d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 15d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * IN THE SOFTWARE. 22d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 23d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 24d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** @file brw_fs_visitor.cpp 25d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 26d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * This file supports generating the FS LIR from the GLSL IR. The LIR 27d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * makes it easier to do backend-specific optimizations than doing so 28d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * in the GLSL IR or in the native code. 29d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 30d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtextern "C" { 31d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 32d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include <sys/types.h> 33d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 34d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/macros.h" 35d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/shaderobj.h" 36d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/uniforms.h" 37d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_parameter.h" 38d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_print.h" 39d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_optimize.h" 40d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/register_allocate.h" 41d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/sampler.h" 42d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/hash_table.h" 43d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_context.h" 44d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_eu.h" 45d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_wm.h" 46d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 47d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_shader.h" 48d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_fs.h" 492f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/glsl_types.h" 502f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir_optimization.h" 512f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir_print_visitor.h" 52d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 53d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 54d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_variable *ir) 55d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 56d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg *reg = NULL; 57d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 58d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (variable_storage(ir)) 59d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 60d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 61d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->mode == ir_var_in) { 62d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!strcmp(ir->name, "gl_FragCoord")) { 63d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_fragcoord_interpolation(ir); 64d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (!strcmp(ir->name, "gl_FrontFacing")) { 65d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_frontfacing_interpolation(ir); 66d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 67d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = emit_general_interpolation(ir); 68d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 69d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(reg); 70d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt hash_table_insert(this->variable_ht, reg, ir); 71d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 726d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else if (ir->mode == ir_var_out) { 736d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt reg = new(this->mem_ctx) fs_reg(this, ir->type); 74d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 7529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt if (ir->index > 0) { 7629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt assert(ir->location == FRAG_RESULT_DATA0); 7729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt assert(ir->index == 1); 7829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt this->dual_src_output = *reg; 7929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt } else if (ir->location == FRAG_RESULT_COLOR) { 806d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* Writing gl_FragColor outputs to all color regions. */ 811e188f2daef1ae31224d2429bcc1fab75c81fb36Eric Anholt for (unsigned int i = 0; i < MAX2(c->key.nr_color_regions, 1); i++) { 826d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt this->outputs[i] = *reg; 832f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke this->output_components[i] = 4; 846d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } 856d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else if (ir->location == FRAG_RESULT_DEPTH) { 866d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt this->frag_depth = ir; 876d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else { 886d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* gl_FragData or a user-defined FS output */ 896d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt assert(ir->location >= FRAG_RESULT_DATA0 && 906d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt ir->location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS); 916d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt 922f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke int vector_elements = 932f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke ir->type->is_array() ? ir->type->fields.array->vector_elements 942f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke : ir->type->vector_elements; 952f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke 966d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* General color output. */ 976d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt for (unsigned int i = 0; i < MAX2(1, ir->type->length); i++) { 986d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt int output = ir->location - FRAG_RESULT_DATA0 + i; 996d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt this->outputs[output] = *reg; 1002f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke this->outputs[output].reg_offset += vector_elements * i; 1012f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke this->output_components[output] = vector_elements; 1026d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } 1036d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } 1046d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt } else if (ir->mode == ir_var_uniform) { 105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int param_index = c->prog_data.nr_params; 106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 10790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt /* Thanks to the lower_ubo_reference pass, we will see only 10890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO 10990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt * variables, so no need for them to be in variable_ht. 11090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt */ 11190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt if (ir->uniform_block != -1) 11290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt return; 11390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt 114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!variable_storage(ir)) { 116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Failed to find uniform '%s' in 16-wide\n", ir->name); 117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!strncmp(ir->name, "gl_", 3)) { 122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt setup_builtin_uniform_values(ir); 123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt setup_uniform_values(ir->location, ir->type); 125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index); 128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg->type = brw_type_for_base_type(ir->type); 129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!reg) 132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt reg = new(this->mem_ctx) fs_reg(this, ir->type); 133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt hash_table_insert(this->variable_ht, reg, ir); 135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_variable *ir) 139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg *reg = variable_storage(ir->var); 141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = *reg; 142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 145d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_record *ir) 146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const glsl_type *struct_type = ir->record->type; 148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->record->accept(this); 150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt unsigned int offset = 0; 152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < struct_type->length; i++) { 153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt offset += type_size(struct_type->fields.structure[i].type); 156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += offset; 158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.type = brw_type_for_base_type(ir->type); 159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_array *ir) 163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_constant *index; 165d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int element_size; 166d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 167d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->array->accept(this); 168d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt index = ir->array_index->as_constant(); 169d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 170d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt element_size = type_size(ir->type); 171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.type = brw_type_for_base_type(ir->type); 172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (index) { 174b76378d46a211521582cfab56dc05031a57502a6Eric Anholt assert(this->result.file == UNIFORM || this->result.file == GRF); 175d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += index->value.i[0] * element_size; 176d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 177d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME: non-constant array element"); 178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 181d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* Instruction selection: Produce a MOV.sat instead of 182d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * MIN(MAX(val, 0), 1) when possible. 183d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtbool 185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::try_emit_saturate(ir_expression *ir) 186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_rvalue *sat_val = ir->as_rvalue_to_saturate(); 188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!sat_val) 190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return false; 191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 19232ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt fs_inst *pre_inst = (fs_inst *) this->instructions.get_tail(); 19332ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt 194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sat_val->accept(this); 195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src = this->result; 196d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 19732ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt fs_inst *last_inst = (fs_inst *) this->instructions.get_tail(); 19832ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt 19932ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt /* If the last instruction from our accept() didn't generate our 20032ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt * src, generate a saturated MOV 20132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt */ 20232ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt fs_inst *modify = get_instruction_generating_reg(pre_inst, last_inst, src); 20332ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt if (!modify || modify->regs_written() != 1) { 2040ba14013f66c03c6a3cc0a5e3ef74e92bfe5afb9Eric Anholt this->result = fs_reg(this, ir->type); 20532ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, this->result, src); 20632ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt inst->saturate = true; 20732ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt } else { 20832ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt modify->saturate = true; 20932ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt this->result = src; 21032ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt } 21132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt 212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return true; 214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2167d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholtbool 2177d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholtfs_visitor::try_emit_mad(ir_expression *ir, int mul_arg) 2187d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt{ 2197d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt /* 3-src instructions were introduced in gen6. */ 2207d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt if (intel->gen < 6) 2217d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt return false; 2227d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2237d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt /* MAD can only handle floating-point data. */ 2247d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt if (ir->type != glsl_type::float_type) 2257d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt return false; 2267d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2277d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt ir_rvalue *nonmul = ir->operands[1 - mul_arg]; 2287d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt ir_expression *mul = ir->operands[mul_arg]->as_expression(); 2297d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2307d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt if (!mul || mul->operation != ir_binop_mul) 2317d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt return false; 2327d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2337d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt if (nonmul->as_constant() || 2347d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt mul->operands[0]->as_constant() || 2357d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt mul->operands[1]->as_constant()) 2367d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt return false; 2377d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2387d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt nonmul->accept(this); 2397d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt fs_reg src0 = this->result; 2407d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2417d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt mul->operands[0]->accept(this); 2427d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt fs_reg src1 = this->result; 2437d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2447d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt mul->operands[1]->accept(this); 2457d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt fs_reg src2 = this->result; 2467d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2477d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt this->result = fs_reg(this, ir->type); 2487d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt emit(BRW_OPCODE_MAD, this->result, src0, src1, src2); 2497d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 2507d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt return true; 2517d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt} 2527d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt 253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_expression *ir) 255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt unsigned int operand; 257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2], temp; 258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 260d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->get_num_operands() <= 2); 261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (try_emit_saturate(ir)) 263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 2647d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt if (ir->operation == ir_binop_add) { 2657d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt if (try_emit_mad(ir, 0) || try_emit_mad(ir, 1)) 2667d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt return; 2677d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt } 268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->operands[operand]->accept(this); 271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (this->result.file == BAD_FILE) { 272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_print_visitor v; 273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Failed to get tree for expression operand:\n"); 274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->operands[operand]->accept(&v); 275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[operand] = this->result; 277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Matrix expression operands should have been broken down to vector 279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * operations already. 280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->operands[operand]->type->is_matrix()); 282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* And then those vector operands should have been broken down to scalar. 283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!ir->operands[operand]->type->is_vector()); 285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 287d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke /* Storage for our result. If our result goes into an assignment, it will 288d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke * just get copy-propagated out, so no worries. 289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 290d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke this->result = fs_reg(this, ir->type); 291d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 292d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->operation) { 293d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 294d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Note that BRW_OPCODE_NOT is not appropriate here, since it is 295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * ones complement of the whole register, not just bit 0. 296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_XOR, this->result, op[0], fs_reg(1)); 298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_neg: 300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = !op[0].negate; 301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = op[0]; 302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_abs: 304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].abs = true; 305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = false; 306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = op[0]; 307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sign: 309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = fs_reg(this, ir->type); 310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f)); 312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)); 314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_G; 315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(1.0f)); 316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)); 319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f)); 321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_rcp: 32565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->result, op[0]); 326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_exp2: 32965b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_EXP2, this->result, op[0]); 330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_log2: 33265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_LOG2, this->result, op[0]); 333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_exp: 335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_log: 336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sin: 339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sin_reduced: 34065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_SIN, this->result, op[0]); 341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_cos: 343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_cos_reduced: 34465b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_COS, this->result, op[0]); 345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_dFdx: 348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DDX, this->result, op[0]); 349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_dFdy: 351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DDY, this->result, op[0]); 352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_add: 355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, this->result, op[0], op[1]); 356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_sub: 358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by ir_sub_to_add_neg"); 359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_mul: 3623f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt if (ir->type->is_integer()) { 3633f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt /* For integer multiplication, the MUL uses the low 16 bits 3643f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * of one of the operands (src0 on gen6, src1 on gen7). The 3653f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * MACH accumulates in the contribution of the upper 16 bits 3663f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * of that operand. 3673f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * 3683f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * FINISHME: Emit just the MUL if we know an operand is small 3693f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt * enough. 3703f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt */ 37101044fce6b3de11635ea5078b76ffee1a33b3802Kenneth Graunke if (intel->gen >= 7 && c->dispatch_width == 16) 37201044fce6b3de11635ea5078b76ffee1a33b3802Kenneth Graunke fail("16-wide explicit accumulator operands unsupported\n"); 37301044fce6b3de11635ea5078b76ffee1a33b3802Kenneth Graunke 3743f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D); 3753f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt 3763f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MUL, acc, op[0], op[1]); 3773f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]); 3783f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MOV, this->result, fs_reg(acc)); 3793f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt } else { 3803f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt emit(BRW_OPCODE_MUL, this->result, op[0], op[1]); 3813f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt } 382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_div: 38483dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt if (intel->gen >= 7 && c->dispatch_width == 16) 38583dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt fail("16-wide INTDIV unsupported\n"); 38683dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt 387ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke /* Floating point should be lowered by DIV_TO_MUL_RCP in the compiler. */ 388ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke assert(ir->type->is_integer()); 389ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]); 390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_mod: 39283dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt if (intel->gen >= 7 && c->dispatch_width == 16) 39383dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt fail("16-wide INTDIV unsupported\n"); 39483dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt 395ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */ 396ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke assert(ir->type->is_integer()); 397ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke emit_math(SHADER_OPCODE_INT_REMAINDER, this->result, op[0], op[1]); 398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp = this->result; 409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* original gen4 does implicit conversion before comparison. */ 410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen < 5) 411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt temp.type = op[0].type; 412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 41373b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[0]); 41473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[1]); 41573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 416dc42910e98dc00760255cc4579da458de09175b9Eric Anholt resolve_bool_comparison(ir->operands[0], &op[0]); 417dc42910e98dc00760255cc4579da458de09175b9Eric Anholt resolve_bool_comparison(ir->operands[1], &op[1]); 418dc42910e98dc00760255cc4579da458de09175b9Eric Anholt 419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]); 420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = brw_conditional_for_comparison(ir->operation); 421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_XOR, this->result, op[0], op[1]); 425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_OR, this->result, op[0], op[1]); 429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_AND, this->result, op[0], op[1]); 433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_dot: 436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_any: 437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by brw_fs_channel_expressions"); 438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_noise: 441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by lower_noise"); 442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_quadop_vector: 445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached: should be handled by lower_quadop_vector"); 446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_sqrt: 44965b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_SQRT, this->result, op[0]); 450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_rsq: 45365b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RSQ, this->result, op[0]); 454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 45605790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke case ir_unop_bitcast_i2f: 45705790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke case ir_unop_bitcast_u2f: 45805790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke op[0].type = BRW_REGISTER_TYPE_F; 45905790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke this->result = op[0]; 46005790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke break; 461b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke case ir_unop_i2u: 46205790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke case ir_unop_bitcast_f2u: 463b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke op[0].type = BRW_REGISTER_TYPE_UD; 464b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke this->result = op[0]; 465b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke break; 466b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke case ir_unop_u2i: 46705790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke case ir_unop_bitcast_f2i: 468b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke op[0].type = BRW_REGISTER_TYPE_D; 469b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke this->result = op[0]; 470b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke break; 471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2f: 4724bc5bfb641bce931bf35f0e78ec2b44263d152baKenneth Graunke case ir_unop_u2f: 473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2i: 47411a7b93592c22c8165f8fde6395f76778fca452ePaul Berry case ir_unop_f2u: 475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->result, op[0]); 476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 47780ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt 47880ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt case ir_unop_b2i: 47980ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt inst = emit(BRW_OPCODE_AND, this->result, op[0], fs_reg(1)); 48080ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt break; 48180ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt case ir_unop_b2f: 48280ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt temp = fs_reg(this, glsl_type::int_type); 48380ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt emit(BRW_OPCODE_AND, temp, op[0], fs_reg(1)); 48480ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt emit(BRW_OPCODE_MOV, this->result, temp); 48580ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt break; 48680ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt 487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 488cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace inst = emit(BRW_OPCODE_CMP, this->result, op[0], fs_reg(0.0f)); 489cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace inst->conditional_mod = BRW_CONDITIONAL_NZ; 490cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1)); 491cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace break; 492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 493cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace assert(op[0].type == BRW_REGISTER_TYPE_D); 49473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 495cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace inst = emit(BRW_OPCODE_CMP, this->result, op[0], fs_reg(0)); 496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 497cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1)); 498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_trunc: 501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_RNDZ, this->result, op[0]); 502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_ceil: 504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[0].negate = !op[0].negate; 505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_RNDD, this->result, op[0]); 506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.negate = true; 507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_floor: 509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_RNDD, this->result, op[0]); 510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_fract: 512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_FRC, this->result, op[0]); 513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_round_even: 515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_RNDE, this->result, op[0]); 516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_min: 51973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[0]); 52073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[1]); 52173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 522c331b3123ecda127919458e24848b7c1596525acEric Anholt if (intel->gen >= 6) { 523c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 524c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 525c331b3123ecda127919458e24848b7c1596525acEric Anholt } else { 526c331b3123ecda127919458e24848b7c1596525acEric Anholt /* Unalias the destination */ 527c331b3123ecda127919458e24848b7c1596525acEric Anholt this->result = fs_reg(this, ir->type); 528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 529c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); 530c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 532c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 533c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->predicated = true; 534c331b3123ecda127919458e24848b7c1596525acEric Anholt } 535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_max: 53773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[0]); 53873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[1]); 53973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 540c331b3123ecda127919458e24848b7c1596525acEric Anholt if (intel->gen >= 6) { 541c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 542c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_GE; 543c331b3123ecda127919458e24848b7c1596525acEric Anholt } else { 544c331b3123ecda127919458e24848b7c1596525acEric Anholt /* Unalias the destination */ 545c331b3123ecda127919458e24848b7c1596525acEric Anholt this->result = fs_reg(this, ir->type); 546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 547c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); 548c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->conditional_mod = BRW_CONDITIONAL_G; 549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 550c331b3123ecda127919458e24848b7c1596525acEric Anholt inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); 551c331b3123ecda127919458e24848b7c1596525acEric Anholt inst->predicated = true; 552c331b3123ecda127919458e24848b7c1596525acEric Anholt } 553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 554d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_pow: 55665b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]); 557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_bit_not: 560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_NOT, this->result, op[0]); 561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_and: 563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, this->result, op[0], op[1]); 564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 565d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_xor: 566d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_XOR, this->result, op[0], op[1]); 567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_bit_or: 569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_OR, this->result, op[0], op[1]); 570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lshift: 5737de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt inst = emit(BRW_OPCODE_SHL, this->result, op[0], op[1]); 5747de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt break; 5757de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt 576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_rshift: 5777de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt if (ir->type->base_type == GLSL_TYPE_INT) 5787de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt inst = emit(BRW_OPCODE_ASR, this->result, op[0], op[1]); 5797de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt else 5807de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt inst = emit(BRW_OPCODE_SHR, this->result, op[0], op[1]); 581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 5822ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt 5832ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt case ir_binop_ubo_load: 58490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt ir_constant *uniform_block = ir->operands[0]->as_constant(); 58590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt ir_constant *offset = ir->operands[1]->as_constant(); 58690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt 58790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt fs_reg packed_consts = fs_reg(this, glsl_type::float_type); 58890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt packed_consts.type = result.type; 58990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt fs_reg surf_index = fs_reg((unsigned)SURF_INDEX_WM_UBO(uniform_block->value.u[0])); 59090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt fs_inst *pull = emit(fs_inst(FS_OPCODE_PULL_CONSTANT_LOAD, 59190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt packed_consts, 59290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt surf_index, 59390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt fs_reg(offset->value.u[0]))); 59490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt pull->base_mrf = 14; 59590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt pull->mlen = 1; 59690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt 59790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt packed_consts.smear = offset->value.u[0] % 16 / 4; 59890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt for (int i = 0; i < ir->type->vector_elements; i++) { 59990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt /* UBO bools are any nonzero value. We consider bools to be 60090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt * values with the low bit set to 1. Convert them using CMP. 60190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt */ 60290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt if (ir->type->base_type == GLSL_TYPE_BOOL) { 60390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP, result, 60490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt packed_consts, fs_reg(0u))); 60590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 60690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt } else { 60790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt emit(fs_inst(BRW_OPCODE_MOV, result, packed_consts)); 60890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt } 60990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt 61090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt packed_consts.smear++; 61190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt result.reg_offset++; 61290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt 61390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt /* The std140 packing rules don't allow vectors to cross 16-byte 61490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt * boundaries, and a reg is 32 bytes. 61590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt */ 61690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt assert(packed_consts.smear < 8); 61790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt } 61890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt result.reg_offset = 0; 6192ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt break; 620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r, 625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const glsl_type *type, bool predicated) 626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (type->base_type) { 628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_FLOAT: 629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_UINT: 630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_INT: 631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_BOOL: 632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->components(); i++) { 633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.type = brw_type_for_base_type(type); 634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.type = brw_type_for_base_type(type); 635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 636d1029f99884e2ba7f663765274cd6bdb4f82feedKenneth Graunke if (predicated || !l.equals(r)) { 637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, l, r); 638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = predicated; 639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset++; 642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.reg_offset++; 643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_ARRAY: 646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, type->fields.array, predicated); 648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_STRUCT: 652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, type->fields.structure[i].type, 654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt predicated); 655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 657d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 658d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_SAMPLER: 659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 666d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 667dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke/* If the RHS processing resulted in an instruction generating a 668dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * temporary value, and it would be easy to rewrite the instruction to 669dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * generate its result right into the LHS instead, do so. This ends 670dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * up reliably removing instructions where it can be tricky to do so 671dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * later without real UD chain information. 672dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke */ 673dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkebool 674dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkefs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir, 675dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_reg dst, 676dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_reg src, 677dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *pre_rhs_inst, 678dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *last_rhs_inst) 679dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke{ 680dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Only attempt if we're doing a direct assignment. */ 681dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (ir->condition || 682dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke !(ir->lhs->type->is_scalar() || 683dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke (ir->lhs->type->is_vector() && 684dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1))) 685dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; 686dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 687dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Make sure the last instruction generated our source reg. */ 68832ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt fs_inst *modify = get_instruction_generating_reg(pre_rhs_inst, 68932ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt last_rhs_inst, 69032ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt src); 69132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt if (!modify) 692dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return false; 693dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 6944b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke /* If last_rhs_inst wrote a different number of components than our LHS, 6954b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke * we can't safely rewrite it. 6964b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke */ 69732ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt if (ir->lhs->type->vector_elements != modify->regs_written()) 6984b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke return false; 6994b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke 700dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke /* Success! Rewrite the instruction. */ 70132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt modify->dst = dst; 702dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 703dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return true; 704dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke} 705dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_assignment *ir) 708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 709eb86bb55f5faef67c21604db19210c6788592679Kenneth Graunke fs_reg l, r; 710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* FINISHME: arrays on the lhs */ 713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lhs->accept(this); 714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l = this->result; 715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 716dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail(); 717dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->rhs->accept(this); 719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r = this->result; 720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 721dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail(); 722dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(l.file != BAD_FILE); 724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(r.file != BAD_FILE); 725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 726dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst)) 727dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke return; 728dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke 729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->condition) { 730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_bool_to_cond_code(ir->condition); 731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->lhs->type->is_scalar() || 734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->lhs->type->is_vector()) { 735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->lhs->type->vector_elements; i++) { 736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->write_mask & (1 << i)) { 737d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke inst = emit(BRW_OPCODE_MOV, l, r); 738d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke if (ir->condition) 739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt r.reg_offset++; 741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset++; 743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_assignment_writes(l, r, ir->lhs->type, ir->condition != NULL); 746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, 751bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke fs_reg shadow_c, fs_reg lod, fs_reg dPdy) 752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen; 754d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 1; 755d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool simd16 = false; 756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg orig_dst; 757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* g0 header. */ 759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = 1; 760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 761b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke if (ir->shadow_comparitor) { 762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 76307e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); 764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* gen4's SIMD8 sampler always has the slots for u,v,r present. */ 767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 3; 768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->op == ir_tex) { 770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* There's no plain shadow compare message, so we use shadow 771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * compare with a bias of 0.0. 772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f)); 774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 775c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke } else if (ir->op == ir_txb || ir->op == ir_txl) { 776c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod); 777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 779c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke assert(!"Should not get here."); 780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 782c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), shadow_c); 783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_tex) { 785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 78607e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); 787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* gen4's SIMD8 sampler always has the slots for u,v,r present. */ 790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 3; 791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->op == ir_txd) { 792c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke fs_reg &dPdx = lod; 7936c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 7946c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 7956c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); 7966c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke coordinate.reg_offset++; 7976c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 7986c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke /* the slots for u and v are always present, but r is optional */ 7996c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke mlen += MAX2(ir->coordinate->type->vector_elements, 2); 8006c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 8016c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke /* P = u, v, r 8026c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx = dudx, dvdx, drdx 8036c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdy = dudy, dvdy, drdy 8046c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 8053e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke * 1-arg: Does not exist. 8063e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke * 8076c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 2-arg: dudx dvdx dudy dvdy 8086c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx.x dPdx.y dPdy.x dPdy.y 8096c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * m4 m5 m6 m7 8106c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 8116c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * 3-arg: dudx dvdx drdx dudy dvdy drdy 8126c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z 8136c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke * m5 m6 m7 m8 m9 m10 8146c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke */ 8156c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { 8166c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); 8176c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke dPdx.reg_offset++; 8186c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 8193e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke mlen += MAX2(ir->lod_info.grad.dPdx->type->vector_elements, 2); 8206c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke 8216c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) { 8226c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); 8236c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke dPdy.reg_offset++; 8246c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke } 8253e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2); 8264eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke } else if (ir->op == ir_txs) { 8274eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke /* There's no SIMD8 resinfo message on Gen4. Use SIMD16 instead. */ 8284eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke simd16 = true; 829c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod); 8304eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke mlen += 2; 831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Oh joy. gen4 doesn't have SIMD8 non-shadow-compare bias/lod 833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instructions. We'll need to do SIMD16 here. 834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 8354eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke simd16 = true; 83647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke assert(ir->op == ir_txb || ir->op == ir_txl || ir->op == ir_txf); 837d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 83907e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type), 84007e621c52329cd17b97051a26493626228d043b9Eric Anholt coordinate); 841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate.reg_offset++; 842d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 84447b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke /* Initialize the rest of u/v/r with 0.0. Empirically, this seems to 84547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke * be necessary for TXF (ld), but seems wise to do for all messages. 84647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke */ 84747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke for (int i = ir->coordinate->type->vector_elements; i < 3; i++) { 84847b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f)); 84947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke } 85047b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke 851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* lod/bias appears after u/v/r. */ 852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += 6; 853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 854c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, lod.type), lod); 855c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke mlen++; 856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The unused upper half. */ 858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 8594eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke } 860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 8614eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke if (simd16) { 862d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Now, since we're doing simd16, the return is 2 interleaved 863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * vec4s where the odd-indexed ones are junk. We'll need to move 864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * this weirdness around to the expected layout. 865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt orig_dst = dst; 8674eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke const glsl_type *vec_type = 8684eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke glsl_type::get_instance(ir->type->base_type, 4, 1); 8694eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2)); 8704eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type) 8714eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke : BRW_REGISTER_TYPE_F; 872d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 877febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TEX, dst); 878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 880d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXB, dst); 881d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 882d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 883febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXL, dst); 884d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txd: 886febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXD, dst); 887d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 8881e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 889febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXS, dst); 8904eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke break; 8914eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke case ir_txf: 892febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXF, dst); 893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = true; 898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (simd16) { 900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < 4; i++) { 901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, orig_dst, dst); 902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt orig_dst.reg_offset++; 903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst.reg_offset += 2; 904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* gen5's sampler has slots for u, v, r, array index, then optional 911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters like shadow comparitor or LOD bias. If optional 912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters aren't present, those base slots are optional and don't 913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * need to be included in the message. 914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * We don't fill in the unnecessary slots regardless, which may look 916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * surprising in the disassembly. 917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, 920bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke fs_reg shadow_c, fs_reg lod, fs_reg lod2) 921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen = 0; 923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 2; 924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool header_present = false; 926ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke const int vector_elements = 927ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke ir->coordinate ? ir->coordinate->type->vector_elements : 0; 928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 929217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke if (ir->offset != NULL && ir->op == ir_txf) { 930217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke /* It appears that the ld instruction used for txf does its 931217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke * address bounds check before adding in the offset. To work 932217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke * around this, just add the integer offset to the integer texel 933217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke * coordinate, and don't put the offset in the header. 934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 935217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke ir_constant *offset = ir->offset->as_constant(); 936217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke for (int i = 0; i < vector_elements; i++) { 937217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke emit(BRW_OPCODE_ADD, 938217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type), 939217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke coordinate, 940217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke offset->value.i[i]); 941217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke coordinate.reg_offset++; 942217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke } 943217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke } else { 944217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke if (ir->offset) { 945217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke /* The offsets set up by the ir_texture visitor are in the 946217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke * m1 header, so we can't go headerless. 947217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke */ 948217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke header_present = true; 949217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke mlen++; 950217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke base_mrf--; 951217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke } 952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 953217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke for (int i = 0; i < vector_elements; i++) { 954217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke emit(BRW_OPCODE_MOV, 955217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type), 956217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke coordinate); 957217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke coordinate.reg_offset++; 958217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke } 959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 960ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += vector_elements * reg_width; 961d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 962b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke if (ir->shadow_comparitor) { 963d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 964d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 965c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), shadow_c); 966d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 967d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 968d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 969d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 970d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 971d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 972febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TEX, dst); 973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 975d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 976c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod); 977d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 978d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 979d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(FS_OPCODE_TXB, dst); 980d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 981d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 982d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen = MAX2(mlen, header_present + 4 * reg_width); 983c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod); 984d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 986febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXL, dst); 987d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 9882f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke case ir_txd: { 9892f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */ 9902f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 9912f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke /** 9922f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * P = u, v, r 9932f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * dPdx = dudx, dvdx, drdx 9942f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * dPdy = dudy, dvdy, drdy 9952f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * 9962f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * Load up these values: 9972f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * - dudx dudy dvdx dvdy drdx drdy 9982f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z 9992f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke */ 10002f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { 1001c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod); 1002c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod.reg_offset++; 10032f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen += reg_width; 10042f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 1005c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod2); 1006c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod2.reg_offset++; 10072f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke mlen += reg_width; 10082f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke } 10092f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke 1010febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXD, dst); 10112f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke break; 10122f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke } 10131e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 1014c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod); 1015ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += reg_width; 1016febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXS, dst); 1017ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke break; 1018ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txf: 101930be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke mlen = header_present + 4 * reg_width; 102030be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke 102130be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke emit(BRW_OPCODE_MOV, 102230be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD), 1023c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod); 1024febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke inst = emit(SHADER_OPCODE_TXF, dst); 1025d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1026d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1027d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 1028d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 1029d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1030d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1031d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (mlen > 11) { 1032d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Message length >11 disallowed by hardware\n"); 1033d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1034d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1035d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 1036d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1037d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1038d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 1039d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, 1040bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke fs_reg shadow_c, fs_reg lod, fs_reg lod2) 1041d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1042d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int mlen = 0; 1043d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int base_mrf = 2; 1044d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 1045d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt bool header_present = false; 1046f41ecade7b458c02d504158b522acb2231585040Eric Anholt int offsets[3]; 1047d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1048f41ecade7b458c02d504158b522acb2231585040Eric Anholt if (ir->offset && ir->op != ir_txf) { 1049d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The offsets set up by the ir_texture visitor are in the 1050d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m1 header, so we can't go headerless. 1051d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1052d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = true; 1053d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen++; 1054d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt base_mrf--; 1055d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1056d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1057b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke if (ir->shadow_comparitor) { 1058c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), shadow_c); 1059d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 1060d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1061d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1062d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Set up the LOD info */ 1063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 1064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_tex: 1065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1066d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: 1067c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod); 1068d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 1069d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1070d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txl: 1071c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod); 1072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt mlen += reg_width; 1073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 10743fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke case ir_txd: { 10753fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke if (c->dispatch_width == 16) 10763fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode."); 10773fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 10783fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke /* Load dPdx and the coordinate together: 10793fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z 10803fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke */ 10813fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 108207e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate); 10833fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate.reg_offset++; 10843fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 10853fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 1086c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod); 1087c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod.reg_offset++; 10883fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 10893fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke 1090c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod2); 1091c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod2.reg_offset++; 10923fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 10933fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 10943fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke break; 10953fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 10961e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 1097c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod); 1098ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke mlen += reg_width; 1099ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke break; 1100ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke case ir_txf: 1101f41ecade7b458c02d504158b522acb2231585040Eric Anholt /* It appears that the ld instruction used for txf does its 1102f41ecade7b458c02d504158b522acb2231585040Eric Anholt * address bounds check before adding in the offset. To work 1103f41ecade7b458c02d504158b522acb2231585040Eric Anholt * around this, just add the integer offset to the integer texel 1104f41ecade7b458c02d504158b522acb2231585040Eric Anholt * coordinate, and don't put the offset in the header. 1105f41ecade7b458c02d504158b522acb2231585040Eric Anholt */ 1106f41ecade7b458c02d504158b522acb2231585040Eric Anholt if (ir->offset) { 1107f41ecade7b458c02d504158b522acb2231585040Eric Anholt ir_constant *offset = ir->offset->as_constant(); 1108f41ecade7b458c02d504158b522acb2231585040Eric Anholt offsets[0] = offset->value.i[0]; 1109f41ecade7b458c02d504158b522acb2231585040Eric Anholt offsets[1] = offset->value.i[1]; 1110f41ecade7b458c02d504158b522acb2231585040Eric Anholt offsets[2] = offset->value.i[2]; 1111f41ecade7b458c02d504158b522acb2231585040Eric Anholt } else { 1112f41ecade7b458c02d504158b522acb2231585040Eric Anholt memset(offsets, 0, sizeof(offsets)); 1113f41ecade7b458c02d504158b522acb2231585040Eric Anholt } 1114f41ecade7b458c02d504158b522acb2231585040Eric Anholt 11150edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */ 1116f41ecade7b458c02d504158b522acb2231585040Eric Anholt emit(BRW_OPCODE_ADD, 1117f41ecade7b458c02d504158b522acb2231585040Eric Anholt fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate, offsets[0]); 11180edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke coordinate.reg_offset++; 11190edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 11200edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke 1121c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), lod); 11220edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 11230edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke 11240edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke for (int i = 1; i < ir->coordinate->type->vector_elements; i++) { 1125f41ecade7b458c02d504158b522acb2231585040Eric Anholt emit(BRW_OPCODE_ADD, 1126f41ecade7b458c02d504158b522acb2231585040Eric Anholt fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate, offsets[i]); 11270edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke coordinate.reg_offset++; 11280edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke mlen += reg_width; 11290edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke } 1130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 11330edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke /* Set up the coordinate (except for cases where it was done above) */ 11340edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf) { 11353fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { 113607e621c52329cd17b97051a26493626228d043b9Eric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate); 11373fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke coordinate.reg_offset++; 11383fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke mlen += reg_width; 11393fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke } 1140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Generate the SEND */ 1143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 1144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->op) { 1145febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst); break; 1146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break; 1147febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst); break; 1148febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst); break; 1149febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst); break; 1150febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break; 1151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->base_mrf = base_mrf; 1153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->mlen = mlen; 1154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 1155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (mlen > 11) { 1157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Message length >11 disallowed by hardware\n"); 1158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return inst; 1161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 116327bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke/** 116427bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke * Emit code to produce the coordinates for a texture lookup. 116527bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke * 116627bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke * Returns the fs_reg containing the texture coordinate (as opposed to 116727bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke * setting this->result). 116827bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke */ 116927bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunkefs_reg 1170f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunkefs_visitor::emit_texcoord(ir_texture *ir, int sampler, int texunit) 1171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = NULL; 1173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 117427bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke if (!ir->coordinate) 117527bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke return fs_reg(); /* Return the default BAD_FILE register. */ 1176f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke 117727bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke ir->coordinate->accept(this); 1178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg coordinate = this->result; 1179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 11807c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt bool needs_gl_clamp = true; 11817c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt 11827c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt fs_reg scale_x, scale_y; 11837c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt 1184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* The 965 requires the EU to do the normalization of GL rectangle 1185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * texture coordinates. We use the program parameter state 1186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * tracking to get the scaling factor. 1187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 11887c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT && 11897c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt (intel->gen < 6 || 1190f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke (intel->gen >= 6 && (c->key.tex.gl_clamp_mask[0] & (1 << sampler) || 1191f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke c->key.tex.gl_clamp_mask[1] & (1 << sampler))))) { 1192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt struct gl_program_parameter_list *params = c->fp->program.Base.Parameters; 1193d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int tokens[STATE_LENGTH] = { 1194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt STATE_INTERNAL, 1195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt STATE_TEXRECT_SCALE, 11960ad2dce24aa0475e607e3c58b8aa50057412c6efKenneth Graunke texunit, 1197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 0, 1198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 0 1199d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt }; 1200d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dispatch_width == 16) { 1202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("rectangle scale uniform setup not supported on 16-wide\n"); 120327bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke return fs_reg(this, ir->type); 1204d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 12067c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt scale_x = fs_reg(UNIFORM, c->prog_data.nr_params); 12077c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1); 12087c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt 1209d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt GLuint index = _mesa_add_state_reference(params, 1210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt (gl_state_index *)tokens); 1211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_index[c->prog_data.nr_params] = index; 1213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_offset[c->prog_data.nr_params] = 0; 1214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.nr_params++; 1215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_index[c->prog_data.nr_params] = index; 1216d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->param_offset[c->prog_data.nr_params] = 1; 1217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->prog_data.nr_params++; 12187c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt } 1219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 12207c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt /* The 965 requires the EU to do the normalization of GL rectangle 12217c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * texture coordinates. We use the program parameter state 12227c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * tracking to get the scaling factor. 12237c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt */ 12247c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt if (intel->gen < 6 && 12257c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) { 1226d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg dst = fs_reg(this, ir->coordinate->type); 1227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src = coordinate; 1228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt coordinate = dst; 1229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MUL, dst, src, scale_x); 1231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst.reg_offset++; 1232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src.reg_offset++; 1233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MUL, dst, src, scale_y); 12347c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt } else if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) { 12357c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt /* On gen6+, the sampler handles the rectangle coordinates 12367c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * natively, without needing rescaling. But that means we have 12377c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * to do GL_CLAMP clamping at the [0, width], [0, height] scale, 12387c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * not [0, 1] like the default case below. 12397c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt */ 12407c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt needs_gl_clamp = false; 12417c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt 12427c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt for (int i = 0; i < 2; i++) { 1243f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) { 12447c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt fs_reg chan = coordinate; 12457c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt chan.reg_offset += i; 12467c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt 12477c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt inst = emit(BRW_OPCODE_SEL, chan, chan, brw_imm_f(0.0)); 12487c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt inst->conditional_mod = BRW_CONDITIONAL_G; 12497c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt 12507c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt /* Our parameter comes in as 1.0/width or 1.0/height, 12517c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * because that's what people normally want for doing 12527c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * texture rectangle handling. We need width or height 12537c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * for clamping, but we don't care enough to make a new 12547c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt * parameter type, so just invert back. 12557c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt */ 12567c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt fs_reg limit = fs_reg(this, glsl_type::float_type); 12577c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt emit(BRW_OPCODE_MOV, limit, i == 0 ? scale_x : scale_y); 12587c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt emit(SHADER_OPCODE_RCP, limit, limit); 12597c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt 12607c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt inst = emit(BRW_OPCODE_SEL, chan, chan, limit); 12617c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt inst->conditional_mod = BRW_CONDITIONAL_L; 12627c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt } 12637c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt } 1264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 126507e621c52329cd17b97051a26493626228d043b9Eric Anholt 12667c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt if (ir->coordinate && needs_gl_clamp) { 12671e188f2daef1ae31224d2429bcc1fab75c81fb36Eric Anholt for (unsigned int i = 0; 12681e188f2daef1ae31224d2429bcc1fab75c81fb36Eric Anholt i < MIN2(ir->coordinate->type->vector_elements, 3); i++) { 1269f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) { 127007e621c52329cd17b97051a26493626228d043b9Eric Anholt fs_reg chan = coordinate; 127107e621c52329cd17b97051a26493626228d043b9Eric Anholt chan.reg_offset += i; 127207e621c52329cd17b97051a26493626228d043b9Eric Anholt 127307e621c52329cd17b97051a26493626228d043b9Eric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, chan, chan); 127407e621c52329cd17b97051a26493626228d043b9Eric Anholt inst->saturate = true; 127507e621c52329cd17b97051a26493626228d043b9Eric Anholt } 127607e621c52329cd17b97051a26493626228d043b9Eric Anholt } 127707e621c52329cd17b97051a26493626228d043b9Eric Anholt } 127827bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke return coordinate; 127927bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke} 128027bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke 128127bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunkevoid 128227bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunkefs_visitor::visit(ir_texture *ir) 128327bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke{ 128427bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke fs_inst *inst = NULL; 128527bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke 128627bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base); 12870ad2dce24aa0475e607e3c58b8aa50057412c6efKenneth Graunke int texunit = fp->Base.SamplerUnits[sampler]; 128827bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke 128927bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke /* Should be lowered by do_lower_texture_projection */ 129027bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke assert(!ir->projector); 129127bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke 1292c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke /* Generate code to compute all the subexpression trees. This has to be 1293c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke * done before loading any values into MRFs for the sampler message since 1294c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke * generating these values may involve SEND messages that need the MRFs. 1295c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke */ 1296f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke fs_reg coordinate = emit_texcoord(ir, sampler, texunit); 1297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1298c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke fs_reg shadow_comparitor; 1299c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke if (ir->shadow_comparitor) { 1300c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke ir->shadow_comparitor->accept(this); 1301c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke shadow_comparitor = this->result; 1302c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke } 1303c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke 1304c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke fs_reg lod, lod2; 1305c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke switch (ir->op) { 1306c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke case ir_tex: 1307c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke break; 1308c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke case ir_txb: 1309c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke ir->lod_info.bias->accept(this); 1310c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod = this->result; 1311c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke break; 1312c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke case ir_txd: 1313c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke ir->lod_info.grad.dPdx->accept(this); 1314c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod = this->result; 1315c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke 1316c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke ir->lod_info.grad.dPdy->accept(this); 1317c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod2 = this->result; 1318c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke break; 1319c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke case ir_txf: 1320c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke case ir_txl: 1321c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke case ir_txs: 1322c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke ir->lod_info.lod->accept(this); 1323c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke lod = this->result; 1324c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke break; 1325c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke }; 1326c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke 1327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Writemasking doesn't eliminate channels on SIMD8 texture 1328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * samples, so don't worry about them. 1329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1330b6bdcf2a908889532ef6d5eb643791176dffcb9dKenneth Graunke fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1)); 1331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 7) { 1333c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor, 1334bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke lod, lod2); 1335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (intel->gen >= 5) { 1336c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor, 1337bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke lod, lod2); 1338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1339c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke inst = emit_texture_gen4(ir, dst, coordinate, shadow_comparitor, 1340bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke lod, lod2); 1341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 134382bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke /* The header is set up by generate_tex() when necessary. */ 134482bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke inst->src[0] = reg_undef; 134582bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke 134682bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke if (ir->offset != NULL && ir->op != ir_txf) 134782bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke inst->texture_offset = brw_texture_offset(ir->offset->as_constant()); 1348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 134985e8e9e000732908b259a7e2cbc1724a1be2d447Kenneth Graunke inst->sampler = sampler; 1350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1351b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke if (ir->shadow_comparitor) 1352b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke inst->shadow_compare = true; 1353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1354f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke swizzle_result(ir, dst, sampler); 135501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke} 135601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke 135701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke/** 135801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * Swizzle the result of a texture result. This is necessary for 135901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons. 136001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke */ 136101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkevoid 1362f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunkefs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler) 136301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke{ 136401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke this->result = orig_val; 136501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke 1366c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke if (ir->op == ir_txs) 1367c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke return; 1368c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke 1369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type == glsl_type::float_type) { 1370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Ignore DEPTH_TEXTURE_MODE swizzling. */ 1371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->sampler->type->sampler_shadow); 1372f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke } else if (c->key.tex.swizzles[sampler] != SWIZZLE_NOOP) { 137301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type); 1374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int i = 0; i < 4; i++) { 1376f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke int swiz = GET_SWZ(c->key.tex.swizzles[sampler], i); 137701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg l = swizzled_result; 1378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt l.reg_offset += i; 1379d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1380d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (swiz == SWIZZLE_ZERO) { 1381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, fs_reg(0.0f)); 1382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (swiz == SWIZZLE_ONE) { 1383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, fs_reg(1.0f)); 1384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 138501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke fs_reg r = orig_val; 1386f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke r.reg_offset += GET_SWZ(c->key.tex.swizzles[sampler], i); 1387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, l, r); 1388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 139001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke this->result = swizzled_result; 1391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_swizzle *ir) 1396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->val->accept(this); 1398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg val = this->result; 1399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type->vector_elements == 1) { 1401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result.reg_offset += ir->mask.x; 1402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg result = fs_reg(this, ir->type); 1406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = result; 1407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < ir->type->vector_elements; i++) { 1409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg channel = val; 1410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int swiz = 0; 1411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (i) { 1413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 0: 1414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.x; 1415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 1: 1417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.y; 1418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 2: 1420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.z; 1421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case 3: 1423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt swiz = ir->mask.w; 1424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt channel.reg_offset += swiz; 1428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, result, channel); 1429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt result.reg_offset++; 1430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_discard *ir) 1435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(ir->condition == NULL); /* FINISHME */ 1437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_DISCARD); 1439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_constant *ir) 1443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Set this->result to reg at the bottom of the function because some code 1445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * paths will cause this visitor to be applied to other fields. This will 1446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * cause the value stored in this->result to be modified. 1447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 1448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Make reg constant so that it doesn't get accidentally modified along the 1449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * way. Yes, I actually had this problem. :( 1450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const fs_reg reg(this, ir->type); 1452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg dst_reg = reg; 1453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->type->is_array()) { 1455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(ir->type->fields.array); 1456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < ir->type->length; i++) { 1458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->array_elements[i]->accept(this); 1459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src_reg = this->result; 1460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.type = src_reg.type; 1462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned j = 0; j < size; j++) { 1463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, src_reg); 1464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src_reg.reg_offset++; 1465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else if (ir->type->is_record()) { 1469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt foreach_list(node, &ir->components) { 1470f75c2d53146ea14f8dfedcc5b7a4704278ba0792Kenneth Graunke ir_constant *const field = (ir_constant *) node; 1471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(field->type); 1472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt field->accept(this); 1474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg src_reg = this->result; 1475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.type = src_reg.type; 1477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned j = 0; j < size; j++) { 1478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, src_reg); 1479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt src_reg.reg_offset++; 1480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const unsigned size = type_size(ir->type); 1485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned i = 0; i < size; i++) { 1487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->type->base_type) { 1488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_FLOAT: 1489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.f[i])); 1490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_UINT: 1492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.u[i])); 1493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_INT: 1495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.i[i])); 1496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case GLSL_TYPE_BOOL: 1498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, dst_reg, fs_reg((int)ir->value.b[i])); 1499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"Non-float/uint/int/bool constant"); 1502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt dst_reg.reg_offset++; 1504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->result = reg; 1508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_bool_to_cond_code(ir_rvalue *ir) 1512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_expression *expr = ir->as_expression(); 1514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (expr) { 1516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2]; 1517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->get_num_operands() <= 2); 1520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < expr->get_num_operands(); i++) { 1521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->operands[i]->type->is_scalar()); 1522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt expr->operands[i]->accept(this); 1524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[i] = this->result; 152573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 152673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt resolve_ud_negate(&op[i]); 1527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (expr->operation) { 1530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 1531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1)); 1532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_Z; 1533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 1536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 1537d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 153880ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt goto out; 1539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 1541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0.0f)); 1543d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1544d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, reg_null_f, op[0]); 1545d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 1550d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6) { 1551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0)); 1552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_MOV, reg_null_d, op[0]); 1554d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1556d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 1559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 1560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 1561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 1562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 1563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 1564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 1565d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 1566dc42910e98dc00760255cc4579da458de09175b9Eric Anholt resolve_bool_comparison(expr->operands[0], &op[0]); 1567dc42910e98dc00760255cc4579da458de09175b9Eric Anholt resolve_bool_comparison(expr->operands[1], &op[1]); 1568dc42910e98dc00760255cc4579da458de09175b9Eric Anholt 1569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]); 1570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = 1571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt brw_conditional_for_comparison(expr->operation); 1572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("bad cond code\n"); 1577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 158280ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholtout: 1583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 158580ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt fs_inst *inst = emit(BRW_OPCODE_AND, reg_null_d, this->result, fs_reg(1)); 158680ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1589d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** 1590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Emit a gen6 IF statement with the comparison folded into the IF 1591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instruction. 1592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_if_gen6(ir_if *ir) 1595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir_expression *expr = ir->condition->as_expression(); 1597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (expr) { 1599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg op[2]; 1600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg temp; 1602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->get_num_operands() <= 2); 1604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (unsigned int i = 0; i < expr->get_num_operands(); i++) { 1605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(expr->operands[i]->type->is_scalar()); 1606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt expr->operands[i]->accept(this); 1608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt op[i] = this->result; 1609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (expr->operation) { 1612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_logic_not: 1613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_xor: 1614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_or: 1615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_logic_and: 1616457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt /* For operations on bool arguments, only the low bit of the bool is 1617457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt * valid, and the others are undefined. Fall back to the condition 1618457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt * code path. 1619457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt */ 1620457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt break; 1621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_f2b: 1623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0)); 1624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_unop_i2b: 1628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0)); 1629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_greater: 1633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_gequal: 1634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_less: 1635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_lequal: 1636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_equal: 1637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_all_equal: 1638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_nequal: 1639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_binop_any_nequal: 1640457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt resolve_bool_comparison(expr->operands[0], &op[0]); 1641457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt resolve_bool_comparison(expr->operands[1], &op[1]); 1642457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt 1643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]); 1644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = 1645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt brw_conditional_for_comparison(expr->operation); 1646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt default: 1648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0)); 1650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = BRW_CONDITIONAL_NZ; 1651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("bad condition\n"); 1652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return; 1653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1656457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt emit_bool_to_cond_code(ir->condition); 1657457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt fs_inst *inst = emit(BRW_OPCODE_IF); 1658457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt inst->predicated = true; 1659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_if *ir) 1663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst; 1665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 166679cba4c2b17456e2b25ac555c45e1c106b4e3f6bKenneth Graunke if (intel->gen < 6 && c->dispatch_width == 16) { 1667d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Can't support (non-uniform) control flow on 16-wide\n"); 1668d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1669d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1670d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Don't point the annotation at the if statement, because then it plus 1671d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * the then and else blocks get printed. 1672d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1673d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->condition; 1674d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1675d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen == 6) { 1676d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_if_gen6(ir); 1677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit_bool_to_cond_code(ir->condition); 1679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1680d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_IF); 1681d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 1682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 168444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->then_instructions) { 168544ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1686d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1687d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (!ir->else_instructions.is_empty()) { 1692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ELSE); 1693d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 169444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->else_instructions) { 169544ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1696d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1697d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1698d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1699d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1701d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ENDIF); 1703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop *ir) 1707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg counter = reg_undef; 1709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 171099cd475cc9d3bd54140f84c24b55b9e05d7310a1Kenneth Graunke if (intel->gen < 6 && c->dispatch_width == 16) { 1711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Can't support (non-uniform) control flow on 16-wide\n"); 1712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->counter) { 1715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->counter; 1716d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->counter->accept(this); 1717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt counter = *(variable_storage(ir->counter)); 1718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->from) { 1720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->from; 1721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->from->accept(this); 1722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1723d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke emit(BRW_OPCODE_MOV, counter, this->result); 1724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1726d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 17278890c759513597903997f519c69e9db30790b6f4Eric Anholt this->base_ir = NULL; 1728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_DO); 1729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->to) { 1731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->to; 1732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->to->accept(this); 1733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result); 1735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->conditional_mod = brw_conditional_for_comparison(ir->cmp); 1736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst = emit(BRW_OPCODE_BREAK); 1738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->predicated = true; 1739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 174144ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &ir->body_instructions) { 174244ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (ir->increment) { 1749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir->increment; 1750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->increment->accept(this); 1751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, counter, counter, this->result); 1752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 17548890c759513597903997f519c69e9db30790b6f4Eric Anholt this->base_ir = NULL; 1755d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_WHILE); 1756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop_jump *ir) 1760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt switch (ir->mode) { 1762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_loop_jump::jump_break: 1763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_BREAK); 1764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt case ir_loop_jump::jump_continue: 1766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_CONTINUE); 1767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt break; 1768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_call *ir) 1773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME"); 1775d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1776d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_return *ir) 1779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"FINISHME"); 1781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function *ir) 1785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 1787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 1788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (strcmp(ir->name, "main") == 0) { 1790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt const ir_function_signature *sig; 1791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt exec_list empty; 1792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt sig = ir->matching_signature(&empty); 1794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(sig); 1796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 179744ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt foreach_list(node, &sig->body) { 179844ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt ir_instruction *ir = (ir_instruction *)node; 1799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->base_ir = ir; 1800d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke 1801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt ir->accept(this); 1802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1804d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function_signature *ir) 1808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(!"not reached"); 1810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt (void)ir; 1811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst * 1814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit(fs_inst inst) 1815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *list_inst = new(mem_ctx) fs_inst; 1817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *list_inst = inst; 1818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (force_uncompressed_stack > 0) 1820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->force_uncompressed = true; 1821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt else if (force_sechalf_stack > 0) 1822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->force_sechalf = true; 1823d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1824d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->annotation = this->current_annotation; 1825d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt list_inst->ir = this->base_ir; 1826d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->instructions.push_tail(list_inst); 1828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1829d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return list_inst; 1830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits a dummy fragment shader consisting of magenta for bringup purposes. */ 1833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_dummy_fs() 1835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1836df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke int reg_width = c->dispatch_width / 8; 1837df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke 1838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Everyone's favorite color. */ 1839df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 0 * reg_width), fs_reg(1.0f)); 1840df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 1 * reg_width), fs_reg(0.0f)); 1841df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 2 * reg_width), fs_reg(1.0f)); 1842df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 3 * reg_width), fs_reg(0.0f)); 1843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1844d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *write; 1845d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0)); 18466750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky write->base_mrf = 2; 1847df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke write->mlen = 4 * reg_width; 1848393b42240f22dbbfb4f089036319031ad36173f3Kenneth Graunke write->eot = true; 1849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1850d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* The register location here is relative to the start of the URB 1852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * data. It will get adjusted to be a real location before 1853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * generate_code() time. 1854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtstruct brw_reg 1856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::interp_reg(int location, int channel) 1857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int regnr = urb_setup[location] * 2 + channel / 2; 1859d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int stride = (channel & 1) * 4; 1860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1861d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(urb_setup[location] != -1); 1862d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt return brw_vec1_grf(regnr, stride); 1864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */ 1867d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1868d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen4() 1869d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1870d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel centers"; 1871d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x = fs_reg(this, glsl_type::uint_type); 1872d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y = fs_reg(this, glsl_type::uint_type); 1873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x.type = BRW_REGISTER_TYPE_UW; 1874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y.type = BRW_REGISTER_TYPE_UW; 1875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_PIXEL_X, this->pixel_x); 1877d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(FS_OPCODE_PIXEL_Y, this->pixel_y); 1878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel deltas from v0"; 1880d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (brw->has_pln) { 1881e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1882e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry fs_reg(this, glsl_type::vec2_type); 1883e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1884e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC]; 1885e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg_offset++; 1886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1887e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1888e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry fs_reg(this, glsl_type::float_type); 1889e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = 1890e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry fs_reg(this, glsl_type::float_type); 1891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 1892e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry emit(BRW_OPCODE_ADD, this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0)))); 1894e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry emit(BRW_OPCODE_ADD, this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1)))); 1896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pos.w and 1/pos.w"; 1898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Compute wpos.w. It's always in our setup, since it's needed to 1899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * interpolate the other attributes. 1900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->wpos_w = fs_reg(this, glsl_type::float_type); 1902e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry emit(FS_OPCODE_LINTERP, wpos_w, 1903e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1904e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], 1905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt interp_reg(FRAG_ATTRIB_WPOS, 3)); 1906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Compute the pixel 1/W value from wpos.w. */ 1907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_w = fs_reg(this, glsl_type::float_type); 190865b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w); 1909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */ 1913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 1914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen6() 1915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW); 1917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* If the pixel centers end up used, the setup is the same as for gen4. */ 1919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pixel centers"; 1920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg int_pixel_x = fs_reg(this, glsl_type::uint_type); 1921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg int_pixel_y = fs_reg(this, glsl_type::uint_type); 1922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_x.type = BRW_REGISTER_TYPE_UW; 1923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_y.type = BRW_REGISTER_TYPE_UW; 1924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, 1925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_x, 1926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)), 1927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_v(0x10101010))); 1928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_ADD, 1929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int_pixel_y, 1930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)), 1931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_imm_v(0x11001100))); 1932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* As of gen6, we can no longer mix float and int sources. We have 1934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * to turn the integer pixel centers into floats for their actual 1935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * use. 1936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 1937d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_x = fs_reg(this, glsl_type::float_type); 1938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_y = fs_reg(this, glsl_type::float_type); 1939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->pixel_x, int_pixel_x); 1940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, this->pixel_y, int_pixel_y); 1941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "compute pos.w"; 1943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->pixel_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0)); 1944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->wpos_w = fs_reg(this, glsl_type::float_type); 194565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w); 1946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1947e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry for (int i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) { 1948e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry uint8_t reg = c->barycentric_coord_reg[i]; 1949e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_x[i] = fs_reg(brw_vec8_grf(reg, 0)); 1950e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry this->delta_y[i] = fs_reg(brw_vec8_grf(reg + 1, 0)); 1951e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry } 1952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 1954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 1955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 1956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 19576d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholtfs_visitor::emit_color_write(int target, int index, int first_color_mrf) 1958d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 1959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 19604fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt fs_inst *inst; 19616d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt fs_reg color = outputs[target]; 19626d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt fs_reg mrf; 19636d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt 19646d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt /* If there's no color data to be written, skip it. */ 19656d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt if (color.file == BAD_FILE) 19666d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt return; 19676d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt 19686d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt color.reg_offset += index; 1969d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 197083df7fbe62be2798d557142a47e01af86ec9e2e2Kenneth Graunke if (c->dispatch_width == 8 || intel->gen >= 6) { 1971d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* SIMD8 write looks like: 1972d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: r1 1974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: g0 1975d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: g1 1976d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * 1977d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * gen6 SIMD16 DP write looks like: 1978d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1979d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: r1 1980d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: g0 1981d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: g1 1982d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 4: b0 1983d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 5: b1 1984d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 6: a0 1985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 7: a1 1986d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 19874fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, 1988e988d816e16f9c0844424472d689486a833931c3Eric Anholt fs_reg(MRF, first_color_mrf + index * reg_width, color.type), 19894fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 19904fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 1991d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 1992d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* pre-gen6 SIMD16 single source DP write looks like: 1993d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 0: r0 1994d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 1: g0 1995d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 2: b0 1996d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 3: a0 1997d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 4: r1 1998d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 5: g1 1999d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 6: b1 2000d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * m + 7: a1 2001d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 2002d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (brw->has_compr4) { 2003d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* By setting the high bit of the MRF register number, we 2004d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * indicate that we want COMPR4 mode - instead of doing the 2005d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * usual destination + 1 for the second half we get 2006d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * destination + 4. 2007d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 20084fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst = emit(BRW_OPCODE_MOV, 2009e988d816e16f9c0844424472d689486a833931c3Eric Anholt fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index, 2010e988d816e16f9c0844424472d689486a833931c3Eric Anholt color.type), 20114fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 20124fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 2013d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 2014d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_uncompressed(); 2015e988d816e16f9c0844424472d689486a833931c3Eric Anholt inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index, 2016e988d816e16f9c0844424472d689486a833931c3Eric Anholt color.type), 20174fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 20184fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 2019d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_uncompressed(); 2020d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2021d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_sechalf(); 2022d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.sechalf = true; 2023e988d816e16f9c0844424472d689486a833931c3Eric Anholt inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4, 2024e988d816e16f9c0844424472d689486a833931c3Eric Anholt color.type), 20254fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt color); 20264fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt inst->saturate = c->key.clamp_fragment_color; 2027d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_sechalf(); 2028d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt color.sechalf = false; 2029d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2030d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2031d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 2032d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2033d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid 2034d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_fb_writes() 2035d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{ 2036d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = "FB write header"; 20372e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke bool header_present = true; 2038b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke /* We can potentially have a message length of up to 15, so we have to set 2039b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke * base_mrf to either 0 or 1 in order to fit in m0..m15. 2040b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke */ 2041b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke int base_mrf = 1; 2042eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke int nr = base_mrf; 2043d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int reg_width = c->dispatch_width / 8; 204429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt bool do_dual_src = this->dual_src_output.file != BAD_FILE; 2045e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat bool src0_alpha_to_render_target = false; 2046d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 204729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt if (c->dispatch_width == 16 && do_dual_src) { 204829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fail("GL_ARB_blend_func_extended not yet supported in 16-wide."); 204929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt do_dual_src = false; 205029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt } 205129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt 205229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt /* From the Sandy Bridge PRM, volume 4, page 198: 205329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt * 205429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt * "Dispatched Pixel Enables. One bit per pixel indicating 205529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt * which pixels were originally enabled when the thread was 205629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt * dispatched. This field is only required for the end-of- 205729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt * thread message and on all dual-source messages." 205829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt */ 2059d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen >= 6 && 20609544e44262651a51ffdb3a572f99f902807a6205Paul Berry !this->fp->UsesKill && 206129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt !do_dual_src && 2062d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt c->key.nr_color_regions == 1) { 2063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt header_present = false; 2064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2066d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (header_present) { 2067e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat src0_alpha_to_render_target = intel->gen >= 6 && 2068e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat !do_dual_src && 2069e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat c->key.nr_color_regions > 1 && 2070e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat c->key.sample_alpha_to_coverage; 20716750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky /* m2, m3 header */ 2072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += 2; 2073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2074d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2075d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->aa_dest_stencil_reg) { 2076d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt push_force_uncompressed(); 2077d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr++), 2078d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->aa_dest_stencil_reg, 0))); 2079d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt pop_force_uncompressed(); 2080d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2081d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2082d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Reserve space for color. It'll be filled in per MRT below. */ 2083d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt int color_mrf = nr; 2084d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += 4 * reg_width; 208529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt if (do_dual_src) 208629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt nr += 4; 2087e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat if (src0_alpha_to_render_target) 2088e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat nr += reg_width; 2089d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2090d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->source_depth_to_render_target) { 2091d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (intel->gen == 6 && c->dispatch_width == 16) { 2092d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* For outputting oDepth on gen6, SIMD8 writes have to be 2093d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * used. This would require 8-wide moves of each half to 2094d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * message regs, kind of like pre-gen5 SIMD16 FB writes. 2095d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Just bail on doing so for now. 2096d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */ 2097d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fail("Missing support for simd16 depth writes on gen6\n"); 2098d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2099d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->computes_depth) { 2101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Hand over gl_FragDepth. */ 2102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt assert(this->frag_depth); 2103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg depth = *(variable_storage(this->frag_depth)); 2104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), depth); 2106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } else { 2107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt /* Pass through the payload depth. */ 2108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), 2109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->source_depth_reg, 0))); 2110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += reg_width; 2112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->dest_depth_reg) { 2115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), 2116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_reg(brw_vec8_grf(c->dest_depth_reg, 0))); 2117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt nr += reg_width; 2118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 212029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt if (do_dual_src) { 212129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fs_reg src0 = this->outputs[0]; 212229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fs_reg src1 = this->dual_src_output; 212329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt 212429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt this->current_annotation = ralloc_asprintf(this->mem_ctx, 212529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt "FB write src0"); 212629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt for (int i = 0; i < 4; i++) { 212729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, 212829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fs_reg(MRF, color_mrf + i, src0.type), 212929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt src0); 213029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt src0.reg_offset++; 213129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt inst->saturate = c->key.clamp_fragment_color; 213229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt } 213329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt 213429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt this->current_annotation = ralloc_asprintf(this->mem_ctx, 213529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt "FB write src1"); 213629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt for (int i = 0; i < 4; i++) { 213729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fs_inst *inst = emit(BRW_OPCODE_MOV, 213829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fs_reg(MRF, color_mrf + 4 + i, src1.type), 213929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt src1); 214029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt src1.reg_offset++; 214129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt inst->saturate = c->key.clamp_fragment_color; 214229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt } 214329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt 214429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt fs_inst *inst = emit(FS_OPCODE_FB_WRITE); 214529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt inst->target = 0; 214629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt inst->base_mrf = base_mrf; 214729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt inst->mlen = nr - base_mrf; 214829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt inst->eot = true; 214929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt inst->header_present = header_present; 215029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt 215129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt c->prog_data.dual_src_blend = true; 215229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt this->current_annotation = NULL; 215329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt return; 215429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt } 215529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt 2156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt for (int target = 0; target < c->key.nr_color_regions; target++) { 2157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = ralloc_asprintf(this->mem_ctx, 2158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt "FB write target %d", 2159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt target); 2160e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat /* If src0_alpha_to_render_target is true, include source zero alpha 2161e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat * data in RenderTargetWrite message for targets > 0. 2162e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat */ 2163e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat int write_color_mrf = color_mrf; 2164e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat if (src0_alpha_to_render_target && target != 0) { 2165e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat fs_inst *inst; 2166e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat fs_reg color = outputs[0]; 2167e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat color.reg_offset += 3; 2168e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat 2169e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat inst = emit(BRW_OPCODE_MOV, 2170e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat fs_reg(MRF, write_color_mrf, color.type), 2171e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat color); 2172e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat inst->saturate = c->key.clamp_fragment_color; 2173e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat write_color_mrf = color_mrf + reg_width; 2174e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat } 2175e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat 21762f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke for (unsigned i = 0; i < this->output_components[target]; i++) 2177e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat emit_color_write(target, i, write_color_mrf); 2178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(FS_OPCODE_FB_WRITE); 2180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->target = target; 2181eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->base_mrf = base_mrf; 2182e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat if (src0_alpha_to_render_target && target == 0) 2183e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat inst->mlen = nr - base_mrf - reg_width; 2184e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat else 2185e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat inst->mlen = nr - base_mrf; 2186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (target == c->key.nr_color_regions - 1) 2187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->eot = true; 2188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 2189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt if (c->key.nr_color_regions == 0) { 219286e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke /* Even if there's no color buffers enabled, we still need to send 219386e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke * alpha out the pipeline to our null renderbuffer to support 219486e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke * alpha-testing, alpha-to-coverage, and so on. 219586e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke */ 219686e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke emit_color_write(0, 3, color_mrf); 2197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt fs_inst *inst = emit(FS_OPCODE_FB_WRITE); 2199eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->base_mrf = base_mrf; 2200eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke inst->mlen = nr - base_mrf; 2201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->eot = true; 2202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt inst->header_present = header_present; 2203d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt } 2204d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt 2205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt this->current_annotation = NULL; 2206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt} 220773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 220873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtvoid 220973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtfs_visitor::resolve_ud_negate(fs_reg *reg) 221073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt{ 221173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt if (reg->type != BRW_REGISTER_TYPE_UD || 221273b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt !reg->negate) 221373b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt return; 221473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt 221573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt fs_reg temp = fs_reg(this, glsl_type::uint_type); 221673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt emit(BRW_OPCODE_MOV, temp, *reg); 221773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt *reg = temp; 221873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt} 2219dc42910e98dc00760255cc4579da458de09175b9Eric Anholt 2220dc42910e98dc00760255cc4579da458de09175b9Eric Anholtvoid 2221dc42910e98dc00760255cc4579da458de09175b9Eric Anholtfs_visitor::resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg) 2222dc42910e98dc00760255cc4579da458de09175b9Eric Anholt{ 2223dc42910e98dc00760255cc4579da458de09175b9Eric Anholt if (rvalue->type != glsl_type::bool_type) 2224dc42910e98dc00760255cc4579da458de09175b9Eric Anholt return; 2225dc42910e98dc00760255cc4579da458de09175b9Eric Anholt 2226dc42910e98dc00760255cc4579da458de09175b9Eric Anholt fs_reg temp = fs_reg(this, glsl_type::bool_type); 2227dc42910e98dc00760255cc4579da458de09175b9Eric Anholt emit(BRW_OPCODE_AND, temp, *reg, fs_reg(1)); 2228dc42910e98dc00760255cc4579da458de09175b9Eric Anholt *reg = temp; 2229dc42910e98dc00760255cc4579da458de09175b9Eric Anholt} 2230fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt 2231fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholtfs_visitor::fs_visitor(struct brw_wm_compile *c, struct gl_shader_program *prog, 2232fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt struct brw_shader *shader) 2233fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt{ 2234fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->c = c; 2235fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->p = &c->func; 2236fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->brw = p->brw; 2237fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->fp = (struct gl_fragment_program *) 2238fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program; 2239fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->prog = prog; 2240fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->intel = &brw->intel; 2241fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->ctx = &intel->ctx; 2242fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->mem_ctx = ralloc_context(NULL); 2243fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->shader = shader; 2244fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->failed = false; 2245fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->variable_ht = hash_table_ctor(0, 2246fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt hash_table_pointer_hash, 2247fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt hash_table_pointer_compare); 2248fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt 2249fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt /* There's a question that appears to be left open in the spec: 2250fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * How do implicit dst conversions interact with the CMP 2251fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * instruction or conditional mods? On gen6, the instruction: 2252fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * 2253fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * CMP null<d> src0<f> src1<f> 2254fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * 2255fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * will do src1 - src0 and compare that result as if it was an 2256fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * integer. On gen4, it will do src1 - src0 as float, convert 2257fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * the result to int, and compare as int. In between, it 2258fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * appears that it does src1 - src0 and does the compare in the 2259fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt * execution type so dst type doesn't matter. 2260fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt */ 2261fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt if (this->intel->gen > 4) 2262fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->reg_null_cmp = reg_null_d; 2263fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt else 2264fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->reg_null_cmp = reg_null_f; 2265fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt 2266fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->frag_depth = NULL; 2267fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt memset(this->outputs, 0, sizeof(this->outputs)); 22686928bea7ca1f2ed308d8255c6816f44467306255Kenneth Graunke memset(this->output_components, 0, sizeof(this->output_components)); 2269fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->first_non_payload_grf = 0; 2270fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->max_grf = intel->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF; 2271fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt 2272fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->current_annotation = NULL; 2273fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->base_ir = NULL; 2274fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt 2275fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->virtual_grf_sizes = NULL; 2276a6411520b40d59a8806289c7aaea4a6b26a54443Eric Anholt this->virtual_grf_count = 0; 2277fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->virtual_grf_array_size = 0; 2278fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->virtual_grf_def = NULL; 2279fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->virtual_grf_use = NULL; 2280fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->live_intervals_valid = false; 2281fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt 2282fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->force_uncompressed_stack = 0; 2283fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt this->force_sechalf_stack = 0; 2284fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt} 2285fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt 2286fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholtfs_visitor::~fs_visitor() 2287fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt{ 2288fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt ralloc_free(this->mem_ctx); 2289fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt hash_table_dtor(this->variable_ht); 2290fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt} 2291