18411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga/* 28411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * Copyright © 2014 Intel Corporation 38411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 48411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * Permission is hereby granted, free of charge, to any person obtaining a 58411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * copy of this software and associated documentation files (the "Software"), 68411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * to deal in the Software without restriction, including without limitation 78411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * and/or sell copies of the Software, and to permit persons to whom the 98411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * Software is furnished to do so, subject to the following conditions: 108411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 118411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * The above copyright notice and this permission notice (including the next 128411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * paragraph) shall be included in all copies or substantial portions of the 138411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * Software. 148411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 158411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 188411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 198411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 208411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 218411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * IN THE SOFTWARE. 228411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 238411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * This code is based on original work by Ilia Mirkin. 248411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 258411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 268411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga/** 278411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * \file gen6_gs_visitor.cpp 288411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 298411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * Gen6 geometry shader implementation 308411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 318411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 328411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga#include "gen6_gs_visitor.h" 33f36993b46962eab4446bc1964eb47149751aee26Matt Turner#include "brw_eu.h" 348411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 358411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroganamespace brw { 368411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 378411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogavoid 388411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogagen6_gs_visitor::emit_prolog() 398411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga{ 408411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga vec4_gs_visitor::emit_prolog(); 418411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 428411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* Gen6 geometry shaders require to allocate an initial VUE handle via 438411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * FF_SYNC message, however the documentation remarks that only one thread 448411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * can write to the URB simultaneously and the FF_SYNC message provides the 458411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * synchronization mechanism for this, so using this message effectively 468411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * stalls the thread until it is its turn to write to the URB. Because of 478411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * this, the best way to implement geometry shader algorithms in gen6 is to 488411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * execute the algorithm before the FF_SYNC message to maximize parallelism. 498411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 508411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * To achieve this we buffer the geometry shader outputs for each emitted 518411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * vertex in vertex_output during operation. Then, when we have processed 528411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * the last vertex (that is, at thread end time), we send the FF_SYNC 538411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * message to allocate the initial VUE handle and write all buffered vertex 548411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * data to the URB in one go. 558411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 568411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * For each emitted vertex, vertex_output will hold vue_map.num_slots 578411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * data items plus one additional item to hold required flags 588411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * (PrimType, PrimStart, PrimEnd, as expected by the URB_WRITE message) 598411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * which come right after the data items for that vertex. Vertex data and 608411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * flags for the next vertex come right after the data items and flags for 618411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * the previous vertex. 628411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 638411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->current_annotation = "gen6 prolog"; 648411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->vertex_output = src_reg(this, 658411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga glsl_type::uint_type, 668411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga (prog_data->vue_map.num_slots + 1) * 67e1af20f18a86f52a9640faf2d4ff8a71b0a4fa9bTimothy Arceri nir->info->gs.vertices_out); 688411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->vertex_output_offset = src_reg(this, glsl_type::uint_type); 69f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->vertex_output_offset), brw_imm_ud(0u))); 708411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 718411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* MRF 1 will be the header for all messages (FF_SYNC and URB_WRITES), 728411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * so initialize it once to R0. 738411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 748411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga vec4_instruction *inst = emit(MOV(dst_reg(MRF, 1), 758411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga retype(brw_vec8_grf(0, 0), 768411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga BRW_REGISTER_TYPE_UD))); 778411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst->force_writemask_all = true; 788411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 798411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* This will be used as a temporary to store writeback data of FF_SYNC 808411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * and URB_WRITE messages. 818411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 828411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->temp = src_reg(this, glsl_type::uint_type); 83d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga 84d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga /* This will be used to know when we are processing the first vertex of 85d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * a primitive. We will set this to URB_WRITE_PRIM_START only when we know 86d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * that we are processing the first vertex in the primitive and to zero 87d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * otherwise. This way we can use its value directly in the URB write 88d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * headers. 89d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga */ 90d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga this->first_vertex = src_reg(this, glsl_type::uint_type); 91f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->first_vertex), brw_imm_ud(URB_WRITE_PRIM_START))); 92d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga 93d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga /* The FF_SYNC message requires to know the number of primitives generated, 94d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * so keep a counter for this. 95d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga */ 96d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga this->prim_count = src_reg(this, glsl_type::uint_type); 97f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->prim_count), brw_imm_ud(0u))); 98524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 99340b22c217f31330ae3bfaa523b574d98ca53e89Timothy Arceri if (prog->info.has_transform_feedback_varyings) { 100fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Create a virtual register to hold destination indices in SOL */ 101fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->destination_indices = src_reg(this, glsl_type::uvec4_type); 102fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Create a virtual register to hold number of written primitives */ 103fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->sol_prim_written = src_reg(this, glsl_type::uint_type); 104fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Create a virtual register to hold Streamed Vertex Buffer Indices */ 105fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->svbi = src_reg(this, glsl_type::uvec4_type); 106fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Create a virtual register to hold max values of SVBI */ 107fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->max_svbi = src_reg(this, glsl_type::uvec4_type); 108fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(MOV(dst_reg(this->max_svbi), 109fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez src_reg(retype(brw_vec1_grf(1, 4), BRW_REGISTER_TYPE_UD)))); 1102614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga 1112614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga xfb_setup(); 112fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 113fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 114524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga /* PrimitveID is delivered in r0.1 of the thread payload. If the program 115524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * needs it we have to move it to a separate register where we can map 116524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * the atttribute. 117524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * 118524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * Notice that we cannot use a virtual register for this, because we need to 119524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * map all input attributes to hardware registers in setup_payload(), 120524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * which happens before virtual registers are mapped to hardware registers. 121524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * We could work around that issue if we were able to compute the first 122524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * non-payload register here and move the PrimitiveID information to that 123524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * register, but we can't because at this point we don't know the final 124524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * number uniforms that will be included in the payload. 125524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * 126524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * So, what we do is to place PrimitiveID information in r1, which is always 127524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * delivered as part of the payload, but its only populated with data 128524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * relevant for transform feedback when we set GEN6_GS_SVBI_PAYLOAD_ENABLE 129524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * in the 3DSTATE_GS state packet. That information can be obtained by other 130524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * means though, so we can safely use r1 for this purpose. 131524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga */ 132fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand if (gs_prog_data->include_primitive_id) { 133524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga this->primitive_id = 134524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga src_reg(retype(brw_vec8_grf(1, 0), BRW_REGISTER_TYPE_UD)); 135524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga emit(GS_OPCODE_SET_PRIMITIVE_ID, dst_reg(this->primitive_id)); 136524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga } 1378411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga} 1388411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 1398411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogavoid 1407eced3aa863394c6e74ac3f037ed1cf9c481fe37Samuel Iglesias Gonsálvezgen6_gs_visitor::gs_emit_vertex(int stream_id) 1418411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga{ 1428411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->current_annotation = "gen6 emit vertex"; 143df31c1850d14729e27513ae733110a668f6b6e95Kenneth Graunke 14431a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke /* Buffer all output slots for this vertex in vertex_output */ 14531a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke for (int slot = 0; slot < prog_data->vue_map.num_slots; ++slot) { 14631a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke int varying = prog_data->vue_map.slot_to_varying[slot]; 14731a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke if (varying != VARYING_SLOT_PSIZ) { 14831a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke dst_reg dst(this->vertex_output); 14931a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke dst.reladdr = ralloc(mem_ctx, src_reg); 15031a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke memcpy(dst.reladdr, &this->vertex_output_offset, sizeof(src_reg)); 15131a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke emit_urb_slot(dst, varying); 152d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga } else { 15331a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke /* The PSIZ slot can pack multiple varyings in different channels 15431a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * and emit_urb_slot() will produce a MOV instruction for each of 15531a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * them. Since we are writing to an array, that will translate to 15631a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * possibly multiple MOV instructions with an array destination and 15731a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * each will generate a scratch write with the same offset into 15831a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * scratch space (thus, each one overwriting the previous). This is 15931a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * not what we want. What we will do instead is emit PSIZ to a 16031a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * a regular temporary register, then move that resgister into the 16131a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * array. This way we only have one instruction with an array 16231a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * destination and we only produce a single scratch write. 163d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga */ 16431a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke dst_reg tmp = dst_reg(src_reg(this, glsl_type::uvec4_type)); 16531a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke emit_urb_slot(tmp, varying); 16631a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke dst_reg dst(this->vertex_output); 16731a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke dst.reladdr = ralloc(mem_ctx, src_reg); 16831a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke memcpy(dst.reladdr, &this->vertex_output_offset, sizeof(src_reg)); 16931a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke vec4_instruction *inst = emit(MOV(dst, src_reg(tmp))); 17031a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke inst->force_writemask_all = true; 1718411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga } 17231a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke 1738411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga emit(ADD(dst_reg(this->vertex_output_offset), 174f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner this->vertex_output_offset, brw_imm_ud(1u))); 1758411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga } 17631a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke 17731a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke /* Now buffer flags for this vertex */ 17831a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke dst_reg dst(this->vertex_output); 17931a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke dst.reladdr = ralloc(mem_ctx, src_reg); 18031a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke memcpy(dst.reladdr, &this->vertex_output_offset, sizeof(src_reg)); 181e1af20f18a86f52a9640faf2d4ff8a71b0a4fa9bTimothy Arceri if (nir->info->gs.output_primitive == GL_POINTS) { 18231a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke /* If we are outputting points, then every vertex has PrimStart and 18331a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * PrimEnd set. 18431a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke */ 185f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst, brw_imm_d((_3DPRIM_POINTLIST << URB_WRITE_PRIM_TYPE_SHIFT) | 186f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner URB_WRITE_PRIM_START | URB_WRITE_PRIM_END))); 187f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(ADD(dst_reg(this->prim_count), this->prim_count, brw_imm_ud(1u))); 18831a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke } else { 18931a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke /* Otherwise, we can only set the PrimStart flag, which we have stored 19031a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * in the first_vertex register. We will have to wait until we execute 19131a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * EndPrimitive() or we end the thread to set the PrimEnd flag on a 19231a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke * vertex. 19331a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke */ 19431a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke emit(OR(dst, this->first_vertex, 195f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner brw_imm_ud(gs_prog_data->output_topology << 196f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner URB_WRITE_PRIM_TYPE_SHIFT))); 197f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->first_vertex), brw_imm_ud(0u))); 19831a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke } 19931a36ffbc81a4dd79b91bf0fc59f0e5f8d44dbd7Kenneth Graunke emit(ADD(dst_reg(this->vertex_output_offset), 200f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner this->vertex_output_offset, brw_imm_ud(1u))); 2018411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga} 2028411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 2038411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogavoid 2047eced3aa863394c6e74ac3f037ed1cf9c481fe37Samuel Iglesias Gonsálvezgen6_gs_visitor::gs_end_primitive() 2057eced3aa863394c6e74ac3f037ed1cf9c481fe37Samuel Iglesias Gonsálvez{ 2068411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->current_annotation = "gen6 end primitive"; 2078411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* Calling EndPrimitive() is optional for point output. In this case we set 2088411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * the PrimEnd flag when we process EmitVertex(). 2098411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 210e1af20f18a86f52a9640faf2d4ff8a71b0a4fa9bTimothy Arceri if (nir->info->gs.output_primitive == GL_POINTS) 2118411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga return; 212d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga 213d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga /* Otherwise we know that the last vertex we have processed was the last 214d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * vertex in the primitive and we need to set its PrimEnd flag, so do this 215c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * unless we haven't emitted that vertex at all (vertex_count != 0). 216d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * 217d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * Notice that we have already incremented vertex_count when we processed 218d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * the last emit_vertex, so we need to take that into account in the 219d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * comparison below (hence the num_output_vertices + 1 in the comparison 220d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * below). 221d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga */ 222e1af20f18a86f52a9640faf2d4ff8a71b0a4fa9bTimothy Arceri unsigned num_output_vertices = nir->info->gs.vertices_out; 223f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(CMP(dst_null_ud(), this->vertex_count, 224f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner brw_imm_ud(num_output_vertices + 1), BRW_CONDITIONAL_L)); 225f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner vec4_instruction *inst = emit(CMP(dst_null_ud(), 226f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner this->vertex_count, brw_imm_ud(0u), 227c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga BRW_CONDITIONAL_NEQ)); 228c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga inst->predicate = BRW_PREDICATE_NORMAL; 229d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga emit(IF(BRW_PREDICATE_NORMAL)); 230d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga { 231d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga /* vertex_output_offset is already pointing at the first entry of the 232d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * next vertex. So subtract 1 to modify the flags for the previous 233d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * vertex. 234d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga */ 235d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga src_reg offset(this, glsl_type::uint_type); 236f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(ADD(dst_reg(offset), this->vertex_output_offset, brw_imm_d(-1))); 237d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga 238d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga src_reg dst(this->vertex_output); 239d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga dst.reladdr = ralloc(mem_ctx, src_reg); 240d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga memcpy(dst.reladdr, &offset, sizeof(src_reg)); 241d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga 242f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(OR(dst_reg(dst), dst, brw_imm_d(URB_WRITE_PRIM_END))); 243f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(ADD(dst_reg(this->prim_count), this->prim_count, brw_imm_ud(1u))); 244d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga 245d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga /* Set the first vertex flag to indicate that the next vertex will start 246d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga * a primitive. 247d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga */ 248f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->first_vertex), brw_imm_d(URB_WRITE_PRIM_START))); 249d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga } 250d93ca68666675392e632a5c0f99a33ff25a42e53Iago Toral Quiroga emit(BRW_OPCODE_ENDIF); 2518411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga} 2528411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 2538411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogavoid 2548411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogagen6_gs_visitor::emit_urb_write_header(int mrf) 2558411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga{ 2568411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->current_annotation = "gen6 urb header"; 2578411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* Compute offset of the flags for the current vertex in vertex_output and 2588411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * write them in dw2 of the message header. 2598411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 2608411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * Notice that by the time that emit_thread_end() calls here 2618411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * vertex_output_offset should point to the first data item of the current 2628411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * vertex in vertex_output, thus we only need to add the number of output 2638411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * slots per vertex to that offset to obtain the flags data offset. 2648411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 2658411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga src_reg flags_offset(this, glsl_type::uint_type); 2668411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga emit(ADD(dst_reg(flags_offset), 267f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner this->vertex_output_offset, 268f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner brw_imm_d(prog_data->vue_map.num_slots))); 2698411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 2708411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga src_reg flags_data(this->vertex_output); 2718411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga flags_data.reladdr = ralloc(mem_ctx, src_reg); 2728411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga memcpy(flags_data.reladdr, &flags_offset, sizeof(src_reg)); 2738411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 2748411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga emit(GS_OPCODE_SET_DWORD_2, dst_reg(MRF, mrf), flags_data); 2758411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga} 2768411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 2771efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quirogastatic int 2781efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quirogaalign_interleaved_urb_mlen(int mlen) 2791efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga{ 2801efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga /* URB data written (does not include the message header reg) must 2811efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga * be a multiple of 256 bits, or 2 VS registers. See vol5c.5, 2821efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga * section 5.4.3.2.2: URB_INTERLEAVED. 2831efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga */ 2841efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga if ((mlen % 2) != 1) 2851efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga mlen++; 2861efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga return mlen; 2871efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga} 2881efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga 2898411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogavoid 290c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quirogagen6_gs_visitor::emit_urb_write_opcode(bool complete, int base_mrf, 291c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga int last_mrf, int urb_offset) 2928411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga{ 2938411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga vec4_instruction *inst = NULL; 2948411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 2958411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga if (!complete) { 296c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* If the vertex is not complete we don't have to do anything special */ 2978411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst = emit(GS_OPCODE_URB_WRITE); 2988411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst->urb_write_flags = BRW_URB_WRITE_NO_FLAGS; 299c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga } else { 300c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* Otherwise we always request to allocate a new VUE handle. If this is 301c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * the last write before the EOT message and the new handle never gets 302c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * used it will be dereferenced when we send the EOT message. This is 303c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * necessary to avoid different setups for the EOT message (one for the 304c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * case when there is no output and another for the case when there is) 305c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * which would require to end the program with an IF/ELSE/ENDIF block, 306c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * something we do not want. 307c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga */ 3088411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst = emit(GS_OPCODE_URB_WRITE_ALLOCATE); 3098411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst->urb_write_flags = BRW_URB_WRITE_COMPLETE; 3108411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst->dst = dst_reg(MRF, base_mrf); 3118411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst->src[0] = this->temp; 3128411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga } 313c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga 314c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga inst->base_mrf = base_mrf; 3151efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga inst->mlen = align_interleaved_urb_mlen(last_mrf - base_mrf); 316c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga inst->offset = urb_offset; 3178411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga} 3188411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 3198411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogavoid 3208411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quirogagen6_gs_visitor::emit_thread_end() 3218411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga{ 322c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga /* Make sure the current primitive is ended: we know it is not ended when 323c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga * first_vertex is not zero. This is only relevant for outputs other than 324c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga * points because in the point case we set PrimEnd on all vertices. 325c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga */ 326e1af20f18a86f52a9640faf2d4ff8a71b0a4fa9bTimothy Arceri if (nir->info->gs.output_primitive != GL_POINTS) { 327f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(CMP(dst_null_ud(), this->first_vertex, brw_imm_ud(0u), BRW_CONDITIONAL_Z)); 328c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga emit(IF(BRW_PREDICATE_NORMAL)); 3291153f12076d121fd0213f58f1953872a60da041dJason Ekstrand gs_end_primitive(); 330c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga emit(BRW_OPCODE_ENDIF); 331c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga } 332c1b8a5155b4026ac6d0fdeae9afd12e489ef106bIago Toral Quiroga 3338411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* Here we have to: 3348411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 1) Emit an FF_SYNC messsage to obtain an initial VUE handle. 3358411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 2) Loop over all buffered vertex data and write it to corresponding 3368411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * URB entries. 3378411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 3) Allocate new VUE handles for all vertices other than the first. 3388411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 4) Send a final EOT message. 3398411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 3408411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 3418411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* MRF 0 is reserved for the debugger, so start with message header 3428411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * in MRF 1. 3438411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 3448411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga int base_mrf = 1; 3458411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 3468411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* In the process of generating our URB write message contents, we 3478411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * may need to unspill a register or load from an array. Those 3481efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga * reads would use MRFs 21..23 3498411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 3501efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga int max_usable_mrf = FIRST_SPILL_MRF(devinfo->gen); 3518411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 3528411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* Issue the FF_SYNC message and obtain the initial VUE handle. */ 353f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), BRW_CONDITIONAL_G)); 354c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit(IF(BRW_PREDICATE_NORMAL)); 3558411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga { 356c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga this->current_annotation = "gen6 thread end: ff_sync"; 357fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 358fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez vec4_instruction *inst; 359340b22c217f31330ae3bfaa523b574d98ca53e89Timothy Arceri if (prog->info.has_transform_feedback_varyings) { 360fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez src_reg sol_temp(this, glsl_type::uvec4_type); 361fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(GS_OPCODE_FF_SYNC_SET_PRIMITIVES, 362fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez dst_reg(this->svbi), 363fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->vertex_count, 364fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->prim_count, 365fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez sol_temp); 366fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez inst = emit(GS_OPCODE_FF_SYNC, 367fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez dst_reg(this->temp), this->prim_count, this->svbi); 368fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } else { 369fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez inst = emit(GS_OPCODE_FF_SYNC, 370f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner dst_reg(this->temp), this->prim_count, brw_imm_ud(0u)); 371fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 372c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga inst->base_mrf = base_mrf; 3738411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 374c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* Loop over all buffered vertices and emit URB write messages */ 375c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga this->current_annotation = "gen6 thread end: urb writes init"; 376c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga src_reg vertex(this, glsl_type::uint_type); 377f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(vertex), brw_imm_ud(0u))); 378f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->vertex_output_offset), brw_imm_ud(0u))); 3798411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 380c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga this->current_annotation = "gen6 thread end: urb writes"; 381c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit(BRW_OPCODE_DO); 382c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga { 383c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit(CMP(dst_null_d(), vertex, this->vertex_count, BRW_CONDITIONAL_GE)); 384c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga inst = emit(BRW_OPCODE_BREAK); 385c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga inst->predicate = BRW_PREDICATE_NORMAL; 3868411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 387c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* First we prepare the message header */ 388c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit_urb_write_header(base_mrf); 3898411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 390c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* Then add vertex data to the message in interleaved fashion */ 391c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga int slot = 0; 392c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga bool complete = false; 393c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga do { 394c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga int mrf = base_mrf + 1; 3958411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 396c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* URB offset is in URB row increments, and each of our MRFs is half 397c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * of one of those, since we're doing interleaved writes. 3988411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 399c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga int urb_offset = slot / 2; 400c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga 401c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga for (; slot < prog_data->vue_map.num_slots; ++slot) { 402c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga int varying = prog_data->vue_map.slot_to_varying[slot]; 403c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga current_annotation = output_reg_annotation[varying]; 404c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga 405c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* Compute offset of this slot for the current vertex 406c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * in vertex_output 407c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga */ 408c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga src_reg data(this->vertex_output); 409c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga data.reladdr = ralloc(mem_ctx, src_reg); 410c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga memcpy(data.reladdr, &this->vertex_output_offset, 411c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga sizeof(src_reg)); 412c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga 41321204434845398de86fb707c78dd5bdd1fb5826fSamuel Iglesias Gonsálvez /* Copy this slot to the appropriate message register */ 41421204434845398de86fb707c78dd5bdd1fb5826fSamuel Iglesias Gonsálvez dst_reg reg = dst_reg(MRF, mrf); 415f182e5eafc31ebc7c140e9a369d5f747948733aeKenneth Graunke reg.type = output_reg[varying][0].type; 41621204434845398de86fb707c78dd5bdd1fb5826fSamuel Iglesias Gonsálvez data.type = reg.type; 41721204434845398de86fb707c78dd5bdd1fb5826fSamuel Iglesias Gonsálvez vec4_instruction *inst = emit(MOV(reg, data)); 41821204434845398de86fb707c78dd5bdd1fb5826fSamuel Iglesias Gonsálvez inst->force_writemask_all = true; 419c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga 420c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga mrf++; 421c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit(ADD(dst_reg(this->vertex_output_offset), 422f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner this->vertex_output_offset, brw_imm_ud(1u))); 423c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga 424c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* If this was max_usable_mrf, we can't fit anything more into 4251efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga * this URB WRITE. Same if we reached the max. message length. 426c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga */ 4271efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga if (mrf > max_usable_mrf || 4281efbb8151b402f76df6dbf0b4ed9c2823e3a44fdIago Toral Quiroga align_interleaved_urb_mlen(mrf - base_mrf + 1) > BRW_MAX_MSG_LENGTH) { 429c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga slot++; 430c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga break; 431c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga } 4328411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga } 4338411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 434c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga complete = slot >= prog_data->vue_map.num_slots; 435c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit_urb_write_opcode(complete, base_mrf, mrf, urb_offset); 436c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga } while (!complete); 4378411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 438c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga /* Skip over the flags data item so that vertex_output_offset points 439c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * to the first data item of the next vertex, so that we can start 440c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * writing the next vertex. 4418411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 442c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit(ADD(dst_reg(this->vertex_output_offset), 443f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner this->vertex_output_offset, brw_imm_ud(1u))); 4448411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 445f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(ADD(dst_reg(vertex), vertex, brw_imm_ud(1u))); 446c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga } 447c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit(BRW_OPCODE_WHILE); 448fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 449340b22c217f31330ae3bfaa523b574d98ca53e89Timothy Arceri if (prog->info.has_transform_feedback_varyings) 450fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez xfb_write(); 4518411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga } 452c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga emit(BRW_OPCODE_ENDIF); 4538411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 4548411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga /* Finally, emit EOT message. 4558411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga * 456c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * In gen6 we need to end the thread differently depending on whether we have 457c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * emitted at least one vertex or not. In case we did, the EOT message must 458c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * always include the COMPLETE flag or else the GPU hangs. If we have not 459c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * produced any output we can't use the COMPLETE flag. 460c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * 461c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * However, this would lead us to end the program with an ENDIF opcode, 462c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * which we want to avoid, so what we do is that we always request a new 463c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * VUE handle every time we do a URB WRITE, even for the last vertex we emit. 464c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * With this we make sure that whether we have emitted at least one vertex 465c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * or none at all, we have to finish the thread without writing to the URB, 466c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * which works for both cases by setting the COMPLETE and UNUSED flags in 467c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga * the EOT message. 4688411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga */ 4698411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga this->current_annotation = "gen6 thread end: EOT"; 470fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 471340b22c217f31330ae3bfaa523b574d98ca53e89Timothy Arceri if (prog->info.has_transform_feedback_varyings) { 472fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* When emitting EOT, set SONumPrimsWritten Increment Value. */ 473fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez src_reg data(this, glsl_type::uint_type); 474f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(AND(dst_reg(data), this->sol_prim_written, brw_imm_ud(0xffffu))); 475f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(SHL(dst_reg(data), data, brw_imm_ud(16u))); 476fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(GS_OPCODE_SET_DWORD_2, dst_reg(MRF, base_mrf), data); 477fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 478fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 479c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga vec4_instruction *inst = emit(GS_OPCODE_THREAD_END); 480c091804f4cd282bfc03b02a7ef6c72e5f42f6c76Iago Toral Quiroga inst->urb_write_flags = BRW_URB_WRITE_COMPLETE | BRW_URB_WRITE_UNUSED; 4818411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst->base_mrf = base_mrf; 4828411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga inst->mlen = 1; 4838411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga} 4848411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga 485524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quirogavoid 486524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quirogagen6_gs_visitor::setup_payload() 487524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga{ 488524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga int attribute_map[BRW_VARYING_SLOT_COUNT * MAX_GS_INPUT_VERTICES]; 489524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 490524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga /* Attributes are going to be interleaved, so one register contains two 491524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * attribute slots. 492524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga */ 493524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga int attributes_per_reg = 2; 494524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 495524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga /* If a geometry shader tries to read from an input that wasn't written by 496524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * the vertex shader, that produces undefined results, but it shouldn't 497524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * crash anything. So initialize attribute_map to zeros--that ensures that 498524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * these undefined results are read from r0. 499524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga */ 500524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga memset(attribute_map, 0, sizeof(attribute_map)); 501524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 502524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga int reg = 0; 503524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 504524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga /* The payload always contains important data in r0. */ 505524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga reg++; 506524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 507524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga /* r1 is always part of the payload and it holds information relevant 508524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * for transform feedback when we set the GEN6_GS_SVBI_PAYLOAD_ENABLE bit in 509524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * the 3DSTATE_GS packet. We will overwrite it with the PrimitiveID 510524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * information (and move the original value to a virtual register if 511524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga * necessary). 512524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga */ 513fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand if (gs_prog_data->include_primitive_id) 514524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga attribute_map[VARYING_SLOT_PRIMITIVE_ID] = attributes_per_reg * reg; 515524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga reg++; 516524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 517524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga reg = setup_uniforms(reg); 518524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 519524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga reg = setup_varying_inputs(reg, attribute_map, attributes_per_reg); 520524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 521524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga lower_attributes_to_hw_regs(attribute_map, true); 522524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 523524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga this->first_non_payload_grf = reg; 524524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga} 525524ad6b901c3847db9d3528223d4ab2e2f517a1dIago Toral Quiroga 526fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvezvoid 5272614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quirogagen6_gs_visitor::xfb_setup() 528fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez{ 529fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez static const unsigned swizzle_for_offset[4] = { 530fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez BRW_SWIZZLE4(0, 1, 2, 3), 531fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez BRW_SWIZZLE4(1, 2, 3, 3), 532fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez BRW_SWIZZLE4(2, 3, 3, 3), 533fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez BRW_SWIZZLE4(3, 3, 3, 3) 534fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez }; 535fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 5362614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga const struct gl_transform_feedback_info *linked_xfb_info = 5372c0d267717d9b01c644864bae945d29e0a6ca881Timothy Arceri this->prog->sh.LinkedTransformFeedback; 5382614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga int i; 53921204434845398de86fb707c78dd5bdd1fb5826fSamuel Iglesias Gonsálvez 5402614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* Make sure that the VUE slots won't overflow the unsigned chars in 5412614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * prog_data->transform_feedback_bindings[]. 5422614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga */ 5432614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 256); 544fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 5452614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* Make sure that we don't need more binding table entries than we've 5462614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * set aside for use in transform feedback. (We shouldn't, since we 5472614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * set aside enough binding table entries to have one per component). 5482614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga */ 5492614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS); 5502614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga 551fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand gs_prog_data->num_transform_feedback_bindings = linked_xfb_info->NumOutputs; 552fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand for (i = 0; i < gs_prog_data->num_transform_feedback_bindings; i++) { 553fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand gs_prog_data->transform_feedback_bindings[i] = 5542614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga linked_xfb_info->Outputs[i].OutputRegister; 555fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand gs_prog_data->transform_feedback_swizzles[i] = 5562614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset]; 557fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 558fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez} 559fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 560fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvezvoid 561fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvezgen6_gs_visitor::xfb_write() 562fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez{ 563fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez unsigned num_verts; 564fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 565fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand if (!gs_prog_data->num_transform_feedback_bindings) 566fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez return; 567fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 568fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand switch (gs_prog_data->output_topology) { 569fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_POINTLIST: 570fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez num_verts = 1; 571fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez break; 572fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_LINELIST: 573fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_LINESTRIP: 574fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_LINELOOP: 575fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez num_verts = 2; 576fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez break; 577fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_TRILIST: 578fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_TRIFAN: 579fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_TRISTRIP: 580fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_RECTLIST: 581fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez num_verts = 3; 582fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez break; 583fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_QUADLIST: 584fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_QUADSTRIP: 585fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez case _3DPRIM_POLYGON: 586fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez num_verts = 3; 587fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez break; 588fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez default: 589fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez unreachable("Unexpected primitive type in Gen6 SOL program."); 590fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 591fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 592fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->current_annotation = "gen6 thread end: svb writes init"; 593fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 594f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->vertex_output_offset), brw_imm_ud(0u))); 595f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->sol_prim_written), brw_imm_ud(0u))); 596fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 597fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Check that at least one primitive can be written 598fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * 599fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * Note: since we use the binding table to keep track of buffer offsets 600fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * and stride, the GS doesn't need to keep track of a separate pointer 601fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * into each buffer; it uses a single pointer which increments by 1 for 602fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * each vertex. So we use SVBI0 for this pointer, regardless of whether 603fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * transform feedback is in interleaved or separate attribs mode. 604fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez */ 605fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez src_reg sol_temp(this, glsl_type::uvec4_type); 606f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(ADD(dst_reg(sol_temp), this->svbi, brw_imm_ud(num_verts))); 607fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 608fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Compare SVBI calculated number with the maximum value, which is 609fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * in R1.4 (previously saved in this->max_svbi) for gen6. 610fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez */ 611fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(CMP(dst_null_d(), sol_temp, this->max_svbi, BRW_CONDITIONAL_LE)); 612fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(IF(BRW_PREDICATE_NORMAL)); 613fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez { 614ad175113023ec0f67bf51275d0aac20d9e3ea0b9Matt Turner vec4_instruction *inst = emit(MOV(dst_reg(destination_indices), 615ad175113023ec0f67bf51275d0aac20d9e3ea0b9Matt Turner brw_imm_vf4(brw_float_to_vf(0.0), 616ad175113023ec0f67bf51275d0aac20d9e3ea0b9Matt Turner brw_float_to_vf(1.0), 617ad175113023ec0f67bf51275d0aac20d9e3ea0b9Matt Turner brw_float_to_vf(2.0), 618ad175113023ec0f67bf51275d0aac20d9e3ea0b9Matt Turner brw_float_to_vf(0.0)))); 619fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez inst->force_writemask_all = true; 620fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 621fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(ADD(dst_reg(this->destination_indices), 622fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->destination_indices, 623fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->svbi)); 624fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 625fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(BRW_OPCODE_ENDIF); 626fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 6272614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* Write transform feedback data for all processed vertices. */ 628e1af20f18a86f52a9640faf2d4ff8a71b0a4fa9bTimothy Arceri for (int i = 0; i < (int)nir->info->gs.vertices_out; i++) { 629f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(sol_temp), brw_imm_d(i))); 630fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(CMP(dst_null_d(), sol_temp, this->vertex_count, 631fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez BRW_CONDITIONAL_L)); 632fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(IF(BRW_PREDICATE_NORMAL)); 633fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez { 6342614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga xfb_program(i, num_verts); 635fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 636fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(BRW_OPCODE_ENDIF); 637fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 638fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez} 639fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 640fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvezvoid 6412614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quirogagen6_gs_visitor::xfb_program(unsigned vertex, unsigned num_verts) 642fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez{ 643fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez unsigned binding; 644fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand unsigned num_bindings = gs_prog_data->num_transform_feedback_bindings; 645fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez src_reg sol_temp(this, glsl_type::uvec4_type); 646fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 6472614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* Check for buffer overflow: we need room to write the complete primitive 6482614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * (all vertices). Otherwise, avoid writing any vertices for it 6492614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga */ 650f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(ADD(dst_reg(sol_temp), this->sol_prim_written, brw_imm_ud(1u))); 651f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MUL(dst_reg(sol_temp), sol_temp, brw_imm_ud(num_verts))); 652fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(ADD(dst_reg(sol_temp), sol_temp, this->svbi)); 653fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(CMP(dst_null_d(), sol_temp, this->max_svbi, BRW_CONDITIONAL_LE)); 654fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(IF(BRW_PREDICATE_NORMAL)); 655fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez { 656fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Avoid overwriting MRF 1 as it is used as URB write message header */ 657fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez dst_reg mrf_reg(MRF, 2); 658fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 659fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->current_annotation = "gen6: emit SOL vertex data"; 660fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* For each vertex, generate code to output each varying using the 661fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * appropriate binding table entry. 662fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez */ 663fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez for (binding = 0; binding < num_bindings; ++binding) { 6642614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga unsigned char varying = 665fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand gs_prog_data->transform_feedback_bindings[binding]; 6662614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga 667fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Set up the correct destination index for this vertex */ 668fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez vec4_instruction *inst = emit(GS_OPCODE_SVB_SET_DST_INDEX, 669fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez mrf_reg, 670fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->destination_indices); 6712614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga inst->sol_vertex = vertex % num_verts; 672fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 673fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* From the Sandybridge PRM, Volume 2, Part 1, Section 4.5.1: 674fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * 675fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * "Prior to End of Thread with a URB_WRITE, the kernel must 676fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * ensure that all writes are complete by sending the final 677fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * write as a committed write." 678fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez */ 679fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez bool final_write = binding == (unsigned) num_bindings - 1 && 6802614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga inst->sol_vertex == num_verts - 1; 681fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 682fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* Compute offset of this varying for the current vertex 6832614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * in vertex_output 684fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez */ 685fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->current_annotation = output_reg_annotation[varying]; 6862614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga src_reg data(this->vertex_output); 6872614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga data.reladdr = ralloc(mem_ctx, src_reg); 6882614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga int offset = get_vertex_output_offset_for_varying(vertex, varying); 689f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner emit(MOV(dst_reg(this->vertex_output_offset), brw_imm_d(offset))); 6902614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga memcpy(data.reladdr, &this->vertex_output_offset, sizeof(src_reg)); 691f182e5eafc31ebc7c140e9a369d5f747948733aeKenneth Graunke data.type = output_reg[varying][0].type; 692fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 6932614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* PSIZ, LAYER and VIEWPORT are packed in different channels of the 6942614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * same slot, so make sure we write the appropriate channel 6952614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga */ 6962614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga if (varying == VARYING_SLOT_PSIZ) 6972614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga data.swizzle = BRW_SWIZZLE_WWWW; 6982614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga else if (varying == VARYING_SLOT_LAYER) 6992614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga data.swizzle = BRW_SWIZZLE_YYYY; 7002614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga else if (varying == VARYING_SLOT_VIEWPORT) 7012614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga data.swizzle = BRW_SWIZZLE_ZZZZ; 7022614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga else 703fac9b21e037f9ce456039fbf35cd5fa573dee229Jason Ekstrand data.swizzle = gs_prog_data->transform_feedback_swizzles[binding]; 7042614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga 7052614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* Write data */ 7062614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga inst = emit(GS_OPCODE_SVB_WRITE, mrf_reg, data, sol_temp); 707fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez inst->sol_binding = binding; 708fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez inst->sol_final_write = final_write; 709fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 710fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez if (final_write) { 711fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez /* This is the last vertex of the primitive, then increment 712fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez * SO num primitive counter and destination indices. 713fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez */ 714fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(ADD(dst_reg(this->destination_indices), 715fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->destination_indices, 716f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner brw_imm_ud(num_verts))); 717fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(ADD(dst_reg(this->sol_prim_written), 718f9a9ba5eac2f1934bd7fecc92cd309f22411164bMatt Turner this->sol_prim_written, brw_imm_ud(1u))); 719fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 720fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 721fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 722fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez this->current_annotation = NULL; 723fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez } 724fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez emit(BRW_OPCODE_ENDIF); 725fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez} 726fda4470944762dddaff249ea36d6e21aa5f8e2caSamuel Iglesias Gonsálvez 7272614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quirogaint 7282614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quirogagen6_gs_visitor::get_vertex_output_offset_for_varying(int vertex, int varying) 7292614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga{ 7302614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* Find the output slot assigned to this varying. 7312614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * 7322614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * VARYING_SLOT_LAYER and VARYING_SLOT_VIEWPORT are packed in the same slot 7332614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * as VARYING_SLOT_PSIZ. 7342614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga */ 7352614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga if (varying == VARYING_SLOT_LAYER || varying == VARYING_SLOT_VIEWPORT) 7362614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga varying = VARYING_SLOT_PSIZ; 7372614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga int slot = prog_data->vue_map.varying_to_slot[varying]; 7382614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga 7392614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga if (slot < 0) { 7402614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga /* This varying does not exist in the VUE so we are not writing to it 7412614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * and its value is undefined. We still want to return a valid offset 7422614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * into vertex_output though, to prevent any out-of-bound accesses into 7432614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * the vertex_output array. Since the value for this varying is undefined 7442614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * we don't really care for the value we assign to it, so any offset 7452614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga * within the limits of vertex_output will do. 7462614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga */ 7472614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga slot = 0; 7482614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga } 7492614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga 7502614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga return vertex * (prog_data->vue_map.num_slots + 1) + slot; 7512614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga} 7522614cde9981ee3609b8e22d84596603a1bd42212Iago Toral Quiroga 7538411bf2c69136efcae594529f16e70ea0a22e271Iago Toral Quiroga} /* namespace brw */ 754