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