142542f5fSchristos/* 242542f5fSchristos * Copyright © 2013 Intel Corporation 342542f5fSchristos * 442542f5fSchristos * Permission is hereby granted, free of charge, to any person obtaining a 542542f5fSchristos * copy of this software and associated documentation files (the "Software"), 642542f5fSchristos * to deal in the Software without restriction, including without limitation 742542f5fSchristos * the rights to use, copy, modify, merge, publish, distribute, sublicense, 842542f5fSchristos * and/or sell copies of the Software, and to permit persons to whom the 942542f5fSchristos * Software is furnished to do so, subject to the following conditions: 1042542f5fSchristos * 1142542f5fSchristos * The above copyright notice and this permission notice (including the next 1242542f5fSchristos * paragraph) shall be included in all copies or substantial portions of the 1342542f5fSchristos * Software. 1442542f5fSchristos * 1542542f5fSchristos * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1642542f5fSchristos * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1742542f5fSchristos * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1842542f5fSchristos * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1942542f5fSchristos * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2042542f5fSchristos * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2142542f5fSchristos * IN THE SOFTWARE. 2242542f5fSchristos */ 2342542f5fSchristos 2442542f5fSchristos#ifdef HAVE_CONFIG_H 2542542f5fSchristos#include "config.h" 2642542f5fSchristos#endif 2742542f5fSchristos 2842542f5fSchristos#include <string.h> 2942542f5fSchristos 3042542f5fSchristos#include "compiler.h" 3142542f5fSchristos#include "brw/brw.h" 3242542f5fSchristos#include "gen8_eu.h" 3342542f5fSchristos 3442542f5fSchristos#ifndef ARRAY_SIZE 3542542f5fSchristos#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) 3642542f5fSchristos#endif 3742542f5fSchristos 3842542f5fSchristos/* EU ISA */ 3942542f5fSchristos 4042542f5fSchristos#define MRF_HACK_START 111 4142542f5fSchristos 4242542f5fSchristosstruct gen8_instruction { 4342542f5fSchristos uint32_t data[4]; 4442542f5fSchristos}; 4542542f5fSchristos 4642542f5fSchristosstatic inline unsigned 4742542f5fSchristos__gen8_mask(unsigned high, unsigned low) 4842542f5fSchristos{ 4942542f5fSchristos assert(high >= low); 5042542f5fSchristos return (1 << (high - low + 1)) - 1; 5142542f5fSchristos} 5242542f5fSchristos 5342542f5fSchristos/** 5442542f5fSchristos * Fetch a set of contiguous bits from the instruction. 5542542f5fSchristos * 5642542f5fSchristos * Bits indexes range from 0..127; fields may not cross 32-bit boundaries. 5742542f5fSchristos */ 5842542f5fSchristosstatic inline unsigned 5942542f5fSchristos__gen8_bits(struct gen8_instruction *insn, unsigned high, unsigned low) 6042542f5fSchristos{ 6142542f5fSchristos /* We assume the field doesn't cross 32-bit boundaries. */ 6242542f5fSchristos const unsigned word = high / 32; 6342542f5fSchristos 6442542f5fSchristos assert(word == low / 32); 6542542f5fSchristos 6642542f5fSchristos high %= 32; 6742542f5fSchristos low %= 32; 6842542f5fSchristos 6942542f5fSchristos return (insn->data[word] >> low) & __gen8_mask(high, low); 7042542f5fSchristos} 7142542f5fSchristos 7242542f5fSchristos/** 7342542f5fSchristos * Set bits in the instruction, with proper shifting and masking. 7442542f5fSchristos * 7542542f5fSchristos * Bits indexes range from 0..127; fields may not cross 32-bit boundaries. 7642542f5fSchristos */ 7742542f5fSchristosstatic inline void 7842542f5fSchristos__gen8_set_bits(struct gen8_instruction *insn, 7942542f5fSchristos unsigned high, 8042542f5fSchristos unsigned low, 8142542f5fSchristos unsigned value) 8242542f5fSchristos{ 8342542f5fSchristos const unsigned word = high / 32; 8442542f5fSchristos unsigned mask; 8542542f5fSchristos 8642542f5fSchristos assert(word == low / 32); 8742542f5fSchristos 8842542f5fSchristos high %= 32; 8942542f5fSchristos low %= 32; 9042542f5fSchristos assert(value < __gen8_mask(high, low) + 1); 9142542f5fSchristos 9242542f5fSchristos mask = __gen8_mask(high, low) << low; 9342542f5fSchristos insn->data[word] &= ~mask; 9442542f5fSchristos insn->data[word] |= (value << low) & mask; 9542542f5fSchristos 9642542f5fSchristos assert(__gen8_bits(insn, 32*word+high, 32*word+low) == value); 9742542f5fSchristos} 9842542f5fSchristos 9942542f5fSchristos#define F(name, high, low) \ 10042542f5fSchristosstatic inline void __gen8_set_##name(struct gen8_instruction *insn, unsigned v) \ 10142542f5fSchristos{ \ 10242542f5fSchristos __gen8_set_bits(insn, high, low, v); \ 10342542f5fSchristos} \ 10442542f5fSchristosstatic inline unsigned __gen8_##name(struct gen8_instruction *insn) \ 10542542f5fSchristos{ \ 10642542f5fSchristos return __gen8_bits(insn, high, low); \ 10742542f5fSchristos} 10842542f5fSchristos 10942542f5fSchristos/** 11042542f5fSchristos* Direct addressing only: 11142542f5fSchristos* @{ 11242542f5fSchristos*/ 11342542f5fSchristosF(src1_da_reg_nr, 108, 101); 11442542f5fSchristosF(src0_da_reg_nr, 76, 69); 11542542f5fSchristosF(dst_da1_hstride, 62, 61); 11642542f5fSchristosF(dst_da_reg_nr, 60, 53); 11742542f5fSchristosF(dst_da16_subreg_nr, 52, 52); 11842542f5fSchristosF(dst_da1_subreg_nr, 52, 48); 11942542f5fSchristosF(da16_writemask, 51, 48); /* Dst.ChanEn */ 12042542f5fSchristos/** @} */ 12142542f5fSchristos 12242542f5fSchristosF(src1_vert_stride, 120, 117) 12342542f5fSchristosF(src1_da1_width, 116, 114) 12442542f5fSchristosF(src1_da16_swiz_w, 115, 114) 12542542f5fSchristosF(src1_da16_swiz_z, 113, 112) 12642542f5fSchristosF(src1_da1_hstride, 113, 112) 12742542f5fSchristosF(src1_address_mode, 111, 111) 12842542f5fSchristos/** Src1.SrcMod @{ */ 12942542f5fSchristosF(src1_negate, 110, 110) 13042542f5fSchristosF(src1_abs, 109, 109) 13142542f5fSchristos/** @} */ 13242542f5fSchristosF(src1_da16_subreg_nr, 100, 100) 13342542f5fSchristosF(src1_da1_subreg_nr, 100, 96) 13442542f5fSchristosF(src1_da16_swiz_y, 99, 98) 13542542f5fSchristosF(src1_da16_swiz_x, 97, 96) 13642542f5fSchristosF(src1_reg_type, 94, 91) 13742542f5fSchristosF(src1_reg_file, 90, 89) 13842542f5fSchristosF(src0_vert_stride, 88, 85) 13942542f5fSchristosF(src0_da1_width, 84, 82) 14042542f5fSchristosF(src0_da16_swiz_w, 83, 82) 14142542f5fSchristosF(src0_da16_swiz_z, 81, 80) 14242542f5fSchristosF(src0_da1_hstride, 81, 80) 14342542f5fSchristosF(src0_address_mode, 79, 79) 14442542f5fSchristos/** Src0.SrcMod @{ */ 14542542f5fSchristosF(src0_negate, 78, 78) 14642542f5fSchristosF(src0_abs, 77, 77) 14742542f5fSchristos/** @} */ 14842542f5fSchristosF(src0_da16_subreg_nr, 68, 68) 14942542f5fSchristosF(src0_da1_subreg_nr, 68, 64) 15042542f5fSchristosF(src0_da16_swiz_y, 67, 66) 15142542f5fSchristosF(src0_da16_swiz_x, 65, 64) 15242542f5fSchristosF(dst_address_mode, 63, 63) 15342542f5fSchristosF(src0_reg_type, 46, 43) 15442542f5fSchristosF(src0_reg_file, 42, 41) 15542542f5fSchristosF(dst_reg_type, 40, 37) 15642542f5fSchristosF(dst_reg_file, 36, 35) 15742542f5fSchristosF(mask_control, 34, 34) 15842542f5fSchristosF(flag_reg_nr, 33, 33) 15942542f5fSchristosF(flag_subreg_nr, 32, 32) 16042542f5fSchristosF(saturate, 31, 31) 16142542f5fSchristosF(branch_control, 30, 30) 16242542f5fSchristosF(debug_control, 30, 30) 16342542f5fSchristosF(cmpt_control, 29, 29) 16442542f5fSchristosF(acc_wr_control, 28, 28) 16542542f5fSchristosF(cond_modifier, 27, 24) 16642542f5fSchristosF(exec_size, 23, 21) 16742542f5fSchristosF(pred_inv, 20, 20) 16842542f5fSchristosF(pred_control, 19, 16) 16942542f5fSchristosF(thread_control, 15, 14) 17042542f5fSchristosF(qtr_control, 13, 12) 17142542f5fSchristosF(nib_control, 11, 11) 17242542f5fSchristosF(dep_control, 10, 9) 17342542f5fSchristosF(access_mode, 8, 8) 17442542f5fSchristos/* Bit 7 is Reserved (for future Opcode expansion) */ 17542542f5fSchristosF(opcode, 6, 0) 17642542f5fSchristos 17742542f5fSchristos/** 17842542f5fSchristos* Three-source instructions: 17942542f5fSchristos* @{ 18042542f5fSchristos*/ 18142542f5fSchristosF(src2_3src_reg_nr, 125, 118) 18242542f5fSchristosF(src2_3src_subreg_nr, 117, 115) 18342542f5fSchristosF(src2_3src_swizzle, 114, 107) 18442542f5fSchristosF(src2_3src_rep_ctrl, 106, 106) 18542542f5fSchristosF(src1_3src_reg_nr, 104, 97) 18642542f5fSchristosF(src1_3src_subreg_hi, 96, 96) 18742542f5fSchristosF(src1_3src_subreg_lo, 95, 94) 18842542f5fSchristosF(src1_3src_swizzle, 93, 86) 18942542f5fSchristosF(src1_3src_rep_ctrl, 85, 85) 19042542f5fSchristosF(src0_3src_reg_nr, 83, 76) 19142542f5fSchristosF(src0_3src_subreg_nr, 75, 73) 19242542f5fSchristosF(src0_3src_swizzle, 72, 65) 19342542f5fSchristosF(src0_3src_rep_ctrl, 64, 64) 19442542f5fSchristosF(dst_3src_reg_nr, 63, 56) 19542542f5fSchristosF(dst_3src_subreg_nr, 55, 53) 19642542f5fSchristosF(dst_3src_writemask, 52, 49) 19742542f5fSchristosF(dst_3src_type, 48, 46) 19842542f5fSchristosF(src_3src_type, 45, 43) 19942542f5fSchristosF(src2_3src_negate, 42, 42) 20042542f5fSchristosF(src2_3src_abs, 41, 41) 20142542f5fSchristosF(src1_3src_negate, 40, 40) 20242542f5fSchristosF(src1_3src_abs, 39, 39) 20342542f5fSchristosF(src0_3src_negate, 38, 38) 20442542f5fSchristosF(src0_3src_abs, 37, 37) 20542542f5fSchristos/** @} */ 20642542f5fSchristos 20742542f5fSchristos/** 20842542f5fSchristos* Fields for SEND messages: 20942542f5fSchristos* @{ 21042542f5fSchristos*/ 21142542f5fSchristosF(eot, 127, 127) 21242542f5fSchristosF(mlen, 124, 121) 21342542f5fSchristosF(rlen, 120, 116) 21442542f5fSchristosF(header_present, 115, 115) 21542542f5fSchristosF(function_control, 114, 96) 21642542f5fSchristosF(sfid, 27, 24) 21742542f5fSchristosF(math_function, 27, 24) 21842542f5fSchristos/** @} */ 21942542f5fSchristos 22042542f5fSchristos/** 22142542f5fSchristos* URB message function control bits: 22242542f5fSchristos* @{ 22342542f5fSchristos*/ 22442542f5fSchristosF(urb_per_slot_offset, 113, 113) 22542542f5fSchristosF(urb_interleave, 111, 111) 22642542f5fSchristosF(urb_global_offset, 110, 100) 22742542f5fSchristosF(urb_opcode, 99, 96) 22842542f5fSchristos/** @} */ 22942542f5fSchristos 23042542f5fSchristos/** 23142542f5fSchristos* Sampler message function control bits: 23242542f5fSchristos* @{ 23342542f5fSchristos*/ 23442542f5fSchristosF(sampler_simd_mode, 114, 113) 23542542f5fSchristosF(sampler_msg_type, 112, 108) 23642542f5fSchristosF(sampler, 107, 104) 23742542f5fSchristosF(binding_table_index, 103, 96) 23842542f5fSchristos/** @} */ 23942542f5fSchristos 24042542f5fSchristos/** 24142542f5fSchristos * Data port message function control bits: 24242542f5fSchristos * @ { 24342542f5fSchristos */ 24442542f5fSchristosF(dp_category, 114, 114) 24542542f5fSchristosF(dp_message_type, 113, 110) 24642542f5fSchristosF(dp_message_control, 109, 104) 24742542f5fSchristosF(dp_binding_table_index, 103, 96) 24842542f5fSchristos/** @} */ 24942542f5fSchristos 25042542f5fSchristos/** 25142542f5fSchristos * Thread Spawn message function control bits: 25242542f5fSchristos * @ { 25342542f5fSchristos */ 25442542f5fSchristosF(ts_resource_select, 100, 100) 25542542f5fSchristosF(ts_request_type, 97, 97) 25642542f5fSchristosF(ts_opcode, 96, 96) 25742542f5fSchristos/** @} */ 25842542f5fSchristos 25942542f5fSchristos/** 26042542f5fSchristos * Video Motion Estimation message function control bits: 26142542f5fSchristos * @ { 26242542f5fSchristos */ 26342542f5fSchristosF(vme_message_type, 110, 109) 26442542f5fSchristosF(vme_binding_table_index, 103, 96) 26542542f5fSchristos/** @} */ 26642542f5fSchristos 26742542f5fSchristos/** 26842542f5fSchristos * Check & Refinement Engine message function control bits: 26942542f5fSchristos * @ { 27042542f5fSchristos */ 27142542f5fSchristosF(cre_message_type, 110, 109) 27242542f5fSchristosF(cre_binding_table_index, 103, 96) 27342542f5fSchristos/** @} */ 27442542f5fSchristos 27542542f5fSchristos#undef F 27642542f5fSchristos 27742542f5fSchristos/** 27842542f5fSchristos* Flow control instruction bits: 27942542f5fSchristos* @{ 28042542f5fSchristos*/ 28142542f5fSchristosstatic inline unsigned __gen8_uip(struct gen8_instruction *insn) 28242542f5fSchristos{ 28342542f5fSchristos return insn->data[2]; 28442542f5fSchristos} 28542542f5fSchristos 28642542f5fSchristosstatic inline void __gen8_set_uip(struct gen8_instruction *insn, unsigned uip) 28742542f5fSchristos{ 28842542f5fSchristos insn->data[2] = uip; 28942542f5fSchristos} 29042542f5fSchristos 29142542f5fSchristosstatic inline unsigned __gen8_jip(struct gen8_instruction *insn) 29242542f5fSchristos{ 29342542f5fSchristos return insn->data[3]; 29442542f5fSchristos} 29542542f5fSchristos 29642542f5fSchristosstatic inline void __gen8_set_jip(struct gen8_instruction *insn, unsigned jip) 29742542f5fSchristos{ 29842542f5fSchristos insn->data[3] = jip; 29942542f5fSchristos} 30042542f5fSchristos/** @} */ 30142542f5fSchristos 30242542f5fSchristosstatic inline int __gen8_src1_imm_d(struct gen8_instruction *insn) 30342542f5fSchristos{ 30442542f5fSchristos return insn->data[3]; 30542542f5fSchristos} 30642542f5fSchristos 30742542f5fSchristosstatic inline unsigned __gen8_src1_imm_ud(struct gen8_instruction *insn) 30842542f5fSchristos{ 30942542f5fSchristos return insn->data[3]; 31042542f5fSchristos} 31142542f5fSchristos 31242542f5fSchristosstatic inline float __gen8_src1_imm_f(struct gen8_instruction *insn) 31342542f5fSchristos{ 31442542f5fSchristos union { 31542542f5fSchristos uint32_t u; 31642542f5fSchristos float f; 31742542f5fSchristos } ft = { insn->data[3] }; 31842542f5fSchristos return ft.f; 31942542f5fSchristos} 32042542f5fSchristos 32142542f5fSchristosstatic void 32242542f5fSchristos__gen8_set_dst(struct brw_compile *p, 32342542f5fSchristos struct gen8_instruction *inst, 32442542f5fSchristos struct brw_reg reg) 32542542f5fSchristos{ 32642542f5fSchristos /* MRFs haven't existed since Gen7, so we better not be using them. */ 32742542f5fSchristos if (reg.file == BRW_MESSAGE_REGISTER_FILE) { 32842542f5fSchristos reg.file = BRW_GENERAL_REGISTER_FILE; 32942542f5fSchristos reg.nr += MRF_HACK_START; 33042542f5fSchristos } 33142542f5fSchristos 33242542f5fSchristos assert(reg.file != BRW_MESSAGE_REGISTER_FILE); 33342542f5fSchristos 33442542f5fSchristos if (reg.file == BRW_GENERAL_REGISTER_FILE) 33542542f5fSchristos assert(reg.nr < BRW_MAX_GRF); 33642542f5fSchristos 33742542f5fSchristos __gen8_set_dst_reg_file(inst, reg.file); 33842542f5fSchristos __gen8_set_dst_reg_type(inst, reg.type); 33942542f5fSchristos 34042542f5fSchristos assert(reg.address_mode == BRW_ADDRESS_DIRECT); 34142542f5fSchristos 34242542f5fSchristos __gen8_set_dst_da_reg_nr(inst, reg.nr); 34342542f5fSchristos 34442542f5fSchristos if (__gen8_access_mode(inst) == BRW_ALIGN_1) { 34542542f5fSchristos /* Set Dst.SubRegNum[4:0] */ 34642542f5fSchristos __gen8_set_dst_da1_subreg_nr(inst, reg.subnr); 34742542f5fSchristos 34842542f5fSchristos /* Set Dst.HorzStride */ 34942542f5fSchristos if (reg.hstride == BRW_HORIZONTAL_STRIDE_0) 35042542f5fSchristos reg.hstride = BRW_HORIZONTAL_STRIDE_1; 35142542f5fSchristos __gen8_set_dst_da1_hstride(inst, reg.hstride); 35242542f5fSchristos } else { 35342542f5fSchristos /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */ 35442542f5fSchristos assert(reg.subnr == 0 || reg.subnr == 16); 35542542f5fSchristos __gen8_set_dst_da16_subreg_nr(inst, reg.subnr >> 4); 35642542f5fSchristos __gen8_set_da16_writemask(inst, reg.dw1.bits.writemask); 35742542f5fSchristos } 35842542f5fSchristos 35942542f5fSchristos#if 1 36042542f5fSchristos if (reg.width == BRW_WIDTH_8 && p->compressed) 36142542f5fSchristos __gen8_set_exec_size(inst, BRW_EXECUTE_16); 36242542f5fSchristos else 36342542f5fSchristos __gen8_set_exec_size(inst, reg.width); 36442542f5fSchristos#else 36542542f5fSchristos if (reg.width < BRW_EXECUTE_8) 36642542f5fSchristos __gen8_set_exec_size(inst, reg.width); 36742542f5fSchristos#endif 36842542f5fSchristos} 36942542f5fSchristos 37042542f5fSchristosstatic void 37142542f5fSchristos__gen8_validate_reg(struct gen8_instruction *inst, struct brw_reg reg) 37242542f5fSchristos{ 37342542f5fSchristos int hstride_for_reg[] = {0, 1, 2, 4}; 37442542f5fSchristos int vstride_for_reg[] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256}; 37542542f5fSchristos int width_for_reg[] = {1, 2, 4, 8, 16}; 37642542f5fSchristos int execsize_for_reg[] = {1, 2, 4, 8, 16}; 37742542f5fSchristos int width, hstride, vstride, execsize; 37842542f5fSchristos 37942542f5fSchristos if (reg.file == BRW_IMMEDIATE_VALUE) { 38042542f5fSchristos /* TODO: check immediate vectors */ 38142542f5fSchristos return; 38242542f5fSchristos } 38342542f5fSchristos 38442542f5fSchristos if (reg.file == BRW_ARCHITECTURE_REGISTER_FILE) 38542542f5fSchristos return; 38642542f5fSchristos 38742542f5fSchristos assert(reg.hstride >= 0 && reg.hstride < ARRAY_SIZE(hstride_for_reg)); 38842542f5fSchristos hstride = hstride_for_reg[reg.hstride]; 38942542f5fSchristos 39042542f5fSchristos if (reg.vstride == 0xf) { 39142542f5fSchristos vstride = -1; 39242542f5fSchristos } else { 39342542f5fSchristos assert(reg.vstride >= 0 && reg.vstride < ARRAY_SIZE(vstride_for_reg)); 39442542f5fSchristos vstride = vstride_for_reg[reg.vstride]; 39542542f5fSchristos } 39642542f5fSchristos 39742542f5fSchristos assert(reg.width >= 0 && reg.width < ARRAY_SIZE(width_for_reg)); 39842542f5fSchristos width = width_for_reg[reg.width]; 39942542f5fSchristos 40042542f5fSchristos assert(__gen8_exec_size(inst) >= 0 && 40142542f5fSchristos __gen8_exec_size(inst) < ARRAY_SIZE(execsize_for_reg)); 40242542f5fSchristos execsize = execsize_for_reg[__gen8_exec_size(inst)]; 40342542f5fSchristos 40442542f5fSchristos /* Restrictions from 3.3.10: Register Region Restrictions. */ 40542542f5fSchristos /* 3. */ 40642542f5fSchristos assert(execsize >= width); 40742542f5fSchristos 40842542f5fSchristos /* 4. */ 40942542f5fSchristos if (execsize == width && hstride != 0) { 41042542f5fSchristos assert(vstride == -1 || vstride == width * hstride); 41142542f5fSchristos } 41242542f5fSchristos 41342542f5fSchristos /* 5. */ 41442542f5fSchristos if (execsize == width && hstride == 0) { 41542542f5fSchristos /* no restriction on vstride. */ 41642542f5fSchristos } 41742542f5fSchristos 41842542f5fSchristos /* 6. */ 41942542f5fSchristos if (width == 1) { 42042542f5fSchristos assert(hstride == 0); 42142542f5fSchristos } 42242542f5fSchristos 42342542f5fSchristos /* 7. */ 42442542f5fSchristos if (execsize == 1 && width == 1) { 42542542f5fSchristos assert(hstride == 0); 42642542f5fSchristos assert(vstride == 0); 42742542f5fSchristos } 42842542f5fSchristos 42942542f5fSchristos /* 8. */ 43042542f5fSchristos if (vstride == 0 && hstride == 0) { 43142542f5fSchristos assert(width == 1); 43242542f5fSchristos } 43342542f5fSchristos 43442542f5fSchristos /* 10. Check destination issues. */ 43542542f5fSchristos} 43642542f5fSchristos 43742542f5fSchristosstatic void 43842542f5fSchristos__gen8_set_src0(struct gen8_instruction *inst, struct brw_reg reg) 43942542f5fSchristos{ 44042542f5fSchristos /* MRFs haven't existed since Gen7, so we better not be using them. */ 44142542f5fSchristos if (reg.file == BRW_MESSAGE_REGISTER_FILE) { 44242542f5fSchristos reg.file = BRW_GENERAL_REGISTER_FILE; 44342542f5fSchristos reg.nr += MRF_HACK_START; 44442542f5fSchristos } 44542542f5fSchristos 44642542f5fSchristos if (reg.file == BRW_GENERAL_REGISTER_FILE) 44742542f5fSchristos assert(reg.nr < BRW_MAX_GRF); 44842542f5fSchristos 44942542f5fSchristos __gen8_validate_reg(inst, reg); 45042542f5fSchristos 45142542f5fSchristos __gen8_set_src0_reg_file(inst, reg.file); 45242542f5fSchristos __gen8_set_src0_reg_type(inst, reg.type); 45342542f5fSchristos __gen8_set_src0_abs(inst, reg.abs); 45442542f5fSchristos __gen8_set_src0_negate(inst, reg.negate); 45542542f5fSchristos 45642542f5fSchristos assert(reg.address_mode == BRW_ADDRESS_DIRECT); 45742542f5fSchristos 45842542f5fSchristos if (reg.file == BRW_IMMEDIATE_VALUE) { 45942542f5fSchristos inst->data[3] = reg.dw1.ud; 46042542f5fSchristos 46142542f5fSchristos /* Required to set some fields in src1 as well: */ 46242542f5fSchristos __gen8_set_src1_reg_file(inst, 0); /* arf */ 46342542f5fSchristos __gen8_set_src1_reg_type(inst, reg.type); 46442542f5fSchristos } else { 46542542f5fSchristos __gen8_set_src0_da_reg_nr(inst, reg.nr); 46642542f5fSchristos 46742542f5fSchristos if (__gen8_access_mode(inst) == BRW_ALIGN_1) { 46842542f5fSchristos /* Set Src0.SubRegNum[4:0] */ 46942542f5fSchristos __gen8_set_src0_da1_subreg_nr(inst, reg.subnr); 47042542f5fSchristos 47142542f5fSchristos if (reg.width == BRW_WIDTH_1 && 47242542f5fSchristos __gen8_exec_size(inst) == BRW_EXECUTE_1) { 47342542f5fSchristos __gen8_set_src0_da1_hstride(inst, BRW_HORIZONTAL_STRIDE_0); 47442542f5fSchristos __gen8_set_src0_vert_stride(inst, BRW_VERTICAL_STRIDE_0); 47542542f5fSchristos } else { 47642542f5fSchristos __gen8_set_src0_da1_hstride(inst, reg.hstride); 47742542f5fSchristos __gen8_set_src0_vert_stride(inst, reg.vstride); 47842542f5fSchristos } 47942542f5fSchristos __gen8_set_src0_da1_width(inst, reg.width); 48042542f5fSchristos } else { 48142542f5fSchristos /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */ 48242542f5fSchristos assert(reg.subnr == 0 || reg.subnr == 16); 48342542f5fSchristos __gen8_set_src0_da16_subreg_nr(inst, reg.subnr >> 4); 48442542f5fSchristos 48542542f5fSchristos __gen8_set_src0_da16_swiz_x(inst, 48642542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 48742542f5fSchristos BRW_CHANNEL_X)); 48842542f5fSchristos __gen8_set_src0_da16_swiz_y(inst, 48942542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 49042542f5fSchristos BRW_CHANNEL_Y)); 49142542f5fSchristos __gen8_set_src0_da16_swiz_z(inst, 49242542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 49342542f5fSchristos BRW_CHANNEL_Z)); 49442542f5fSchristos __gen8_set_src0_da16_swiz_w(inst, 49542542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 49642542f5fSchristos BRW_CHANNEL_W)); 49742542f5fSchristos 49842542f5fSchristos /* This is an oddity of the fact that we're using the same 49942542f5fSchristos * descriptions for registers in both Align16 and Align1 modes. 50042542f5fSchristos */ 50142542f5fSchristos if (reg.vstride == BRW_VERTICAL_STRIDE_8) 50242542f5fSchristos __gen8_set_src0_vert_stride(inst, BRW_VERTICAL_STRIDE_4); 50342542f5fSchristos else 50442542f5fSchristos __gen8_set_src0_vert_stride(inst, reg.vstride); 50542542f5fSchristos } 50642542f5fSchristos } 50742542f5fSchristos} 50842542f5fSchristos 50942542f5fSchristosstatic void 51042542f5fSchristos__gen8_set_src1(struct gen8_instruction *inst, struct brw_reg reg) 51142542f5fSchristos{ 51242542f5fSchristos /* MRFs haven't existed since Gen7, so we better not be using them. */ 51342542f5fSchristos if (reg.file == BRW_MESSAGE_REGISTER_FILE) { 51442542f5fSchristos reg.file = BRW_GENERAL_REGISTER_FILE; 51542542f5fSchristos reg.nr += MRF_HACK_START; 51642542f5fSchristos } 51742542f5fSchristos 51842542f5fSchristos if (reg.file == BRW_GENERAL_REGISTER_FILE) 51942542f5fSchristos assert(reg.nr < BRW_MAX_GRF); 52042542f5fSchristos 52142542f5fSchristos __gen8_validate_reg(inst, reg); 52242542f5fSchristos 52342542f5fSchristos __gen8_set_src1_reg_file(inst, reg.file); 52442542f5fSchristos __gen8_set_src1_reg_type(inst, reg.type); 52542542f5fSchristos __gen8_set_src1_abs(inst, reg.abs); 52642542f5fSchristos __gen8_set_src1_negate(inst, reg.negate); 52742542f5fSchristos 52842542f5fSchristos /* Only src1 can be an immediate in two-argument instructions. */ 52942542f5fSchristos assert(__gen8_src0_reg_file(inst) != BRW_IMMEDIATE_VALUE); 53042542f5fSchristos 53142542f5fSchristos assert(reg.address_mode == BRW_ADDRESS_DIRECT); 53242542f5fSchristos 53342542f5fSchristos if (reg.file == BRW_IMMEDIATE_VALUE) { 53442542f5fSchristos inst->data[3] = reg.dw1.ud; 53542542f5fSchristos } else { 53642542f5fSchristos __gen8_set_src1_da_reg_nr(inst, reg.nr); 53742542f5fSchristos 53842542f5fSchristos if (__gen8_access_mode(inst) == BRW_ALIGN_1) { 53942542f5fSchristos /* Set Src0.SubRegNum[4:0] */ 54042542f5fSchristos __gen8_set_src1_da1_subreg_nr(inst, reg.subnr); 54142542f5fSchristos 54242542f5fSchristos if (reg.width == BRW_WIDTH_1 && 54342542f5fSchristos __gen8_exec_size(inst) == BRW_EXECUTE_1) { 54442542f5fSchristos __gen8_set_src1_da1_hstride(inst, BRW_HORIZONTAL_STRIDE_0); 54542542f5fSchristos __gen8_set_src1_vert_stride(inst, BRW_VERTICAL_STRIDE_0); 54642542f5fSchristos } else { 54742542f5fSchristos __gen8_set_src1_da1_hstride(inst, reg.hstride); 54842542f5fSchristos __gen8_set_src1_vert_stride(inst, reg.vstride); 54942542f5fSchristos } 55042542f5fSchristos __gen8_set_src1_da1_width(inst, reg.width); 55142542f5fSchristos } else { 55242542f5fSchristos /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */ 55342542f5fSchristos assert(reg.subnr == 0 || reg.subnr == 16); 55442542f5fSchristos __gen8_set_src1_da16_subreg_nr(inst, reg.subnr >> 4); 55542542f5fSchristos 55642542f5fSchristos __gen8_set_src1_da16_swiz_x(inst, 55742542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 55842542f5fSchristos BRW_CHANNEL_X)); 55942542f5fSchristos __gen8_set_src1_da16_swiz_y(inst, 56042542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 56142542f5fSchristos BRW_CHANNEL_Y)); 56242542f5fSchristos __gen8_set_src1_da16_swiz_z(inst, 56342542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 56442542f5fSchristos BRW_CHANNEL_Z)); 56542542f5fSchristos __gen8_set_src1_da16_swiz_w(inst, 56642542f5fSchristos BRW_GET_SWZ(reg.dw1.bits.swizzle, 56742542f5fSchristos BRW_CHANNEL_W)); 56842542f5fSchristos 56942542f5fSchristos /* This is an oddity of the fact that we're using the same 57042542f5fSchristos * descriptions for registers in both Align16 and Align1 modes. 57142542f5fSchristos */ 57242542f5fSchristos if (reg.vstride == BRW_VERTICAL_STRIDE_8) 57342542f5fSchristos __gen8_set_src1_vert_stride(inst, BRW_VERTICAL_STRIDE_4); 57442542f5fSchristos else 57542542f5fSchristos __gen8_set_src1_vert_stride(inst, reg.vstride); 57642542f5fSchristos } 57742542f5fSchristos } 57842542f5fSchristos} 57942542f5fSchristos 58042542f5fSchristos/** 58142542f5fSchristos * Set the Message Descriptor and Extended Message Descriptor fields 58242542f5fSchristos * for SEND messages. 58342542f5fSchristos * 58442542f5fSchristos * \note This zeroes out the Function Control bits, so it must be called 58542542f5fSchristos * \b before filling out any message-specific data. Callers can 58642542f5fSchristos * choose not to fill in irrelevant bits; they will be zero. 58742542f5fSchristos */ 58842542f5fSchristosstatic void 58942542f5fSchristos__gen8_set_message_descriptor(struct gen8_instruction *inst, 59042542f5fSchristos enum brw_message_target sfid, 59142542f5fSchristos unsigned msg_length, 59242542f5fSchristos unsigned response_length, 59342542f5fSchristos bool header_present, 59442542f5fSchristos bool end_of_thread) 59542542f5fSchristos{ 59642542f5fSchristos __gen8_set_src1(inst, brw_imm_d(0)); 59742542f5fSchristos 59842542f5fSchristos __gen8_set_sfid(inst, sfid); 59942542f5fSchristos __gen8_set_mlen(inst, msg_length); 60042542f5fSchristos __gen8_set_rlen(inst, response_length); 60142542f5fSchristos __gen8_set_header_present(inst, header_present); 60242542f5fSchristos __gen8_set_eot(inst, end_of_thread); 60342542f5fSchristos} 60442542f5fSchristos 60542542f5fSchristos#if 0 60642542f5fSchristosstatic void 60742542f5fSchristos__gen8_set_urb_message(struct gen8_instruction *inst, 60842542f5fSchristos unsigned opcode, 60942542f5fSchristos unsigned msg_length, 61042542f5fSchristos unsigned response_length, 61142542f5fSchristos bool end_of_thread, 61242542f5fSchristos unsigned offset, 61342542f5fSchristos bool interleave) 61442542f5fSchristos{ 61542542f5fSchristos __gen8_set_message_descriptor(inst, BRW_SFID_URB, msg_length, response_length, 61642542f5fSchristos true, end_of_thread); 61742542f5fSchristos __gen8_set_src0(inst, brw_vec8_grf(MRF_HACK_START + 1, 0)); 61842542f5fSchristos __gen8_set_urb_opcode(inst, 0); /* URB_WRITE_HWORD */ 61942542f5fSchristos __gen8_set_urb_global_offset(inst, offset); 62042542f5fSchristos __gen8_set_urb_interleave(inst, interleave); 62142542f5fSchristos /* per_slot_offset = 0 makes it ignore offsets in message header */ 62242542f5fSchristos __gen8_set_urb_per_slot_offset(inst, 0); 62342542f5fSchristos} 62442542f5fSchristos#endif 62542542f5fSchristos 62642542f5fSchristosstatic void 62742542f5fSchristos__gen8_set_sampler_message(struct gen8_instruction *inst, 62842542f5fSchristos unsigned binding_table_index, 62942542f5fSchristos unsigned sampler, 63042542f5fSchristos unsigned msg_type, 63142542f5fSchristos unsigned response_length, 63242542f5fSchristos unsigned msg_length, 63342542f5fSchristos bool header_present, 63442542f5fSchristos unsigned simd_mode) 63542542f5fSchristos{ 63642542f5fSchristos __gen8_set_message_descriptor(inst, BRW_SFID_SAMPLER, msg_length, 63742542f5fSchristos response_length, header_present, false); 63842542f5fSchristos 63942542f5fSchristos __gen8_set_binding_table_index(inst, binding_table_index); 64042542f5fSchristos __gen8_set_sampler(inst, sampler); 64142542f5fSchristos __gen8_set_sampler_msg_type(inst, msg_type); 64242542f5fSchristos __gen8_set_sampler_simd_mode(inst, simd_mode); 64342542f5fSchristos} 64442542f5fSchristos 64542542f5fSchristosstatic void 64642542f5fSchristos__gen8_set_dp_message(struct gen8_instruction *inst, 64742542f5fSchristos enum brw_message_target sfid, 64842542f5fSchristos unsigned binding_table_index, 64942542f5fSchristos unsigned msg_type, 65042542f5fSchristos unsigned msg_control, 65142542f5fSchristos unsigned mlen, 65242542f5fSchristos unsigned rlen, 65342542f5fSchristos bool header_present, 65442542f5fSchristos bool end_of_thread) 65542542f5fSchristos{ 65642542f5fSchristos /* Binding table index is from 0..255 */ 65742542f5fSchristos assert((binding_table_index & 0xff) == binding_table_index); 65842542f5fSchristos 65942542f5fSchristos /* Message Type is only 5 bits */ 66042542f5fSchristos assert((msg_type & 0x1f) == msg_type); 66142542f5fSchristos 66242542f5fSchristos /* Message Control is only 6 bits */ 66342542f5fSchristos assert((msg_control & 0x3f) == msg_control); 66442542f5fSchristos 66542542f5fSchristos __gen8_set_message_descriptor(inst, sfid, mlen, rlen, header_present, 66642542f5fSchristos end_of_thread); 66742542f5fSchristos __gen8_set_function_control(inst, 66842542f5fSchristos binding_table_index | msg_type << 14 | msg_control << 8); 66942542f5fSchristos} 67042542f5fSchristos 67142542f5fSchristosstatic inline struct gen8_instruction * 67242542f5fSchristosgen8_next_insn(struct brw_compile *p, int opcode) 67342542f5fSchristos{ 67442542f5fSchristos struct gen8_instruction *insn; 67542542f5fSchristos 67642542f5fSchristos assert(p->nr_insn + 1 < BRW_EU_MAX_INSN); 67742542f5fSchristos 67842542f5fSchristos insn = memcpy(&p->store[p->nr_insn++], p->current, sizeof(*insn)); 67942542f5fSchristos __gen8_set_opcode(insn, opcode); 68042542f5fSchristos 68142542f5fSchristos return insn; 68242542f5fSchristos} 68342542f5fSchristos 68442542f5fSchristosstatic void gen8_math(struct brw_compile *p, 68542542f5fSchristos struct brw_reg dst, 68642542f5fSchristos unsigned function, 68742542f5fSchristos unsigned saturate, 68842542f5fSchristos unsigned msg_reg_nr, 68942542f5fSchristos struct brw_reg src, 69042542f5fSchristos unsigned data_type, 69142542f5fSchristos unsigned precision) 69242542f5fSchristos{ 69342542f5fSchristos struct gen8_instruction *insn = gen8_next_insn(p, BRW_OPCODE_MATH); 69442542f5fSchristos 69542542f5fSchristos assert(dst.file == BRW_GENERAL_REGISTER_FILE); 69642542f5fSchristos assert(src.file == BRW_GENERAL_REGISTER_FILE); 69742542f5fSchristos 69842542f5fSchristos assert(dst.hstride == BRW_HORIZONTAL_STRIDE_1); 69942542f5fSchristos assert(src.hstride == BRW_HORIZONTAL_STRIDE_1); 70042542f5fSchristos 70142542f5fSchristos /* Source modifiers are ignored for extended math instructions. */ 70242542f5fSchristos assert(!src.negate); 70342542f5fSchristos assert(!src.abs); 70442542f5fSchristos 70542542f5fSchristos if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT && 70642542f5fSchristos function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) { 70742542f5fSchristos assert(src.type == BRW_REGISTER_TYPE_F); 70842542f5fSchristos } 70942542f5fSchristos 71042542f5fSchristos /* Math is the same ISA format as other opcodes, except that CondModifier 71142542f5fSchristos * becomes FC[3:0] and ThreadCtrl becomes FC[5:4]. 71242542f5fSchristos */ 71342542f5fSchristos __gen8_set_cond_modifier(insn, function); 71442542f5fSchristos __gen8_set_saturate(insn, saturate); 71542542f5fSchristos 71642542f5fSchristos __gen8_set_dst(p, insn, dst); 71742542f5fSchristos __gen8_set_src0(insn, src); 71842542f5fSchristos __gen8_set_src1(insn, brw_null_reg()); 71942542f5fSchristos} 72042542f5fSchristos 72142542f5fSchristosstatic inline void gen8_math_invert(struct brw_compile *p, 72242542f5fSchristos struct brw_reg dst, 72342542f5fSchristos struct brw_reg src) 72442542f5fSchristos{ 72542542f5fSchristos gen8_math(p, 72642542f5fSchristos dst, 72742542f5fSchristos BRW_MATH_FUNCTION_INV, 72842542f5fSchristos BRW_MATH_SATURATE_NONE, 72942542f5fSchristos 0, 73042542f5fSchristos src, 73142542f5fSchristos BRW_MATH_PRECISION_FULL, 73242542f5fSchristos BRW_MATH_DATA_VECTOR); 73342542f5fSchristos 73442542f5fSchristos} 73542542f5fSchristos 73642542f5fSchristos/* Helpers for regular instructions: */ 73742542f5fSchristosstatic inline struct gen8_instruction *gen8_alu1(struct brw_compile *p, 73842542f5fSchristos unsigned opcode, 73942542f5fSchristos struct brw_reg dst, 74042542f5fSchristos struct brw_reg src) 74142542f5fSchristos{ 74242542f5fSchristos struct gen8_instruction *insn = gen8_next_insn(p, opcode); 74342542f5fSchristos __gen8_set_dst(p, insn, dst); 74442542f5fSchristos __gen8_set_src0(insn, src); 74542542f5fSchristos return insn; 74642542f5fSchristos} 74742542f5fSchristos 74842542f5fSchristosstatic inline struct gen8_instruction *gen8_alu2(struct brw_compile *p, 74942542f5fSchristos unsigned opcode, 75042542f5fSchristos struct brw_reg dst, 75142542f5fSchristos struct brw_reg src0, 75242542f5fSchristos struct brw_reg src1) 75342542f5fSchristos{ 75442542f5fSchristos struct gen8_instruction *insn = gen8_next_insn(p, opcode); 75542542f5fSchristos __gen8_set_dst(p, insn, dst); 75642542f5fSchristos __gen8_set_src0(insn, src0); 75742542f5fSchristos __gen8_set_src1(insn, src1); 75842542f5fSchristos return insn; 75942542f5fSchristos} 76042542f5fSchristos 76142542f5fSchristos#define ALU1(OP) \ 76242542f5fSchristosstatic inline struct gen8_instruction *gen8_##OP(struct brw_compile *p, \ 76342542f5fSchristos struct brw_reg dst, \ 76442542f5fSchristos struct brw_reg src0) \ 76542542f5fSchristos{ \ 76642542f5fSchristos return gen8_alu1(p, BRW_OPCODE_##OP, dst, src0); \ 76742542f5fSchristos} 76842542f5fSchristos 76942542f5fSchristos#define ALU2(OP) \ 77042542f5fSchristosstatic inline struct gen8_instruction *gen8_##OP(struct brw_compile *p, \ 77142542f5fSchristos struct brw_reg dst, \ 77242542f5fSchristos struct brw_reg src0, \ 77342542f5fSchristos struct brw_reg src1) \ 77442542f5fSchristos{ \ 77542542f5fSchristos return gen8_alu2(p, BRW_OPCODE_##OP, dst, src0, src1); \ 77642542f5fSchristos} 77742542f5fSchristos 77842542f5fSchristosstatic inline struct gen8_instruction *gen8_ADD(struct brw_compile *p, 77942542f5fSchristos struct brw_reg dst, 78042542f5fSchristos struct brw_reg src0, 78142542f5fSchristos struct brw_reg src1) 78242542f5fSchristos{ 78342542f5fSchristos /* 6.2.2: add */ 78442542f5fSchristos if (src0.type == BRW_REGISTER_TYPE_F || 78542542f5fSchristos (src0.file == BRW_IMMEDIATE_VALUE && 78642542f5fSchristos src0.type == BRW_REGISTER_TYPE_VF)) { 78742542f5fSchristos assert(src1.type != BRW_REGISTER_TYPE_UD); 78842542f5fSchristos assert(src1.type != BRW_REGISTER_TYPE_D); 78942542f5fSchristos } 79042542f5fSchristos 79142542f5fSchristos if (src1.type == BRW_REGISTER_TYPE_F || 79242542f5fSchristos (src1.file == BRW_IMMEDIATE_VALUE && 79342542f5fSchristos src1.type == BRW_REGISTER_TYPE_VF)) { 79442542f5fSchristos assert(src0.type != BRW_REGISTER_TYPE_UD); 79542542f5fSchristos assert(src0.type != BRW_REGISTER_TYPE_D); 79642542f5fSchristos } 79742542f5fSchristos 79842542f5fSchristos return gen8_alu2(p, BRW_OPCODE_ADD, dst, src0, src1); 79942542f5fSchristos} 80042542f5fSchristos 80142542f5fSchristosstatic inline struct gen8_instruction *gen8_MUL(struct brw_compile *p, 80242542f5fSchristos struct brw_reg dst, 80342542f5fSchristos struct brw_reg src0, 80442542f5fSchristos struct brw_reg src1) 80542542f5fSchristos{ 80642542f5fSchristos /* 6.32.38: mul */ 80742542f5fSchristos if (src0.type == BRW_REGISTER_TYPE_D || 80842542f5fSchristos src0.type == BRW_REGISTER_TYPE_UD || 80942542f5fSchristos src1.type == BRW_REGISTER_TYPE_D || 81042542f5fSchristos src1.type == BRW_REGISTER_TYPE_UD) { 81142542f5fSchristos assert(dst.type != BRW_REGISTER_TYPE_F); 81242542f5fSchristos } 81342542f5fSchristos 81442542f5fSchristos if (src0.type == BRW_REGISTER_TYPE_F || 81542542f5fSchristos (src0.file == BRW_IMMEDIATE_VALUE && 81642542f5fSchristos src0.type == BRW_REGISTER_TYPE_VF)) { 81742542f5fSchristos assert(src1.type != BRW_REGISTER_TYPE_UD); 81842542f5fSchristos assert(src1.type != BRW_REGISTER_TYPE_D); 81942542f5fSchristos } 82042542f5fSchristos 82142542f5fSchristos if (src1.type == BRW_REGISTER_TYPE_F || 82242542f5fSchristos (src1.file == BRW_IMMEDIATE_VALUE && 82342542f5fSchristos src1.type == BRW_REGISTER_TYPE_VF)) { 82442542f5fSchristos assert(src0.type != BRW_REGISTER_TYPE_UD); 82542542f5fSchristos assert(src0.type != BRW_REGISTER_TYPE_D); 82642542f5fSchristos } 82742542f5fSchristos 82842542f5fSchristos assert(src0.file != BRW_ARCHITECTURE_REGISTER_FILE || 82942542f5fSchristos src0.nr != BRW_ARF_ACCUMULATOR); 83042542f5fSchristos assert(src1.file != BRW_ARCHITECTURE_REGISTER_FILE || 83142542f5fSchristos src1.nr != BRW_ARF_ACCUMULATOR); 83242542f5fSchristos 83342542f5fSchristos return gen8_alu2(p, BRW_OPCODE_MUL, dst, src0, src1); 83442542f5fSchristos} 83542542f5fSchristos 83642542f5fSchristosALU1(MOV); 83742542f5fSchristosALU2(SEL); 83842542f5fSchristosALU1(NOT); 83942542f5fSchristosALU2(AND); 84042542f5fSchristosALU2(OR); 84142542f5fSchristosALU2(XOR); 84242542f5fSchristosALU2(SHR); 84342542f5fSchristosALU2(SHL); 84442542f5fSchristosALU2(RSR); 84542542f5fSchristosALU2(RSL); 84642542f5fSchristosALU2(ASR); 84742542f5fSchristosALU1(FRC); 84842542f5fSchristosALU1(RNDD); 84942542f5fSchristosALU2(MAC); 85042542f5fSchristosALU2(MACH); 85142542f5fSchristosALU1(LZD); 85242542f5fSchristosALU2(DP4); 85342542f5fSchristosALU2(DPH); 85442542f5fSchristosALU2(DP3); 85542542f5fSchristosALU2(DP2); 85642542f5fSchristosALU2(LINE); 85742542f5fSchristosALU2(PLN); 85842542f5fSchristos 85942542f5fSchristosALU1(RNDZ); 86042542f5fSchristosALU1(RNDE); 86142542f5fSchristos 86242542f5fSchristos#undef ALU1 86342542f5fSchristos#undef ALU2 86442542f5fSchristos 86542542f5fSchristosstatic void gen8_set_compression_control(struct brw_compile *p, 86642542f5fSchristos enum brw_compression compression_control) 86742542f5fSchristos{ 86842542f5fSchristos unsigned v; 86942542f5fSchristos 87042542f5fSchristos p->compressed = compression_control == BRW_COMPRESSION_COMPRESSED; 87142542f5fSchristos 87242542f5fSchristos switch (compression_control) { 87342542f5fSchristos default: assert(0); 87442542f5fSchristos case BRW_COMPRESSION_NONE: v = GEN6_COMPRESSION_1Q; break; 87542542f5fSchristos case BRW_COMPRESSION_2NDHALF: v = GEN6_COMPRESSION_2Q; break; 87642542f5fSchristos case BRW_COMPRESSION_COMPRESSED: v = GEN6_COMPRESSION_1H; break; 87742542f5fSchristos } 87842542f5fSchristos __gen8_set_cmpt_control((struct gen8_instruction *)p->current, v); 87942542f5fSchristos} 88042542f5fSchristos 88142542f5fSchristosstatic inline void gen8_set_mask_control(struct brw_compile *p, unsigned value) 88242542f5fSchristos{ 88342542f5fSchristos __gen8_set_mask_control((struct gen8_instruction *)p->current, value); 88442542f5fSchristos} 88542542f5fSchristos 88642542f5fSchristosstatic inline void gen8_set_saturate(struct brw_compile *p, unsigned value) 88742542f5fSchristos{ 88842542f5fSchristos __gen8_set_saturate((struct gen8_instruction *)p->current, value); 88942542f5fSchristos} 89042542f5fSchristos 89142542f5fSchristosstatic inline void gen8_set_acc_write_control(struct brw_compile *p, unsigned value) 89242542f5fSchristos{ 89342542f5fSchristos __gen8_set_acc_wr_control((struct gen8_instruction *)p->current, value); 89442542f5fSchristos} 89542542f5fSchristos 89642542f5fSchristosstatic void gen8_SAMPLE(struct brw_compile *p, 89742542f5fSchristos struct brw_reg dst, 89842542f5fSchristos unsigned msg_reg_nr, 89942542f5fSchristos unsigned binding_table_index, 90042542f5fSchristos unsigned sampler, 90142542f5fSchristos unsigned writemask, 90242542f5fSchristos unsigned msg_type, 90342542f5fSchristos unsigned response_length, 90442542f5fSchristos unsigned msg_length, 90542542f5fSchristos bool header_present, 90642542f5fSchristos unsigned simd_mode) 90742542f5fSchristos{ 90842542f5fSchristos struct brw_reg src0 = brw_message_reg(msg_reg_nr); 90942542f5fSchristos 91042542f5fSchristos assert(writemask); 91142542f5fSchristos 91242542f5fSchristos if (writemask != WRITEMASK_XYZW) { 91342542f5fSchristos writemask = ~writemask & WRITEMASK_XYZW; 91442542f5fSchristos 91542542f5fSchristos brw_push_insn_state(p); 91642542f5fSchristos 91742542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_NONE); 91842542f5fSchristos gen8_set_mask_control(p, BRW_MASK_DISABLE); 91942542f5fSchristos 92042542f5fSchristos gen8_MOV(p, __retype_ud(src0), __retype_ud(brw_vec8_grf(0,0))); 92142542f5fSchristos gen8_MOV(p, get_element_ud(src0, 2), brw_imm_ud(writemask << 12)); 92242542f5fSchristos 92342542f5fSchristos brw_pop_insn_state(p); 92442542f5fSchristos } 92542542f5fSchristos 92642542f5fSchristos { 92742542f5fSchristos struct gen8_instruction *insn; 92842542f5fSchristos 92942542f5fSchristos insn = gen8_next_insn(p, BRW_OPCODE_SEND); 93042542f5fSchristos __gen8_set_pred_control(insn, 0); /* XXX */ 93142542f5fSchristos __gen8_set_cmpt_control(insn, GEN6_COMPRESSION_1Q); 93242542f5fSchristos 93342542f5fSchristos __gen8_set_dst(p, insn, dst); 93442542f5fSchristos __gen8_set_src0(insn, src0); 93542542f5fSchristos __gen8_set_sampler_message(insn, 93642542f5fSchristos binding_table_index, 93742542f5fSchristos sampler, 93842542f5fSchristos msg_type, 93942542f5fSchristos response_length, 94042542f5fSchristos msg_length, 94142542f5fSchristos header_present, 94242542f5fSchristos simd_mode); 94342542f5fSchristos } 94442542f5fSchristos} 94542542f5fSchristos 94642542f5fSchristos/* shader logic */ 94742542f5fSchristos 94842542f5fSchristosstatic void wm_affine_st(struct brw_compile *p, int dw, int channel, int msg) 94942542f5fSchristos{ 95042542f5fSchristos int uv; 95142542f5fSchristos 95242542f5fSchristos if (dw == 16) { 95342542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); 95442542f5fSchristos uv = 6; 95542542f5fSchristos } else { 95642542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_NONE); 95742542f5fSchristos uv = 4; 95842542f5fSchristos } 95942542f5fSchristos uv += 2*channel; 96042542f5fSchristos 96142542f5fSchristos msg++; 96242542f5fSchristos gen8_PLN(p, 96342542f5fSchristos brw_message_reg(msg), 96442542f5fSchristos brw_vec1_grf(uv, 0), 96542542f5fSchristos brw_vec8_grf(2, 0)); 96642542f5fSchristos msg += dw/8; 96742542f5fSchristos 96842542f5fSchristos gen8_PLN(p, 96942542f5fSchristos brw_message_reg(msg), 97042542f5fSchristos brw_vec1_grf(uv, 4), 97142542f5fSchristos brw_vec8_grf(2, 0)); 97242542f5fSchristos} 97342542f5fSchristos 97442542f5fSchristosstatic inline unsigned simd(int dw) 97542542f5fSchristos{ 97642542f5fSchristos return dw == 16 ? BRW_SAMPLER_SIMD_MODE_SIMD16 : BRW_SAMPLER_SIMD_MODE_SIMD8; 97742542f5fSchristos} 97842542f5fSchristos 97942542f5fSchristosstatic inline struct brw_reg sample_result(int dw, int result) 98042542f5fSchristos{ 98142542f5fSchristos return brw_reg(BRW_GENERAL_REGISTER_FILE, result, 0, 98242542f5fSchristos BRW_REGISTER_TYPE_UW, 98342542f5fSchristos dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8, 98442542f5fSchristos dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8, 98542542f5fSchristos BRW_HORIZONTAL_STRIDE_1, 98642542f5fSchristos BRW_SWIZZLE_XYZW, 98742542f5fSchristos WRITEMASK_XYZW); 98842542f5fSchristos} 98942542f5fSchristos 99042542f5fSchristosstatic int wm_sample(struct brw_compile *p, int dw, 99142542f5fSchristos int channel, int msg, int result) 99242542f5fSchristos{ 99342542f5fSchristos int len = dw == 16 ? 4 : 2; 99442542f5fSchristos gen8_SAMPLE(p, sample_result(dw, result), ++msg, 99542542f5fSchristos channel+1, channel, WRITEMASK_XYZW, 0, 99642542f5fSchristos 2*len, len, false, simd(dw)); 99742542f5fSchristos return result; 99842542f5fSchristos} 99942542f5fSchristos 100042542f5fSchristosstatic int wm_sample__alpha(struct brw_compile *p, int dw, 100142542f5fSchristos int channel, int msg, int result) 100242542f5fSchristos{ 100342542f5fSchristos int mlen, rlen; 100442542f5fSchristos 100542542f5fSchristos if (dw == 8) { 100642542f5fSchristos mlen = 3; 100742542f5fSchristos rlen = 1; 100842542f5fSchristos } else { 100942542f5fSchristos mlen = 5; 101042542f5fSchristos rlen = 2; 101142542f5fSchristos } 101242542f5fSchristos 101342542f5fSchristos gen8_SAMPLE(p, sample_result(dw, result), msg, 101442542f5fSchristos channel+1, channel, WRITEMASK_W, 0, 101542542f5fSchristos rlen, mlen, true, simd(dw)); 101642542f5fSchristos 101742542f5fSchristos return result; 101842542f5fSchristos} 101942542f5fSchristos 102042542f5fSchristosstatic int wm_affine(struct brw_compile *p, int dw, 102142542f5fSchristos int channel, int msg, int result) 102242542f5fSchristos{ 102342542f5fSchristos wm_affine_st(p, dw, channel, msg); 102442542f5fSchristos return wm_sample(p, dw, channel, msg, result); 102542542f5fSchristos} 102642542f5fSchristos 102742542f5fSchristosstatic int wm_affine__alpha(struct brw_compile *p, int dw, 102842542f5fSchristos int channel, int msg, int result) 102942542f5fSchristos{ 103042542f5fSchristos wm_affine_st(p, dw, channel, msg); 103142542f5fSchristos return wm_sample__alpha(p, dw, channel, msg, result); 103242542f5fSchristos} 103342542f5fSchristos 103442542f5fSchristosstatic inline struct brw_reg null_result(int dw) 103542542f5fSchristos{ 103642542f5fSchristos return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0, 103742542f5fSchristos BRW_REGISTER_TYPE_UW, 103842542f5fSchristos dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8, 103942542f5fSchristos dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8, 104042542f5fSchristos BRW_HORIZONTAL_STRIDE_1, 104142542f5fSchristos BRW_SWIZZLE_XYZW, 104242542f5fSchristos WRITEMASK_XYZW); 104342542f5fSchristos} 104442542f5fSchristos 104542542f5fSchristosstatic void fb_write(struct brw_compile *p, int dw) 104642542f5fSchristos{ 104742542f5fSchristos struct gen8_instruction *insn; 104842542f5fSchristos unsigned msg_control, msg_len; 104942542f5fSchristos struct brw_reg src0; 105042542f5fSchristos 105142542f5fSchristos if (dw == 16) { 105242542f5fSchristos msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE; 105342542f5fSchristos msg_len = 8; 105442542f5fSchristos } else { 105542542f5fSchristos msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01; 105642542f5fSchristos msg_len = 4; 105742542f5fSchristos } 105842542f5fSchristos msg_control |= 1 << 4; /* Last Render Target */ 105942542f5fSchristos 106042542f5fSchristos /* The execution mask is ignored for render target writes. */ 106142542f5fSchristos insn = gen8_next_insn(p, BRW_OPCODE_SEND); 106242542f5fSchristos __gen8_set_pred_control(insn, 0); 106342542f5fSchristos __gen8_set_cmpt_control(insn, GEN6_COMPRESSION_1Q); 106442542f5fSchristos 106542542f5fSchristos src0 = brw_message_reg(2); 106642542f5fSchristos 106742542f5fSchristos __gen8_set_dst(p, insn, null_result(dw)); 106842542f5fSchristos __gen8_set_src0(insn, src0); 106942542f5fSchristos __gen8_set_dp_message(insn, 107042542f5fSchristos GEN6_SFID_DATAPORT_RENDER_CACHE, 107142542f5fSchristos 0, 107242542f5fSchristos GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, 107342542f5fSchristos msg_control, 107442542f5fSchristos msg_len, 0, 107542542f5fSchristos false, true); 107642542f5fSchristos} 107742542f5fSchristos 107842542f5fSchristosstatic void wm_write__mask(struct brw_compile *p, int dw, 107942542f5fSchristos int src, int mask) 108042542f5fSchristos{ 108142542f5fSchristos int n; 108242542f5fSchristos 108342542f5fSchristos if (dw == 8) { 108442542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_NONE); 108542542f5fSchristos for (n = 0; n < 4; n++) 108642542f5fSchristos gen8_MUL(p, 108742542f5fSchristos brw_message_reg(2 + n), 108842542f5fSchristos brw_vec8_grf(src + n, 0), 108942542f5fSchristos brw_vec8_grf(mask, 0)); 109042542f5fSchristos } else { 109142542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); 109242542f5fSchristos for (n = 0; n < 4; n++) 109342542f5fSchristos gen8_MUL(p, 109442542f5fSchristos brw_message_reg(2 + 2*n), 109542542f5fSchristos brw_vec8_grf(src + 2*n, 0), 109642542f5fSchristos brw_vec8_grf(mask, 0)); 109742542f5fSchristos } 109842542f5fSchristos 109942542f5fSchristos fb_write(p, dw); 110042542f5fSchristos} 110142542f5fSchristos 110242542f5fSchristosstatic void wm_write__opacity(struct brw_compile *p, int dw, int src, int mask) 110342542f5fSchristos{ 110442542f5fSchristos int n; 110542542f5fSchristos 110642542f5fSchristos if (dw == 8) { 110742542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_NONE); 110842542f5fSchristos for (n = 0; n < 4; n++) 110942542f5fSchristos gen8_MUL(p, 111042542f5fSchristos brw_message_reg(2 + n), 111142542f5fSchristos brw_vec8_grf(src + n, 0), 111242542f5fSchristos brw_vec1_grf(mask, 3)); 111342542f5fSchristos } else { 111442542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); 111542542f5fSchristos for (n = 0; n < 4; n++) 111642542f5fSchristos gen8_MUL(p, 111742542f5fSchristos brw_message_reg(2 + 2*n), 111842542f5fSchristos brw_vec8_grf(src + 2*n, 0), 111942542f5fSchristos brw_vec1_grf(mask, 3)); 112042542f5fSchristos } 112142542f5fSchristos 112242542f5fSchristos fb_write(p, dw); 112342542f5fSchristos} 112442542f5fSchristos 112542542f5fSchristosstatic void wm_write__mask_ca(struct brw_compile *p, int dw, 112642542f5fSchristos int src, int mask) 112742542f5fSchristos{ 112842542f5fSchristos int n; 112942542f5fSchristos 113042542f5fSchristos if (dw == 8) { 113142542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_NONE); 113242542f5fSchristos for (n = 0; n < 4; n++) 113342542f5fSchristos gen8_MUL(p, 113442542f5fSchristos brw_message_reg(2 + n), 113542542f5fSchristos brw_vec8_grf(src + n, 0), 113642542f5fSchristos brw_vec8_grf(mask + n, 0)); 113742542f5fSchristos } else { 113842542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); 113942542f5fSchristos for (n = 0; n < 4; n++) 114042542f5fSchristos gen8_MUL(p, 114142542f5fSchristos brw_message_reg(2 + 2*n), 114242542f5fSchristos brw_vec8_grf(src + 2*n, 0), 114342542f5fSchristos brw_vec8_grf(mask + 2*n, 0)); 114442542f5fSchristos } 114542542f5fSchristos 114642542f5fSchristos fb_write(p, dw); 114742542f5fSchristos} 114842542f5fSchristos 114942542f5fSchristosstatic void gen8_compile_init(struct brw_compile *p) 115042542f5fSchristos{ 115142542f5fSchristos struct gen8_instruction *insn = memset(p->current, 0, sizeof(*insn)); 115242542f5fSchristos COMPILE_TIME_ASSERT(sizeof(*insn) == sizeof(*p->current)); 115342542f5fSchristos __gen8_set_mask_control(insn, BRW_MASK_ENABLE); 115442542f5fSchristos __gen8_set_saturate(insn, 0); 115542542f5fSchristos __gen8_set_cmpt_control(insn, GEN6_COMPRESSION_1Q); 115642542f5fSchristos //__gen8_set_pred_control(insn, 0xf); 115742542f5fSchristos} 115842542f5fSchristos 115942542f5fSchristosbool 116042542f5fSchristosgen8_wm_kernel__affine(struct brw_compile *p, int dispatch) 116142542f5fSchristos{ 116242542f5fSchristos gen8_compile_init(p); 116342542f5fSchristos 116413496ba1Ssnj wm_affine(p, dispatch, 0, 10, MRF_HACK_START+2); 116513496ba1Ssnj fb_write(p, dispatch); 116642542f5fSchristos return true; 116742542f5fSchristos} 116842542f5fSchristos 116942542f5fSchristosbool 117042542f5fSchristosgen8_wm_kernel__affine_mask(struct brw_compile *p, int dispatch) 117142542f5fSchristos{ 117242542f5fSchristos int src, mask; 117342542f5fSchristos 117442542f5fSchristos gen8_compile_init(p); 117542542f5fSchristos 117642542f5fSchristos src = wm_affine(p, dispatch, 0, 1, 12); 117742542f5fSchristos mask = wm_affine__alpha(p, dispatch, 1, 6, 20); 117842542f5fSchristos wm_write__mask(p, dispatch, src, mask); 117942542f5fSchristos 118042542f5fSchristos return true; 118142542f5fSchristos} 118242542f5fSchristos 118342542f5fSchristosbool 118442542f5fSchristosgen8_wm_kernel__affine_mask_ca(struct brw_compile *p, int dispatch) 118542542f5fSchristos{ 118642542f5fSchristos int src, mask; 118742542f5fSchristos 118842542f5fSchristos gen8_compile_init(p); 118942542f5fSchristos 119042542f5fSchristos src = wm_affine(p, dispatch, 0, 1, 12); 119142542f5fSchristos mask = wm_affine(p, dispatch, 1, 6, 20); 119242542f5fSchristos wm_write__mask_ca(p, dispatch, src, mask); 119342542f5fSchristos 119442542f5fSchristos return true; 119542542f5fSchristos} 119642542f5fSchristos 119742542f5fSchristosbool 119842542f5fSchristosgen8_wm_kernel__affine_mask_sa(struct brw_compile *p, int dispatch) 119942542f5fSchristos{ 120042542f5fSchristos int src, mask; 120142542f5fSchristos 120242542f5fSchristos gen8_compile_init(p); 120342542f5fSchristos 120442542f5fSchristos src = wm_affine__alpha(p, dispatch, 0, 1, 12); 120542542f5fSchristos mask = wm_affine(p, dispatch, 1, 6, 16); 120642542f5fSchristos wm_write__mask(p, dispatch, mask, src); 120742542f5fSchristos 120842542f5fSchristos return true; 120942542f5fSchristos} 121042542f5fSchristos 121142542f5fSchristos/* Projective variants */ 121242542f5fSchristos 121342542f5fSchristosstatic void wm_projective_st(struct brw_compile *p, int dw, 121442542f5fSchristos int channel, int msg) 121542542f5fSchristos{ 121642542f5fSchristos int uv; 121742542f5fSchristos 121842542f5fSchristos gen8_compile_init(p); 121942542f5fSchristos 122042542f5fSchristos if (dw == 16) { 122142542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); 122242542f5fSchristos uv = 6; 122342542f5fSchristos } else { 122442542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_NONE); 122542542f5fSchristos uv = 4; 122642542f5fSchristos } 122742542f5fSchristos uv += 2*channel; 122842542f5fSchristos 122942542f5fSchristos msg++; 123042542f5fSchristos /* First compute 1/z */ 123142542f5fSchristos gen8_PLN(p, 123242542f5fSchristos brw_vec8_grf(30, 0), 123342542f5fSchristos brw_vec1_grf(uv+1, 0), 123442542f5fSchristos brw_vec8_grf(2, 0)); 123542542f5fSchristos 123642542f5fSchristos if (dw == 16) { 123742542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_NONE); 123842542f5fSchristos gen8_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); 123942542f5fSchristos gen8_math_invert(p, brw_vec8_grf(31, 0), brw_vec8_grf(31, 0)); 124042542f5fSchristos gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); 124142542f5fSchristos } else 124242542f5fSchristos gen8_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); 124342542f5fSchristos 124442542f5fSchristos gen8_PLN(p, 124542542f5fSchristos brw_vec8_grf(26, 0), 124642542f5fSchristos brw_vec1_grf(uv, 0), 124742542f5fSchristos brw_vec8_grf(2, 0)); 124842542f5fSchristos gen8_PLN(p, 124942542f5fSchristos brw_vec8_grf(28, 0), 125013496ba1Ssnj brw_vec1_grf(uv, 4), 125113496ba1Ssnj brw_vec8_grf(2, 0)); 125242542f5fSchristos 125342542f5fSchristos gen8_MUL(p, 125442542f5fSchristos brw_message_reg(msg), 125542542f5fSchristos brw_vec8_grf(26, 0), 125642542f5fSchristos brw_vec8_grf(30, 0)); 125742542f5fSchristos gen8_MUL(p, 125842542f5fSchristos brw_message_reg(msg + dw/8), 125942542f5fSchristos brw_vec8_grf(28, 0), 126042542f5fSchristos brw_vec8_grf(30, 0)); 126142542f5fSchristos} 126242542f5fSchristos 126342542f5fSchristosstatic int wm_projective(struct brw_compile *p, int dw, 126442542f5fSchristos int channel, int msg, int result) 126542542f5fSchristos{ 126642542f5fSchristos gen8_compile_init(p); 126742542f5fSchristos 126842542f5fSchristos wm_projective_st(p, dw, channel, msg); 126942542f5fSchristos return wm_sample(p, dw, channel, msg, result); 127042542f5fSchristos} 127142542f5fSchristos 127242542f5fSchristosstatic int wm_projective__alpha(struct brw_compile *p, int dw, 127342542f5fSchristos int channel, int msg, int result) 127442542f5fSchristos{ 127542542f5fSchristos gen8_compile_init(p); 127642542f5fSchristos 127742542f5fSchristos wm_projective_st(p, dw, channel, msg); 127842542f5fSchristos return wm_sample__alpha(p, dw, channel, msg, result); 127942542f5fSchristos} 128042542f5fSchristos 128142542f5fSchristosbool 128242542f5fSchristosgen8_wm_kernel__projective(struct brw_compile *p, int dispatch) 128342542f5fSchristos{ 128442542f5fSchristos gen8_compile_init(p); 128542542f5fSchristos 128613496ba1Ssnj wm_projective(p, dispatch, 0, 10, MRF_HACK_START+2); 128713496ba1Ssnj fb_write(p, dispatch); 128842542f5fSchristos return true; 128942542f5fSchristos} 129042542f5fSchristos 129142542f5fSchristosbool 129242542f5fSchristosgen8_wm_kernel__projective_mask(struct brw_compile *p, int dispatch) 129342542f5fSchristos{ 129442542f5fSchristos int src, mask; 129542542f5fSchristos 129642542f5fSchristos gen8_compile_init(p); 129742542f5fSchristos 129842542f5fSchristos src = wm_projective(p, dispatch, 0, 1, 12); 129942542f5fSchristos mask = wm_projective__alpha(p, dispatch, 1, 6, 20); 130042542f5fSchristos wm_write__mask(p, dispatch, src, mask); 130142542f5fSchristos 130242542f5fSchristos return true; 130342542f5fSchristos} 130442542f5fSchristos 130542542f5fSchristosbool 130642542f5fSchristosgen8_wm_kernel__projective_mask_ca(struct brw_compile *p, int dispatch) 130742542f5fSchristos{ 130842542f5fSchristos int src, mask; 130942542f5fSchristos 131042542f5fSchristos gen8_compile_init(p); 131142542f5fSchristos 131242542f5fSchristos src = wm_projective(p, dispatch, 0, 1, 12); 131342542f5fSchristos mask = wm_projective(p, dispatch, 1, 6, 20); 131442542f5fSchristos wm_write__mask_ca(p, dispatch, src, mask); 131542542f5fSchristos 131642542f5fSchristos return true; 131742542f5fSchristos} 131842542f5fSchristos 131942542f5fSchristosbool 132042542f5fSchristosgen8_wm_kernel__projective_mask_sa(struct brw_compile *p, int dispatch) 132142542f5fSchristos{ 132242542f5fSchristos int src, mask; 132342542f5fSchristos 132442542f5fSchristos gen8_compile_init(p); 132542542f5fSchristos 132642542f5fSchristos src = wm_projective__alpha(p, dispatch, 0, 1, 12); 132742542f5fSchristos mask = wm_projective(p, dispatch, 1, 6, 16); 132842542f5fSchristos wm_write__mask(p, dispatch, mask, src); 132942542f5fSchristos 133042542f5fSchristos return true; 133142542f5fSchristos} 133242542f5fSchristos 133342542f5fSchristosbool 133442542f5fSchristosgen8_wm_kernel__affine_opacity(struct brw_compile *p, int dispatch) 133542542f5fSchristos{ 133642542f5fSchristos int src, mask; 133742542f5fSchristos 133842542f5fSchristos gen8_compile_init(p); 133942542f5fSchristos 134042542f5fSchristos src = wm_affine(p, dispatch, 0, 1, 12); 134142542f5fSchristos mask = dispatch == 16 ? 8 : 6; 134242542f5fSchristos wm_write__opacity(p, dispatch, src, mask); 134342542f5fSchristos 134442542f5fSchristos return true; 134542542f5fSchristos} 134642542f5fSchristos 134742542f5fSchristosbool 134842542f5fSchristosgen8_wm_kernel__projective_opacity(struct brw_compile *p, int dispatch) 134942542f5fSchristos{ 135042542f5fSchristos int src, mask; 135142542f5fSchristos 135242542f5fSchristos gen8_compile_init(p); 135342542f5fSchristos 135442542f5fSchristos mask = dispatch == 16 ? 8 : 6; 135542542f5fSchristos src = wm_projective(p, dispatch, 0, 1, 12); 135642542f5fSchristos wm_write__opacity(p, dispatch, src, mask); 135742542f5fSchristos 135842542f5fSchristos return true; 135942542f5fSchristos} 1360