Path: blob/21.2-virgl/src/intel/compiler/brw_eu.h
4550 views
/*1Copyright (C) Intel Corp. 2006. All Rights Reserved.2Intel funded Tungsten Graphics to3develop this 3D driver.45Permission is hereby granted, free of charge, to any person obtaining6a copy of this software and associated documentation files (the7"Software"), to deal in the Software without restriction, including8without limitation the rights to use, copy, modify, merge, publish,9distribute, sublicense, and/or sell copies of the Software, and to10permit persons to whom the Software is furnished to do so, subject to11the following conditions:1213The above copyright notice and this permission notice (including the14next paragraph) shall be included in all copies or substantial15portions of the Software.1617THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,18EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.20IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE21LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION22OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.2425**********************************************************************/26/*27* Authors:28* Keith Whitwell <[email protected]>29*/303132#ifndef BRW_EU_H33#define BRW_EU_H3435#include <stdbool.h>36#include <stdio.h>37#include "brw_inst.h"38#include "brw_compiler.h"39#include "brw_eu_defines.h"40#include "brw_reg.h"41#include "brw_disasm_info.h"4243#ifdef __cplusplus44extern "C" {45#endif4647#define BRW_EU_MAX_INSN_STACK 54849struct brw_insn_state {50/* One of BRW_EXECUTE_* */51unsigned exec_size:3;5253/* Group in units of channels */54unsigned group:5;5556/* Compression control on gfx4-5 */57bool compressed:1;5859/* One of BRW_MASK_* */60unsigned mask_control:1;6162/* Scheduling info for Gfx12+ */63struct tgl_swsb swsb;6465bool saturate:1;6667/* One of BRW_ALIGN_* */68unsigned access_mode:1;6970/* One of BRW_PREDICATE_* */71enum brw_predicate predicate:4;7273bool pred_inv:1;7475/* Flag subreg. Bottom bit is subreg, top bit is reg */76unsigned flag_subreg:2;7778bool acc_wr_control:1;79};808182/* A helper for accessing the last instruction emitted. This makes it easy83* to set various bits on an instruction without having to create temporary84* variable and assign the emitted instruction to those.85*/86#define brw_last_inst (&p->store[p->nr_insn - 1])8788struct brw_codegen {89brw_inst *store;90int store_size;91unsigned nr_insn;92unsigned int next_insn_offset;9394void *mem_ctx;9596/* Allow clients to push/pop instruction state:97*/98struct brw_insn_state stack[BRW_EU_MAX_INSN_STACK];99struct brw_insn_state *current;100101/** Whether or not the user wants automatic exec sizes102*103* If true, codegen will try to automatically infer the exec size of an104* instruction from the width of the destination register. If false, it105* will take whatever is set by brw_set_default_exec_size verbatim.106*107* This is set to true by default in brw_init_codegen.108*/109bool automatic_exec_sizes;110111bool single_program_flow;112const struct intel_device_info *devinfo;113114/* Control flow stacks:115* - if_stack contains IF and ELSE instructions which must be patched116* (and popped) once the matching ENDIF instruction is encountered.117*118* Just store the instruction pointer(an index).119*/120int *if_stack;121int if_stack_depth;122int if_stack_array_size;123124/**125* loop_stack contains the instruction pointers of the starts of loops which126* must be patched (and popped) once the matching WHILE instruction is127* encountered.128*/129int *loop_stack;130/**131* pre-gfx6, the BREAK and CONT instructions had to tell how many IF/ENDIF132* blocks they were popping out of, to fix up the mask stack. This tracks133* the IF/ENDIF nesting in each current nested loop level.134*/135int *if_depth_in_loop;136int loop_stack_depth;137int loop_stack_array_size;138139struct brw_shader_reloc *relocs;140int num_relocs;141int reloc_array_size;142};143144struct brw_label {145int offset;146int number;147struct brw_label *next;148};149150void brw_pop_insn_state( struct brw_codegen *p );151void brw_push_insn_state( struct brw_codegen *p );152unsigned brw_get_default_exec_size(struct brw_codegen *p);153unsigned brw_get_default_group(struct brw_codegen *p);154unsigned brw_get_default_access_mode(struct brw_codegen *p);155struct tgl_swsb brw_get_default_swsb(struct brw_codegen *p);156void brw_set_default_exec_size(struct brw_codegen *p, unsigned value);157void brw_set_default_mask_control( struct brw_codegen *p, unsigned value );158void brw_set_default_saturate( struct brw_codegen *p, bool enable );159void brw_set_default_access_mode( struct brw_codegen *p, unsigned access_mode );160void brw_inst_set_compression(const struct intel_device_info *devinfo,161brw_inst *inst, bool on);162void brw_set_default_compression(struct brw_codegen *p, bool on);163void brw_inst_set_group(const struct intel_device_info *devinfo,164brw_inst *inst, unsigned group);165void brw_set_default_group(struct brw_codegen *p, unsigned group);166void brw_set_default_compression_control(struct brw_codegen *p, enum brw_compression c);167void brw_set_default_predicate_control(struct brw_codegen *p, enum brw_predicate pc);168void brw_set_default_predicate_inverse(struct brw_codegen *p, bool predicate_inverse);169void brw_set_default_flag_reg(struct brw_codegen *p, int reg, int subreg);170void brw_set_default_acc_write_control(struct brw_codegen *p, unsigned value);171void brw_set_default_swsb(struct brw_codegen *p, struct tgl_swsb value);172173void brw_init_codegen(const struct intel_device_info *, struct brw_codegen *p,174void *mem_ctx);175bool brw_has_jip(const struct intel_device_info *devinfo, enum opcode opcode);176bool brw_has_uip(const struct intel_device_info *devinfo, enum opcode opcode);177const struct brw_label *brw_find_label(const struct brw_label *root, int offset);178void brw_create_label(struct brw_label **labels, int offset, void *mem_ctx);179int brw_disassemble_inst(FILE *file, const struct intel_device_info *devinfo,180const struct brw_inst *inst, bool is_compacted,181int offset, const struct brw_label *root_label);182const struct183brw_label *brw_label_assembly(const struct intel_device_info *devinfo,184const void *assembly, int start, int end,185void *mem_ctx);186void brw_disassemble_with_labels(const struct intel_device_info *devinfo,187const void *assembly, int start, int end, FILE *out);188void brw_disassemble(const struct intel_device_info *devinfo,189const void *assembly, int start, int end,190const struct brw_label *root_label, FILE *out);191const struct brw_shader_reloc *brw_get_shader_relocs(struct brw_codegen *p,192unsigned *num_relocs);193const unsigned *brw_get_program( struct brw_codegen *p, unsigned *sz );194195bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,196const char *identifier);197198void brw_realign(struct brw_codegen *p, unsigned align);199int brw_append_data(struct brw_codegen *p, void *data,200unsigned size, unsigned align);201brw_inst *brw_next_insn(struct brw_codegen *p, unsigned opcode);202void brw_add_reloc(struct brw_codegen *p, uint32_t id,203enum brw_shader_reloc_type type,204uint32_t offset, uint32_t delta);205void brw_set_dest(struct brw_codegen *p, brw_inst *insn, struct brw_reg dest);206void brw_set_src0(struct brw_codegen *p, brw_inst *insn, struct brw_reg reg);207208void gfx6_resolve_implied_move(struct brw_codegen *p,209struct brw_reg *src,210unsigned msg_reg_nr);211212/* Helpers for regular instructions:213*/214#define ALU1(OP) \215brw_inst *brw_##OP(struct brw_codegen *p, \216struct brw_reg dest, \217struct brw_reg src0);218219#define ALU2(OP) \220brw_inst *brw_##OP(struct brw_codegen *p, \221struct brw_reg dest, \222struct brw_reg src0, \223struct brw_reg src1);224225#define ALU3(OP) \226brw_inst *brw_##OP(struct brw_codegen *p, \227struct brw_reg dest, \228struct brw_reg src0, \229struct brw_reg src1, \230struct brw_reg src2);231232ALU1(MOV)233ALU2(SEL)234ALU1(NOT)235ALU2(AND)236ALU2(OR)237ALU2(XOR)238ALU2(SHR)239ALU2(SHL)240ALU1(DIM)241ALU2(ASR)242ALU2(ROL)243ALU2(ROR)244ALU3(CSEL)245ALU1(F32TO16)246ALU1(F16TO32)247ALU2(ADD)248ALU2(AVG)249ALU2(MUL)250ALU1(FRC)251ALU1(RNDD)252ALU1(RNDE)253ALU1(RNDU)254ALU1(RNDZ)255ALU2(MAC)256ALU2(MACH)257ALU1(LZD)258ALU2(DP4)259ALU2(DPH)260ALU2(DP3)261ALU2(DP2)262ALU2(LINE)263ALU2(PLN)264ALU3(MAD)265ALU3(LRP)266ALU1(BFREV)267ALU3(BFE)268ALU2(BFI1)269ALU3(BFI2)270ALU1(FBH)271ALU1(FBL)272ALU1(CBIT)273ALU2(ADDC)274ALU2(SUBB)275276#undef ALU1277#undef ALU2278#undef ALU3279280281/* Helpers for SEND instruction:282*/283284/**285* Construct a message descriptor immediate with the specified common286* descriptor controls.287*/288static inline uint32_t289brw_message_desc(const struct intel_device_info *devinfo,290unsigned msg_length,291unsigned response_length,292bool header_present)293{294if (devinfo->ver >= 5) {295return (SET_BITS(msg_length, 28, 25) |296SET_BITS(response_length, 24, 20) |297SET_BITS(header_present, 19, 19));298} else {299return (SET_BITS(msg_length, 23, 20) |300SET_BITS(response_length, 19, 16));301}302}303304static inline unsigned305brw_message_desc_mlen(const struct intel_device_info *devinfo, uint32_t desc)306{307if (devinfo->ver >= 5)308return GET_BITS(desc, 28, 25);309else310return GET_BITS(desc, 23, 20);311}312313static inline unsigned314brw_message_desc_rlen(const struct intel_device_info *devinfo, uint32_t desc)315{316if (devinfo->ver >= 5)317return GET_BITS(desc, 24, 20);318else319return GET_BITS(desc, 19, 16);320}321322static inline bool323brw_message_desc_header_present(ASSERTED324const struct intel_device_info *devinfo,325uint32_t desc)326{327assert(devinfo->ver >= 5);328return GET_BITS(desc, 19, 19);329}330331static inline unsigned332brw_message_ex_desc(UNUSED const struct intel_device_info *devinfo,333unsigned ex_msg_length)334{335return SET_BITS(ex_msg_length, 9, 6);336}337338static inline unsigned339brw_message_ex_desc_ex_mlen(UNUSED const struct intel_device_info *devinfo,340uint32_t ex_desc)341{342return GET_BITS(ex_desc, 9, 6);343}344345static inline uint32_t346brw_urb_desc(const struct intel_device_info *devinfo,347unsigned msg_type,348bool per_slot_offset_present,349bool channel_mask_present,350unsigned global_offset)351{352if (devinfo->ver >= 8) {353return (SET_BITS(per_slot_offset_present, 17, 17) |354SET_BITS(channel_mask_present, 15, 15) |355SET_BITS(global_offset, 14, 4) |356SET_BITS(msg_type, 3, 0));357} else if (devinfo->ver >= 7) {358assert(!channel_mask_present);359return (SET_BITS(per_slot_offset_present, 16, 16) |360SET_BITS(global_offset, 13, 3) |361SET_BITS(msg_type, 3, 0));362} else {363unreachable("unhandled URB write generation");364}365}366367static inline uint32_t368brw_urb_desc_msg_type(ASSERTED const struct intel_device_info *devinfo,369uint32_t desc)370{371assert(devinfo->ver >= 7);372return GET_BITS(desc, 3, 0);373}374375/**376* Construct a message descriptor immediate with the specified sampler377* function controls.378*/379static inline uint32_t380brw_sampler_desc(const struct intel_device_info *devinfo,381unsigned binding_table_index,382unsigned sampler,383unsigned msg_type,384unsigned simd_mode,385unsigned return_format)386{387const unsigned desc = (SET_BITS(binding_table_index, 7, 0) |388SET_BITS(sampler, 11, 8));389if (devinfo->ver >= 7)390return (desc | SET_BITS(msg_type, 16, 12) |391SET_BITS(simd_mode, 18, 17));392else if (devinfo->ver >= 5)393return (desc | SET_BITS(msg_type, 15, 12) |394SET_BITS(simd_mode, 17, 16));395else if (devinfo->is_g4x)396return desc | SET_BITS(msg_type, 15, 12);397else398return (desc | SET_BITS(return_format, 13, 12) |399SET_BITS(msg_type, 15, 14));400}401402static inline unsigned403brw_sampler_desc_binding_table_index(UNUSED404const struct intel_device_info *devinfo,405uint32_t desc)406{407return GET_BITS(desc, 7, 0);408}409410static inline unsigned411brw_sampler_desc_sampler(UNUSED const struct intel_device_info *devinfo,412uint32_t desc)413{414return GET_BITS(desc, 11, 8);415}416417static inline unsigned418brw_sampler_desc_msg_type(const struct intel_device_info *devinfo, uint32_t desc)419{420if (devinfo->ver >= 7)421return GET_BITS(desc, 16, 12);422else if (devinfo->ver >= 5 || devinfo->is_g4x)423return GET_BITS(desc, 15, 12);424else425return GET_BITS(desc, 15, 14);426}427428static inline unsigned429brw_sampler_desc_simd_mode(const struct intel_device_info *devinfo,430uint32_t desc)431{432assert(devinfo->ver >= 5);433if (devinfo->ver >= 7)434return GET_BITS(desc, 18, 17);435else436return GET_BITS(desc, 17, 16);437}438439static inline unsigned440brw_sampler_desc_return_format(ASSERTED const struct intel_device_info *devinfo,441uint32_t desc)442{443assert(devinfo->ver == 4 && !devinfo->is_g4x);444return GET_BITS(desc, 13, 12);445}446447/**448* Construct a message descriptor for the dataport449*/450static inline uint32_t451brw_dp_desc(const struct intel_device_info *devinfo,452unsigned binding_table_index,453unsigned msg_type,454unsigned msg_control)455{456/* Prior to gfx6, things are too inconsistent; use the dp_read/write_desc457* helpers instead.458*/459assert(devinfo->ver >= 6);460const unsigned desc = SET_BITS(binding_table_index, 7, 0);461if (devinfo->ver >= 8) {462return (desc | SET_BITS(msg_control, 13, 8) |463SET_BITS(msg_type, 18, 14));464} else if (devinfo->ver >= 7) {465return (desc | SET_BITS(msg_control, 13, 8) |466SET_BITS(msg_type, 17, 14));467} else {468return (desc | SET_BITS(msg_control, 12, 8) |469SET_BITS(msg_type, 16, 13));470}471}472473static inline unsigned474brw_dp_desc_binding_table_index(UNUSED const struct intel_device_info *devinfo,475uint32_t desc)476{477return GET_BITS(desc, 7, 0);478}479480static inline unsigned481brw_dp_desc_msg_type(const struct intel_device_info *devinfo, uint32_t desc)482{483assert(devinfo->ver >= 6);484if (devinfo->ver >= 8)485return GET_BITS(desc, 18, 14);486else if (devinfo->ver >= 7)487return GET_BITS(desc, 17, 14);488else489return GET_BITS(desc, 16, 13);490}491492static inline unsigned493brw_dp_desc_msg_control(const struct intel_device_info *devinfo, uint32_t desc)494{495assert(devinfo->ver >= 6);496if (devinfo->ver >= 7)497return GET_BITS(desc, 13, 8);498else499return GET_BITS(desc, 12, 8);500}501502/**503* Construct a message descriptor immediate with the specified dataport read504* function controls.505*/506static inline uint32_t507brw_dp_read_desc(const struct intel_device_info *devinfo,508unsigned binding_table_index,509unsigned msg_control,510unsigned msg_type,511unsigned target_cache)512{513if (devinfo->ver >= 6)514return brw_dp_desc(devinfo, binding_table_index, msg_type, msg_control);515else if (devinfo->ver >= 5 || devinfo->is_g4x)516return (SET_BITS(binding_table_index, 7, 0) |517SET_BITS(msg_control, 10, 8) |518SET_BITS(msg_type, 13, 11) |519SET_BITS(target_cache, 15, 14));520else521return (SET_BITS(binding_table_index, 7, 0) |522SET_BITS(msg_control, 11, 8) |523SET_BITS(msg_type, 13, 12) |524SET_BITS(target_cache, 15, 14));525}526527static inline unsigned528brw_dp_read_desc_msg_type(const struct intel_device_info *devinfo,529uint32_t desc)530{531if (devinfo->ver >= 6)532return brw_dp_desc_msg_type(devinfo, desc);533else if (devinfo->ver >= 5 || devinfo->is_g4x)534return GET_BITS(desc, 13, 11);535else536return GET_BITS(desc, 13, 12);537}538539static inline unsigned540brw_dp_read_desc_msg_control(const struct intel_device_info *devinfo,541uint32_t desc)542{543if (devinfo->ver >= 6)544return brw_dp_desc_msg_control(devinfo, desc);545else if (devinfo->ver >= 5 || devinfo->is_g4x)546return GET_BITS(desc, 10, 8);547else548return GET_BITS(desc, 11, 8);549}550551/**552* Construct a message descriptor immediate with the specified dataport write553* function controls.554*/555static inline uint32_t556brw_dp_write_desc(const struct intel_device_info *devinfo,557unsigned binding_table_index,558unsigned msg_control,559unsigned msg_type,560unsigned send_commit_msg)561{562assert(devinfo->ver <= 6 || !send_commit_msg);563if (devinfo->ver >= 6) {564return brw_dp_desc(devinfo, binding_table_index, msg_type, msg_control) |565SET_BITS(send_commit_msg, 17, 17);566} else {567return (SET_BITS(binding_table_index, 7, 0) |568SET_BITS(msg_control, 11, 8) |569SET_BITS(msg_type, 14, 12) |570SET_BITS(send_commit_msg, 15, 15));571}572}573574static inline unsigned575brw_dp_write_desc_msg_type(const struct intel_device_info *devinfo,576uint32_t desc)577{578if (devinfo->ver >= 6)579return brw_dp_desc_msg_type(devinfo, desc);580else581return GET_BITS(desc, 14, 12);582}583584static inline unsigned585brw_dp_write_desc_msg_control(const struct intel_device_info *devinfo,586uint32_t desc)587{588if (devinfo->ver >= 6)589return brw_dp_desc_msg_control(devinfo, desc);590else591return GET_BITS(desc, 11, 8);592}593594static inline bool595brw_dp_write_desc_write_commit(const struct intel_device_info *devinfo,596uint32_t desc)597{598assert(devinfo->ver <= 6);599if (devinfo->ver >= 6)600return GET_BITS(desc, 17, 17);601else602return GET_BITS(desc, 15, 15);603}604605/**606* Construct a message descriptor immediate with the specified dataport607* surface function controls.608*/609static inline uint32_t610brw_dp_surface_desc(const struct intel_device_info *devinfo,611unsigned msg_type,612unsigned msg_control)613{614assert(devinfo->ver >= 7);615/* We'll OR in the binding table index later */616return brw_dp_desc(devinfo, 0, msg_type, msg_control);617}618619static inline uint32_t620brw_dp_untyped_atomic_desc(const struct intel_device_info *devinfo,621unsigned exec_size, /**< 0 for SIMD4x2 */622unsigned atomic_op,623bool response_expected)624{625assert(exec_size <= 8 || exec_size == 16);626627unsigned msg_type;628if (devinfo->verx10 >= 75) {629if (exec_size > 0) {630msg_type = HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP;631} else {632msg_type = HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2;633}634} else {635msg_type = GFX7_DATAPORT_DC_UNTYPED_ATOMIC_OP;636}637638const unsigned msg_control =639SET_BITS(atomic_op, 3, 0) |640SET_BITS(0 < exec_size && exec_size <= 8, 4, 4) |641SET_BITS(response_expected, 5, 5);642643return brw_dp_surface_desc(devinfo, msg_type, msg_control);644}645646static inline uint32_t647brw_dp_untyped_atomic_float_desc(const struct intel_device_info *devinfo,648unsigned exec_size,649unsigned atomic_op,650bool response_expected)651{652assert(exec_size <= 8 || exec_size == 16);653assert(devinfo->ver >= 9);654655assert(exec_size > 0);656const unsigned msg_type = GFX9_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_FLOAT_OP;657658const unsigned msg_control =659SET_BITS(atomic_op, 1, 0) |660SET_BITS(exec_size <= 8, 4, 4) |661SET_BITS(response_expected, 5, 5);662663return brw_dp_surface_desc(devinfo, msg_type, msg_control);664}665666static inline unsigned667brw_mdc_cmask(unsigned num_channels)668{669/* See also MDC_CMASK in the SKL PRM Vol 2d. */670return 0xf & (0xf << num_channels);671}672673static inline unsigned674lsc_cmask(unsigned num_channels)675{676assert(num_channels > 0 && num_channels <= 4);677return BITSET_MASK(num_channels);678}679680static inline uint32_t681brw_dp_untyped_surface_rw_desc(const struct intel_device_info *devinfo,682unsigned exec_size, /**< 0 for SIMD4x2 */683unsigned num_channels,684bool write)685{686assert(exec_size <= 8 || exec_size == 16);687688unsigned msg_type;689if (write) {690if (devinfo->verx10 >= 75) {691msg_type = HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE;692} else {693msg_type = GFX7_DATAPORT_DC_UNTYPED_SURFACE_WRITE;694}695} else {696/* Read */697if (devinfo->verx10 >= 75) {698msg_type = HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ;699} else {700msg_type = GFX7_DATAPORT_DC_UNTYPED_SURFACE_READ;701}702}703704/* SIMD4x2 is only valid for read messages on IVB; use SIMD8 instead */705if (write && devinfo->verx10 == 70 && exec_size == 0)706exec_size = 8;707708/* See also MDC_SM3 in the SKL PRM Vol 2d. */709const unsigned simd_mode = exec_size == 0 ? 0 : /* SIMD4x2 */710exec_size <= 8 ? 2 : 1;711712const unsigned msg_control =713SET_BITS(brw_mdc_cmask(num_channels), 3, 0) |714SET_BITS(simd_mode, 5, 4);715716return brw_dp_surface_desc(devinfo, msg_type, msg_control);717}718719static inline unsigned720brw_mdc_ds(unsigned bit_size)721{722switch (bit_size) {723case 8:724return GFX7_BYTE_SCATTERED_DATA_ELEMENT_BYTE;725case 16:726return GFX7_BYTE_SCATTERED_DATA_ELEMENT_WORD;727case 32:728return GFX7_BYTE_SCATTERED_DATA_ELEMENT_DWORD;729default:730unreachable("Unsupported bit_size for byte scattered messages");731}732}733734static inline uint32_t735brw_dp_byte_scattered_rw_desc(const struct intel_device_info *devinfo,736unsigned exec_size,737unsigned bit_size,738bool write)739{740assert(exec_size <= 8 || exec_size == 16);741742assert(devinfo->verx10 >= 75);743const unsigned msg_type =744write ? HSW_DATAPORT_DC_PORT0_BYTE_SCATTERED_WRITE :745HSW_DATAPORT_DC_PORT0_BYTE_SCATTERED_READ;746747assert(exec_size > 0);748const unsigned msg_control =749SET_BITS(exec_size == 16, 0, 0) |750SET_BITS(brw_mdc_ds(bit_size), 3, 2);751752return brw_dp_surface_desc(devinfo, msg_type, msg_control);753}754755static inline uint32_t756brw_dp_dword_scattered_rw_desc(const struct intel_device_info *devinfo,757unsigned exec_size,758bool write)759{760assert(exec_size == 8 || exec_size == 16);761762unsigned msg_type;763if (write) {764if (devinfo->ver >= 6) {765msg_type = GFX6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE;766} else {767msg_type = BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE;768}769} else {770if (devinfo->ver >= 7) {771msg_type = GFX7_DATAPORT_DC_DWORD_SCATTERED_READ;772} else if (devinfo->ver > 4 || devinfo->is_g4x) {773msg_type = G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;774} else {775msg_type = BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;776}777}778779const unsigned msg_control =780SET_BITS(1, 1, 1) | /* Legacy SIMD Mode */781SET_BITS(exec_size == 16, 0, 0);782783return brw_dp_surface_desc(devinfo, msg_type, msg_control);784}785786static inline uint32_t787brw_dp_oword_block_rw_desc(const struct intel_device_info *devinfo,788bool align_16B,789unsigned num_dwords,790bool write)791{792/* Writes can only have addresses aligned by OWORDs (16 Bytes). */793assert(!write || align_16B);794795const unsigned msg_type =796write ? GFX7_DATAPORT_DC_OWORD_BLOCK_WRITE :797align_16B ? GFX7_DATAPORT_DC_OWORD_BLOCK_READ :798GFX7_DATAPORT_DC_UNALIGNED_OWORD_BLOCK_READ;799800const unsigned msg_control =801SET_BITS(BRW_DATAPORT_OWORD_BLOCK_DWORDS(num_dwords), 2, 0);802803return brw_dp_surface_desc(devinfo, msg_type, msg_control);804}805806static inline uint32_t807brw_dp_a64_untyped_surface_rw_desc(const struct intel_device_info *devinfo,808unsigned exec_size, /**< 0 for SIMD4x2 */809unsigned num_channels,810bool write)811{812assert(exec_size <= 8 || exec_size == 16);813assert(devinfo->ver >= 8);814815unsigned msg_type =816write ? GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_WRITE :817GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_READ;818819/* See also MDC_SM3 in the SKL PRM Vol 2d. */820const unsigned simd_mode = exec_size == 0 ? 0 : /* SIMD4x2 */821exec_size <= 8 ? 2 : 1;822823const unsigned msg_control =824SET_BITS(brw_mdc_cmask(num_channels), 3, 0) |825SET_BITS(simd_mode, 5, 4);826827return brw_dp_desc(devinfo, GFX8_BTI_STATELESS_NON_COHERENT,828msg_type, msg_control);829}830831static inline uint32_t832brw_dp_a64_oword_block_rw_desc(const struct intel_device_info *devinfo,833bool align_16B,834unsigned num_dwords,835bool write)836{837/* Writes can only have addresses aligned by OWORDs (16 Bytes). */838assert(!write || align_16B);839840unsigned msg_type =841write ? GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_WRITE :842GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_READ;843844unsigned msg_control =845SET_BITS(!align_16B, 4, 3) |846SET_BITS(BRW_DATAPORT_OWORD_BLOCK_DWORDS(num_dwords), 2, 0);847848return brw_dp_desc(devinfo, GFX8_BTI_STATELESS_NON_COHERENT,849msg_type, msg_control);850}851852/**853* Calculate the data size (see MDC_A64_DS in the "Structures" volume of the854* Skylake PRM).855*/856static inline uint32_t857brw_mdc_a64_ds(unsigned elems)858{859switch (elems) {860case 1: return 0;861case 2: return 1;862case 4: return 2;863case 8: return 3;864default:865unreachable("Unsupported elmeent count for A64 scattered message");866}867}868869static inline uint32_t870brw_dp_a64_byte_scattered_rw_desc(const struct intel_device_info *devinfo,871unsigned exec_size, /**< 0 for SIMD4x2 */872unsigned bit_size,873bool write)874{875assert(exec_size <= 8 || exec_size == 16);876assert(devinfo->ver >= 8);877878unsigned msg_type =879write ? GFX8_DATAPORT_DC_PORT1_A64_SCATTERED_WRITE :880GFX9_DATAPORT_DC_PORT1_A64_SCATTERED_READ;881882const unsigned msg_control =883SET_BITS(GFX8_A64_SCATTERED_SUBTYPE_BYTE, 1, 0) |884SET_BITS(brw_mdc_a64_ds(bit_size / 8), 3, 2) |885SET_BITS(exec_size == 16, 4, 4);886887return brw_dp_desc(devinfo, GFX8_BTI_STATELESS_NON_COHERENT,888msg_type, msg_control);889}890891static inline uint32_t892brw_dp_a64_untyped_atomic_desc(const struct intel_device_info *devinfo,893ASSERTED unsigned exec_size, /**< 0 for SIMD4x2 */894unsigned bit_size,895unsigned atomic_op,896bool response_expected)897{898assert(exec_size == 8);899assert(devinfo->ver >= 8);900assert(bit_size == 16 || bit_size == 32 || bit_size == 64);901assert(devinfo->ver >= 12 || bit_size >= 32);902903const unsigned msg_type = bit_size == 16 ?904GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_INT_OP :905GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_OP;906907const unsigned msg_control =908SET_BITS(atomic_op, 3, 0) |909SET_BITS(bit_size == 64, 4, 4) |910SET_BITS(response_expected, 5, 5);911912return brw_dp_desc(devinfo, GFX8_BTI_STATELESS_NON_COHERENT,913msg_type, msg_control);914}915916static inline uint32_t917brw_dp_a64_untyped_atomic_float_desc(const struct intel_device_info *devinfo,918ASSERTED unsigned exec_size,919unsigned bit_size,920unsigned atomic_op,921bool response_expected)922{923assert(exec_size == 8);924assert(devinfo->ver >= 9);925assert(bit_size == 16 || bit_size == 32);926assert(devinfo->ver >= 12 || bit_size == 32);927928assert(exec_size > 0);929const unsigned msg_type = bit_size == 32 ?930GFX9_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_FLOAT_OP :931GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_FLOAT_OP;932933const unsigned msg_control =934SET_BITS(atomic_op, 1, 0) |935SET_BITS(response_expected, 5, 5);936937return brw_dp_desc(devinfo, GFX8_BTI_STATELESS_NON_COHERENT,938msg_type, msg_control);939}940941static inline uint32_t942brw_dp_typed_atomic_desc(const struct intel_device_info *devinfo,943unsigned exec_size,944unsigned exec_group,945unsigned atomic_op,946bool response_expected)947{948assert(exec_size > 0 || exec_group == 0);949assert(exec_group % 8 == 0);950951unsigned msg_type;952if (devinfo->verx10 >= 75) {953if (exec_size == 0) {954msg_type = HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2;955} else {956msg_type = HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP;957}958} else {959/* SIMD4x2 typed surface R/W messages only exist on HSW+ */960assert(exec_size > 0);961msg_type = GFX7_DATAPORT_RC_TYPED_ATOMIC_OP;962}963964const bool high_sample_mask = (exec_group / 8) % 2 == 1;965966const unsigned msg_control =967SET_BITS(atomic_op, 3, 0) |968SET_BITS(high_sample_mask, 4, 4) |969SET_BITS(response_expected, 5, 5);970971return brw_dp_surface_desc(devinfo, msg_type, msg_control);972}973974static inline uint32_t975brw_dp_typed_surface_rw_desc(const struct intel_device_info *devinfo,976unsigned exec_size,977unsigned exec_group,978unsigned num_channels,979bool write)980{981assert(exec_size > 0 || exec_group == 0);982assert(exec_group % 8 == 0);983984/* Typed surface reads and writes don't support SIMD16 */985assert(exec_size <= 8);986987unsigned msg_type;988if (write) {989if (devinfo->verx10 >= 75) {990msg_type = HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE;991} else {992msg_type = GFX7_DATAPORT_RC_TYPED_SURFACE_WRITE;993}994} else {995if (devinfo->verx10 >= 75) {996msg_type = HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ;997} else {998msg_type = GFX7_DATAPORT_RC_TYPED_SURFACE_READ;999}1000}10011002/* See also MDC_SG3 in the SKL PRM Vol 2d. */1003unsigned msg_control;1004if (devinfo->verx10 >= 75) {1005/* See also MDC_SG3 in the SKL PRM Vol 2d. */1006const unsigned slot_group = exec_size == 0 ? 0 : /* SIMD4x2 */10071 + ((exec_group / 8) % 2);10081009msg_control =1010SET_BITS(brw_mdc_cmask(num_channels), 3, 0) |1011SET_BITS(slot_group, 5, 4);1012} else {1013/* SIMD4x2 typed surface R/W messages only exist on HSW+ */1014assert(exec_size > 0);1015const unsigned slot_group = ((exec_group / 8) % 2);10161017msg_control =1018SET_BITS(brw_mdc_cmask(num_channels), 3, 0) |1019SET_BITS(slot_group, 5, 5);1020}10211022return brw_dp_surface_desc(devinfo, msg_type, msg_control);1023}10241025static inline uint32_t1026brw_fb_desc(const struct intel_device_info *devinfo,1027unsigned binding_table_index,1028unsigned msg_type,1029unsigned msg_control)1030{1031/* Prior to gen6, things are too inconsistent; use the fb_(read|write)_desc1032* helpers instead.1033*/1034assert(devinfo->ver >= 6);1035const unsigned desc = SET_BITS(binding_table_index, 7, 0);1036if (devinfo->ver >= 7) {1037return (desc | SET_BITS(msg_control, 13, 8) |1038SET_BITS(msg_type, 17, 14));1039} else {1040return (desc | SET_BITS(msg_control, 12, 8) |1041SET_BITS(msg_type, 16, 13));1042}1043}10441045static inline unsigned1046brw_fb_desc_binding_table_index(UNUSED const struct intel_device_info *devinfo,1047uint32_t desc)1048{1049return GET_BITS(desc, 7, 0);1050}10511052static inline uint32_t1053brw_fb_desc_msg_control(const struct intel_device_info *devinfo, uint32_t desc)1054{1055assert(devinfo->ver >= 6);1056if (devinfo->ver >= 7)1057return GET_BITS(desc, 13, 8);1058else1059return GET_BITS(desc, 12, 8);1060}10611062static inline unsigned1063brw_fb_desc_msg_type(const struct intel_device_info *devinfo, uint32_t desc)1064{1065assert(devinfo->ver >= 6);1066if (devinfo->ver >= 7)1067return GET_BITS(desc, 17, 14);1068else1069return GET_BITS(desc, 16, 13);1070}10711072static inline uint32_t1073brw_fb_read_desc(const struct intel_device_info *devinfo,1074unsigned binding_table_index,1075unsigned msg_control,1076unsigned exec_size,1077bool per_sample)1078{1079assert(devinfo->ver >= 9);1080assert(exec_size == 8 || exec_size == 16);10811082return brw_fb_desc(devinfo, binding_table_index,1083GFX9_DATAPORT_RC_RENDER_TARGET_READ, msg_control) |1084SET_BITS(per_sample, 13, 13) |1085SET_BITS(exec_size == 8, 8, 8) /* Render Target Message Subtype */;1086}10871088static inline uint32_t1089brw_fb_write_desc(const struct intel_device_info *devinfo,1090unsigned binding_table_index,1091unsigned msg_control,1092bool last_render_target,1093bool coarse_write)1094{1095const unsigned msg_type =1096devinfo->ver >= 6 ?1097GFX6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE :1098BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE;10991100assert(devinfo->ver >= 10 || !coarse_write);11011102if (devinfo->ver >= 6) {1103return brw_fb_desc(devinfo, binding_table_index, msg_type, msg_control) |1104SET_BITS(last_render_target, 12, 12) |1105SET_BITS(coarse_write, 18, 18);1106} else {1107return (SET_BITS(binding_table_index, 7, 0) |1108SET_BITS(msg_control, 11, 8) |1109SET_BITS(last_render_target, 11, 11) |1110SET_BITS(msg_type, 14, 12));1111}1112}11131114static inline unsigned1115brw_fb_write_desc_msg_type(const struct intel_device_info *devinfo,1116uint32_t desc)1117{1118if (devinfo->ver >= 6)1119return brw_fb_desc_msg_type(devinfo, desc);1120else1121return GET_BITS(desc, 14, 12);1122}11231124static inline unsigned1125brw_fb_write_desc_msg_control(const struct intel_device_info *devinfo,1126uint32_t desc)1127{1128if (devinfo->ver >= 6)1129return brw_fb_desc_msg_control(devinfo, desc);1130else1131return GET_BITS(desc, 11, 8);1132}11331134static inline bool1135brw_fb_write_desc_last_render_target(const struct intel_device_info *devinfo,1136uint32_t desc)1137{1138if (devinfo->ver >= 6)1139return GET_BITS(desc, 12, 12);1140else1141return GET_BITS(desc, 11, 11);1142}11431144static inline bool1145brw_fb_write_desc_write_commit(const struct intel_device_info *devinfo,1146uint32_t desc)1147{1148assert(devinfo->ver <= 6);1149if (devinfo->ver >= 6)1150return GET_BITS(desc, 17, 17);1151else1152return GET_BITS(desc, 15, 15);1153}11541155static inline bool1156brw_fb_write_desc_coarse_write(const struct intel_device_info *devinfo,1157uint32_t desc)1158{1159assert(devinfo->ver >= 10);1160return GET_BITS(desc, 18, 18);1161}11621163static inline bool1164lsc_opcode_has_cmask(enum lsc_opcode opcode)1165{1166return opcode == LSC_OP_LOAD_CMASK || opcode == LSC_OP_STORE_CMASK;1167}11681169static inline uint32_t1170lsc_data_size_bytes(enum lsc_data_size data_size)1171{1172switch (data_size) {1173case LSC_DATA_SIZE_D8:1174return 1;1175case LSC_DATA_SIZE_D16:1176return 2;1177case LSC_DATA_SIZE_D32:1178case LSC_DATA_SIZE_D8U32:1179case LSC_DATA_SIZE_D16U32:1180case LSC_DATA_SIZE_D16BF32:1181return 4;1182case LSC_DATA_SIZE_D64:1183return 8;1184default:1185unreachable("Unsupported data payload size.");1186}1187}11881189static inline uint32_t1190lsc_addr_size_bytes(enum lsc_addr_size addr_size)1191{1192switch (addr_size) {1193case LSC_ADDR_SIZE_A16: return 2;1194case LSC_ADDR_SIZE_A32: return 4;1195case LSC_ADDR_SIZE_A64: return 8;1196default:1197unreachable("Unsupported address size.");1198}1199}12001201static inline uint32_t1202lsc_vector_length(enum lsc_vect_size vect_size)1203{1204switch (vect_size) {1205case LSC_VECT_SIZE_V1: return 1;1206case LSC_VECT_SIZE_V2: return 2;1207case LSC_VECT_SIZE_V3: return 3;1208case LSC_VECT_SIZE_V4: return 4;1209case LSC_VECT_SIZE_V8: return 8;1210case LSC_VECT_SIZE_V16: return 16;1211case LSC_VECT_SIZE_V32: return 32;1212case LSC_VECT_SIZE_V64: return 64;1213default:1214unreachable("Unsupported size of vector");1215}1216}12171218static inline enum lsc_vect_size1219lsc_vect_size(unsigned vect_size)1220{1221switch(vect_size) {1222case 1: return LSC_VECT_SIZE_V1;1223case 2: return LSC_VECT_SIZE_V2;1224case 3: return LSC_VECT_SIZE_V3;1225case 4: return LSC_VECT_SIZE_V4;1226case 8: return LSC_VECT_SIZE_V8;1227case 16: return LSC_VECT_SIZE_V16;1228case 32: return LSC_VECT_SIZE_V32;1229case 64: return LSC_VECT_SIZE_V64;1230default:1231unreachable("Unsupported vector size for dataport");1232}1233}12341235static inline uint32_t1236lsc_msg_desc(UNUSED const struct intel_device_info *devinfo,1237enum lsc_opcode opcode, unsigned simd_size,1238enum lsc_addr_surface_type addr_type,1239enum lsc_addr_size addr_sz, unsigned num_coordinates,1240enum lsc_data_size data_sz, unsigned num_channels,1241bool transpose, unsigned cache_ctrl, bool has_dest)1242{1243assert(devinfo->has_lsc);12441245unsigned dest_length = !has_dest ? 0 :1246DIV_ROUND_UP(lsc_data_size_bytes(data_sz) * num_channels * simd_size,1247REG_SIZE);12481249unsigned src0_length =1250DIV_ROUND_UP(lsc_addr_size_bytes(addr_sz) * num_coordinates * simd_size,1251REG_SIZE);12521253unsigned msg_desc =1254SET_BITS(opcode, 5, 0) |1255SET_BITS(addr_sz, 8, 7) |1256SET_BITS(data_sz, 11, 9) |1257SET_BITS(transpose, 15, 15) |1258SET_BITS(cache_ctrl, 19, 17) |1259SET_BITS(dest_length, 24, 20) |1260SET_BITS(src0_length, 28, 25) |1261SET_BITS(addr_type, 30, 29);12621263if (lsc_opcode_has_cmask(opcode))1264msg_desc |= SET_BITS(lsc_cmask(num_channels), 15, 12);1265else1266msg_desc |= SET_BITS(lsc_vect_size(num_channels), 14, 12);12671268return msg_desc;1269}12701271static inline enum lsc_opcode1272lsc_msg_desc_opcode(UNUSED const struct intel_device_info *devinfo,1273uint32_t desc)1274{1275assert(devinfo->has_lsc);1276return (enum lsc_opcode) GET_BITS(desc, 5, 0);1277}12781279static inline enum lsc_addr_size1280lsc_msg_desc_addr_size(UNUSED const struct intel_device_info *devinfo,1281uint32_t desc)1282{1283assert(devinfo->has_lsc);1284return (enum lsc_addr_size) GET_BITS(desc, 8, 7);1285}12861287static inline enum lsc_data_size1288lsc_msg_desc_data_size(UNUSED const struct intel_device_info *devinfo,1289uint32_t desc)1290{1291assert(devinfo->has_lsc);1292return (enum lsc_data_size) GET_BITS(desc, 11, 9);1293}12941295static inline enum lsc_vect_size1296lsc_msg_desc_vect_size(UNUSED const struct intel_device_info *devinfo,1297uint32_t desc)1298{1299assert(devinfo->has_lsc);1300assert(!lsc_opcode_has_cmask(lsc_msg_desc_opcode(devinfo, desc)));1301return (enum lsc_vect_size) GET_BITS(desc, 14, 12);1302}13031304static inline enum lsc_cmask1305lsc_msg_desc_cmask(UNUSED const struct intel_device_info *devinfo,1306uint32_t desc)1307{1308assert(devinfo->has_lsc);1309assert(lsc_opcode_has_cmask(lsc_msg_desc_opcode(devinfo, desc)));1310return (enum lsc_cmask) GET_BITS(desc, 15, 12);1311}13121313static inline bool1314lsc_msg_desc_transpose(UNUSED const struct intel_device_info *devinfo,1315uint32_t desc)1316{1317assert(devinfo->has_lsc);1318return GET_BITS(desc, 15, 15);1319}13201321static inline unsigned1322lsc_msg_desc_cache_ctrl(UNUSED const struct intel_device_info *devinfo,1323uint32_t desc)1324{1325assert(devinfo->has_lsc);1326return GET_BITS(desc, 19, 17);1327}13281329static inline unsigned1330lsc_msg_desc_dest_len(const struct intel_device_info *devinfo,1331uint32_t desc)1332{1333assert(devinfo->has_lsc);1334return GET_BITS(desc, 24, 20);1335}13361337static inline unsigned1338lsc_msg_desc_src0_len(const struct intel_device_info *devinfo,1339uint32_t desc)1340{1341assert(devinfo->has_lsc);1342return GET_BITS(desc, 28, 25);1343}13441345static inline enum lsc_addr_surface_type1346lsc_msg_desc_addr_type(UNUSED const struct intel_device_info *devinfo,1347uint32_t desc)1348{1349assert(devinfo->has_lsc);1350return (enum lsc_addr_surface_type) GET_BITS(desc, 30, 29);1351}13521353static inline uint32_t1354lsc_fence_msg_desc(UNUSED const struct intel_device_info *devinfo,1355enum lsc_fence_scope scope,1356enum lsc_flush_type flush_type,1357bool route_to_lsc)1358{1359assert(devinfo->has_lsc);1360return SET_BITS(LSC_OP_FENCE, 5, 0) |1361SET_BITS(LSC_ADDR_SIZE_A32, 8, 7) |1362SET_BITS(scope, 11, 9) |1363SET_BITS(flush_type, 14, 12) |1364SET_BITS(route_to_lsc, 18, 18) |1365SET_BITS(LSC_ADDR_SURFTYPE_FLAT, 30, 29);1366}13671368static inline enum lsc_fence_scope1369lsc_fence_msg_desc_scope(UNUSED const struct intel_device_info *devinfo,1370uint32_t desc)1371{1372assert(devinfo->has_lsc);1373return (enum lsc_fence_scope) GET_BITS(desc, 11, 9);1374}13751376static inline enum lsc_flush_type1377lsc_fence_msg_desc_flush_type(UNUSED const struct intel_device_info *devinfo,1378uint32_t desc)1379{1380assert(devinfo->has_lsc);1381return (enum lsc_flush_type) GET_BITS(desc, 14, 12);1382}13831384static inline enum lsc_backup_fence_routing1385lsc_fence_msg_desc_backup_routing(UNUSED const struct intel_device_info *devinfo,1386uint32_t desc)1387{1388assert(devinfo->has_lsc);1389return (enum lsc_backup_fence_routing) GET_BITS(desc, 18, 18);1390}13911392static inline uint32_t1393lsc_bti_ex_desc(const struct intel_device_info *devinfo, unsigned bti)1394{1395assert(devinfo->has_lsc);1396return SET_BITS(bti, 31, 24) |1397SET_BITS(0, 23, 12); /* base offset */1398}13991400static inline unsigned1401lsc_bti_ex_desc_base_offset(const struct intel_device_info *devinfo,1402uint32_t ex_desc)1403{1404assert(devinfo->has_lsc);1405return GET_BITS(ex_desc, 23, 12);1406}14071408static inline unsigned1409lsc_bti_ex_desc_index(const struct intel_device_info *devinfo,1410uint32_t ex_desc)1411{1412assert(devinfo->has_lsc);1413return GET_BITS(ex_desc, 31, 24);1414}14151416static inline unsigned1417lsc_flat_ex_desc_base_offset(const struct intel_device_info *devinfo,1418uint32_t ex_desc)1419{1420assert(devinfo->has_lsc);1421return GET_BITS(ex_desc, 31, 12);1422}14231424static inline uint32_t1425lsc_bss_ex_desc(const struct intel_device_info *devinfo,1426unsigned surface_state_index)1427{1428assert(devinfo->has_lsc);1429return SET_BITS(surface_state_index, 31, 6);1430}14311432static inline unsigned1433lsc_bss_ex_desc_index(const struct intel_device_info *devinfo,1434uint32_t ex_desc)1435{1436assert(devinfo->has_lsc);1437return GET_BITS(ex_desc, 31, 6);1438}14391440static inline uint32_t1441brw_mdc_sm2(unsigned exec_size)1442{1443assert(exec_size == 8 || exec_size == 16);1444return exec_size > 8;1445}14461447static inline uint32_t1448brw_mdc_sm2_exec_size(uint32_t sm2)1449{1450assert(sm2 <= 1);1451return 8 << sm2;1452}14531454static inline uint32_t1455brw_btd_spawn_desc(ASSERTED const struct intel_device_info *devinfo,1456unsigned exec_size, unsigned msg_type)1457{1458assert(devinfo->has_ray_tracing);14591460return SET_BITS(0, 19, 19) | /* No header */1461SET_BITS(msg_type, 17, 14) |1462SET_BITS(brw_mdc_sm2(exec_size), 8, 8);1463}14641465static inline uint32_t1466brw_btd_spawn_msg_type(UNUSED const struct intel_device_info *devinfo,1467uint32_t desc)1468{1469return GET_BITS(desc, 17, 14);1470}14711472static inline uint32_t1473brw_btd_spawn_exec_size(UNUSED const struct intel_device_info *devinfo,1474uint32_t desc)1475{1476return brw_mdc_sm2_exec_size(GET_BITS(desc, 8, 8));1477}14781479static inline uint32_t1480brw_rt_trace_ray_desc(ASSERTED const struct intel_device_info *devinfo,1481unsigned exec_size)1482{1483assert(devinfo->has_ray_tracing);14841485return SET_BITS(0, 19, 19) | /* No header */1486SET_BITS(0, 17, 14) | /* Message type */1487SET_BITS(brw_mdc_sm2(exec_size), 8, 8);1488}14891490static inline uint32_t1491brw_rt_trace_ray_desc_exec_size(UNUSED const struct intel_device_info *devinfo,1492uint32_t desc)1493{1494return brw_mdc_sm2_exec_size(GET_BITS(desc, 8, 8));1495}14961497/**1498* Construct a message descriptor immediate with the specified pixel1499* interpolator function controls.1500*/1501static inline uint32_t1502brw_pixel_interp_desc(UNUSED const struct intel_device_info *devinfo,1503unsigned msg_type,1504bool noperspective,1505bool coarse_pixel_rate,1506unsigned simd_mode,1507unsigned slot_group)1508{1509assert(devinfo->ver >= 10 || !coarse_pixel_rate);1510return (SET_BITS(slot_group, 11, 11) |1511SET_BITS(msg_type, 13, 12) |1512SET_BITS(!!noperspective, 14, 14) |1513SET_BITS(coarse_pixel_rate, 15, 15) |1514SET_BITS(simd_mode, 16, 16));1515}15161517void brw_urb_WRITE(struct brw_codegen *p,1518struct brw_reg dest,1519unsigned msg_reg_nr,1520struct brw_reg src0,1521enum brw_urb_write_flags flags,1522unsigned msg_length,1523unsigned response_length,1524unsigned offset,1525unsigned swizzle);15261527/**1528* Send message to shared unit \p sfid with a possibly indirect descriptor \p1529* desc. If \p desc is not an immediate it will be transparently loaded to an1530* address register using an OR instruction.1531*/1532void1533brw_send_indirect_message(struct brw_codegen *p,1534unsigned sfid,1535struct brw_reg dst,1536struct brw_reg payload,1537struct brw_reg desc,1538unsigned desc_imm,1539bool eot);15401541void1542brw_send_indirect_split_message(struct brw_codegen *p,1543unsigned sfid,1544struct brw_reg dst,1545struct brw_reg payload0,1546struct brw_reg payload1,1547struct brw_reg desc,1548unsigned desc_imm,1549struct brw_reg ex_desc,1550unsigned ex_desc_imm,1551bool eot);15521553void brw_ff_sync(struct brw_codegen *p,1554struct brw_reg dest,1555unsigned msg_reg_nr,1556struct brw_reg src0,1557bool allocate,1558unsigned response_length,1559bool eot);15601561void brw_svb_write(struct brw_codegen *p,1562struct brw_reg dest,1563unsigned msg_reg_nr,1564struct brw_reg src0,1565unsigned binding_table_index,1566bool send_commit_msg);15671568brw_inst *brw_fb_WRITE(struct brw_codegen *p,1569struct brw_reg payload,1570struct brw_reg implied_header,1571unsigned msg_control,1572unsigned binding_table_index,1573unsigned msg_length,1574unsigned response_length,1575bool eot,1576bool last_render_target,1577bool header_present);15781579brw_inst *gfx9_fb_READ(struct brw_codegen *p,1580struct brw_reg dst,1581struct brw_reg payload,1582unsigned binding_table_index,1583unsigned msg_length,1584unsigned response_length,1585bool per_sample);15861587void brw_SAMPLE(struct brw_codegen *p,1588struct brw_reg dest,1589unsigned msg_reg_nr,1590struct brw_reg src0,1591unsigned binding_table_index,1592unsigned sampler,1593unsigned msg_type,1594unsigned response_length,1595unsigned msg_length,1596unsigned header_present,1597unsigned simd_mode,1598unsigned return_format);15991600void brw_adjust_sampler_state_pointer(struct brw_codegen *p,1601struct brw_reg header,1602struct brw_reg sampler_index);16031604void gfx4_math(struct brw_codegen *p,1605struct brw_reg dest,1606unsigned function,1607unsigned msg_reg_nr,1608struct brw_reg src,1609unsigned precision );16101611void gfx6_math(struct brw_codegen *p,1612struct brw_reg dest,1613unsigned function,1614struct brw_reg src0,1615struct brw_reg src1);16161617void brw_oword_block_read(struct brw_codegen *p,1618struct brw_reg dest,1619struct brw_reg mrf,1620uint32_t offset,1621uint32_t bind_table_index);16221623unsigned brw_scratch_surface_idx(const struct brw_codegen *p);16241625void brw_oword_block_read_scratch(struct brw_codegen *p,1626struct brw_reg dest,1627struct brw_reg mrf,1628int num_regs,1629unsigned offset);16301631void brw_oword_block_write_scratch(struct brw_codegen *p,1632struct brw_reg mrf,1633int num_regs,1634unsigned offset);16351636void gfx7_block_read_scratch(struct brw_codegen *p,1637struct brw_reg dest,1638int num_regs,1639unsigned offset);16401641void brw_shader_time_add(struct brw_codegen *p,1642struct brw_reg payload,1643uint32_t surf_index);16441645/**1646* Return the generation-specific jump distance scaling factor.1647*1648* Given the number of instructions to jump, we need to scale by1649* some number to obtain the actual jump distance to program in an1650* instruction.1651*/1652static inline unsigned1653brw_jump_scale(const struct intel_device_info *devinfo)1654{1655/* Broadwell measures jump targets in bytes. */1656if (devinfo->ver >= 8)1657return 16;16581659/* Ironlake and later measure jump targets in 64-bit data chunks (in order1660* (to support compaction), so each 128-bit instruction requires 2 chunks.1661*/1662if (devinfo->ver >= 5)1663return 2;16641665/* Gfx4 simply uses the number of 128-bit instructions. */1666return 1;1667}16681669void brw_barrier(struct brw_codegen *p, struct brw_reg src);16701671/* If/else/endif. Works by manipulating the execution flags on each1672* channel.1673*/1674brw_inst *brw_IF(struct brw_codegen *p, unsigned execute_size);1675brw_inst *gfx6_IF(struct brw_codegen *p, enum brw_conditional_mod conditional,1676struct brw_reg src0, struct brw_reg src1);16771678void brw_ELSE(struct brw_codegen *p);1679void brw_ENDIF(struct brw_codegen *p);16801681/* DO/WHILE loops:1682*/1683brw_inst *brw_DO(struct brw_codegen *p, unsigned execute_size);16841685brw_inst *brw_WHILE(struct brw_codegen *p);16861687brw_inst *brw_BREAK(struct brw_codegen *p);1688brw_inst *brw_CONT(struct brw_codegen *p);1689brw_inst *brw_HALT(struct brw_codegen *p);16901691/* Forward jumps:1692*/1693void brw_land_fwd_jump(struct brw_codegen *p, int jmp_insn_idx);16941695brw_inst *brw_JMPI(struct brw_codegen *p, struct brw_reg index,1696unsigned predicate_control);16971698void brw_NOP(struct brw_codegen *p);16991700void brw_WAIT(struct brw_codegen *p);17011702void brw_SYNC(struct brw_codegen *p, enum tgl_sync_function func);17031704/* Special case: there is never a destination, execution size will be1705* taken from src0:1706*/1707void brw_CMP(struct brw_codegen *p,1708struct brw_reg dest,1709unsigned conditional,1710struct brw_reg src0,1711struct brw_reg src1);17121713void brw_CMPN(struct brw_codegen *p,1714struct brw_reg dest,1715unsigned conditional,1716struct brw_reg src0,1717struct brw_reg src1);17181719void1720brw_untyped_atomic(struct brw_codegen *p,1721struct brw_reg dst,1722struct brw_reg payload,1723struct brw_reg surface,1724unsigned atomic_op,1725unsigned msg_length,1726bool response_expected,1727bool header_present);17281729void1730brw_untyped_surface_read(struct brw_codegen *p,1731struct brw_reg dst,1732struct brw_reg payload,1733struct brw_reg surface,1734unsigned msg_length,1735unsigned num_channels);17361737void1738brw_untyped_surface_write(struct brw_codegen *p,1739struct brw_reg payload,1740struct brw_reg surface,1741unsigned msg_length,1742unsigned num_channels,1743bool header_present);17441745void1746brw_memory_fence(struct brw_codegen *p,1747struct brw_reg dst,1748struct brw_reg src,1749enum opcode send_op,1750enum brw_message_target sfid,1751bool commit_enable,1752unsigned bti);17531754void1755brw_pixel_interpolator_query(struct brw_codegen *p,1756struct brw_reg dest,1757struct brw_reg mrf,1758bool noperspective,1759bool coarse_pixel_rate,1760unsigned mode,1761struct brw_reg data,1762unsigned msg_length,1763unsigned response_length);17641765void1766brw_find_live_channel(struct brw_codegen *p,1767struct brw_reg dst,1768struct brw_reg mask);17691770void1771brw_broadcast(struct brw_codegen *p,1772struct brw_reg dst,1773struct brw_reg src,1774struct brw_reg idx);17751776void1777brw_float_controls_mode(struct brw_codegen *p,1778unsigned mode, unsigned mask);17791780void1781brw_update_reloc_imm(const struct intel_device_info *devinfo,1782brw_inst *inst,1783uint32_t value);17841785void1786brw_MOV_reloc_imm(struct brw_codegen *p,1787struct brw_reg dst,1788enum brw_reg_type src_type,1789uint32_t id);17901791/***********************************************************************1792* brw_eu_util.c:1793*/17941795void brw_copy_indirect_to_indirect(struct brw_codegen *p,1796struct brw_indirect dst_ptr,1797struct brw_indirect src_ptr,1798unsigned count);17991800void brw_copy_from_indirect(struct brw_codegen *p,1801struct brw_reg dst,1802struct brw_indirect ptr,1803unsigned count);18041805void brw_copy4(struct brw_codegen *p,1806struct brw_reg dst,1807struct brw_reg src,1808unsigned count);18091810void brw_copy8(struct brw_codegen *p,1811struct brw_reg dst,1812struct brw_reg src,1813unsigned count);18141815void brw_math_invert( struct brw_codegen *p,1816struct brw_reg dst,1817struct brw_reg src);18181819void brw_set_src1(struct brw_codegen *p, brw_inst *insn, struct brw_reg reg);18201821void brw_set_desc_ex(struct brw_codegen *p, brw_inst *insn,1822unsigned desc, unsigned ex_desc);18231824static inline void1825brw_set_desc(struct brw_codegen *p, brw_inst *insn, unsigned desc)1826{1827brw_set_desc_ex(p, insn, desc, 0);1828}18291830void brw_set_uip_jip(struct brw_codegen *p, int start_offset);18311832enum brw_conditional_mod brw_negate_cmod(enum brw_conditional_mod cmod);1833enum brw_conditional_mod brw_swap_cmod(enum brw_conditional_mod cmod);18341835/* brw_eu_compact.c */1836void brw_compact_instructions(struct brw_codegen *p, int start_offset,1837struct disasm_info *disasm);1838void brw_uncompact_instruction(const struct intel_device_info *devinfo,1839brw_inst *dst, brw_compact_inst *src);1840bool brw_try_compact_instruction(const struct intel_device_info *devinfo,1841brw_compact_inst *dst, const brw_inst *src);18421843void brw_debug_compact_uncompact(const struct intel_device_info *devinfo,1844brw_inst *orig, brw_inst *uncompacted);18451846/* brw_eu_validate.c */1847bool brw_validate_instruction(const struct intel_device_info *devinfo,1848const brw_inst *inst, int offset,1849struct disasm_info *disasm);1850bool brw_validate_instructions(const struct intel_device_info *devinfo,1851const void *assembly, int start_offset, int end_offset,1852struct disasm_info *disasm);18531854static inline int1855next_offset(const struct intel_device_info *devinfo, void *store, int offset)1856{1857brw_inst *insn = (brw_inst *)((char *)store + offset);18581859if (brw_inst_cmpt_control(devinfo, insn))1860return offset + 8;1861else1862return offset + 16;1863}18641865struct opcode_desc {1866unsigned ir;1867unsigned hw;1868const char *name;1869int nsrc;1870int ndst;1871int gfx_vers;1872};18731874const struct opcode_desc *1875brw_opcode_desc(const struct intel_device_info *devinfo, enum opcode opcode);18761877const struct opcode_desc *1878brw_opcode_desc_from_hw(const struct intel_device_info *devinfo, unsigned hw);18791880static inline unsigned1881brw_opcode_encode(const struct intel_device_info *devinfo, enum opcode opcode)1882{1883return brw_opcode_desc(devinfo, opcode)->hw;1884}18851886static inline enum opcode1887brw_opcode_decode(const struct intel_device_info *devinfo, unsigned hw)1888{1889const struct opcode_desc *desc = brw_opcode_desc_from_hw(devinfo, hw);1890return desc ? (enum opcode)desc->ir : BRW_OPCODE_ILLEGAL;1891}18921893static inline void1894brw_inst_set_opcode(const struct intel_device_info *devinfo,1895brw_inst *inst, enum opcode opcode)1896{1897brw_inst_set_hw_opcode(devinfo, inst, brw_opcode_encode(devinfo, opcode));1898}18991900static inline enum opcode1901brw_inst_opcode(const struct intel_device_info *devinfo, const brw_inst *inst)1902{1903return brw_opcode_decode(devinfo, brw_inst_hw_opcode(devinfo, inst));1904}19051906static inline bool1907is_3src(const struct intel_device_info *devinfo, enum opcode opcode)1908{1909const struct opcode_desc *desc = brw_opcode_desc(devinfo, opcode);1910return desc && desc->nsrc == 3;1911}19121913/** Maximum SEND message length */1914#define BRW_MAX_MSG_LENGTH 1519151916/** First MRF register used by pull loads */1917#define FIRST_SPILL_MRF(gen) ((gen) == 6 ? 21 : 13)19181919/** First MRF register used by spills */1920#define FIRST_PULL_LOAD_MRF(gen) ((gen) == 6 ? 16 : 13)19211922#ifdef __cplusplus1923}1924#endif19251926#endif192719281929