1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include "tgsi/tgsi_from_mesa.h"
25
26#include "pipe/p_compiler.h"
27
28#include "util/compiler.h"
29
30/**
31 * Determine the semantic index that is used when the given varying is mapped
32 * to TGSI_SEMANTIC_GENERIC.
33 */
34unsigned
35tgsi_get_generic_gl_varying_index(gl_varying_slot attr,
36                                  bool needs_texcoord_semantic)
37{
38   if (attr >= VARYING_SLOT_VAR0) {
39      if (needs_texcoord_semantic)
40         return attr - VARYING_SLOT_VAR0;
41      else
42         return 9 + (attr - VARYING_SLOT_VAR0);
43   }
44   if (attr == VARYING_SLOT_PNTC) {
45      assert(!needs_texcoord_semantic);
46      return 8;
47   }
48   if (attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7) {
49      assert(!needs_texcoord_semantic);
50      return attr - VARYING_SLOT_TEX0;
51   }
52
53   assert(0);
54   return 0;
55}
56
57/**
58 * Determine the semantic name and index used for the given varying.
59 */
60void
61tgsi_get_gl_varying_semantic(gl_varying_slot attr,
62                             bool needs_texcoord_semantic,
63                             unsigned *semantic_name,
64                             unsigned *semantic_index)
65{
66   switch (attr) {
67   case VARYING_SLOT_PRIMITIVE_ID:
68      *semantic_name = TGSI_SEMANTIC_PRIMID;
69      *semantic_index = 0;
70      break;
71   case VARYING_SLOT_POS:
72      *semantic_name = TGSI_SEMANTIC_POSITION;
73      *semantic_index = 0;
74      break;
75   case VARYING_SLOT_COL0:
76      *semantic_name = TGSI_SEMANTIC_COLOR;
77      *semantic_index = 0;
78      break;
79   case VARYING_SLOT_COL1:
80      *semantic_name = TGSI_SEMANTIC_COLOR;
81      *semantic_index = 1;
82      break;
83   case VARYING_SLOT_BFC0:
84      *semantic_name = TGSI_SEMANTIC_BCOLOR;
85      *semantic_index = 0;
86      break;
87   case VARYING_SLOT_BFC1:
88      *semantic_name = TGSI_SEMANTIC_BCOLOR;
89      *semantic_index = 1;
90      break;
91   case VARYING_SLOT_FOGC:
92      *semantic_name = TGSI_SEMANTIC_FOG;
93      *semantic_index = 0;
94      break;
95   case VARYING_SLOT_PSIZ:
96      *semantic_name = TGSI_SEMANTIC_PSIZE;
97      *semantic_index = 0;
98      break;
99   case VARYING_SLOT_CLIP_DIST0:
100      *semantic_name = TGSI_SEMANTIC_CLIPDIST;
101      *semantic_index = 0;
102      break;
103   case VARYING_SLOT_CLIP_DIST1:
104      *semantic_name = TGSI_SEMANTIC_CLIPDIST;
105      *semantic_index = 1;
106      break;
107   case VARYING_SLOT_CULL_DIST0:
108   case VARYING_SLOT_CULL_DIST1:
109      /* these should have been lowered by GLSL */
110      assert(0);
111      break;
112   case VARYING_SLOT_EDGE:
113      *semantic_name = TGSI_SEMANTIC_EDGEFLAG;
114      *semantic_index = 0;
115      break;
116   case VARYING_SLOT_CLIP_VERTEX:
117      *semantic_name = TGSI_SEMANTIC_CLIPVERTEX;
118      *semantic_index = 0;
119      break;
120   case VARYING_SLOT_LAYER:
121      *semantic_name = TGSI_SEMANTIC_LAYER;
122      *semantic_index = 0;
123      break;
124   case VARYING_SLOT_VIEWPORT:
125      *semantic_name = TGSI_SEMANTIC_VIEWPORT_INDEX;
126      *semantic_index = 0;
127      break;
128   case VARYING_SLOT_FACE:
129      *semantic_name = TGSI_SEMANTIC_FACE;
130      *semantic_index = 0;
131      break;
132   case VARYING_SLOT_PNTC:
133      *semantic_name = TGSI_SEMANTIC_PCOORD;
134      *semantic_index = 0;
135      break;
136   case VARYING_SLOT_TESS_LEVEL_OUTER:
137      *semantic_name = TGSI_SEMANTIC_TESSOUTER;
138      *semantic_index = 0;
139      break;
140   case VARYING_SLOT_TESS_LEVEL_INNER:
141      *semantic_name = TGSI_SEMANTIC_TESSINNER;
142      *semantic_index = 0;
143      break;
144   case VARYING_SLOT_VIEWPORT_MASK:
145      *semantic_name = TGSI_SEMANTIC_VIEWPORT_MASK;
146      *semantic_index = 0;
147      break;
148
149   case VARYING_SLOT_TEX0:
150   case VARYING_SLOT_TEX1:
151   case VARYING_SLOT_TEX2:
152   case VARYING_SLOT_TEX3:
153   case VARYING_SLOT_TEX4:
154   case VARYING_SLOT_TEX5:
155   case VARYING_SLOT_TEX6:
156   case VARYING_SLOT_TEX7:
157      if (needs_texcoord_semantic) {
158         *semantic_name = TGSI_SEMANTIC_TEXCOORD;
159         *semantic_index = attr - VARYING_SLOT_TEX0;
160         break;
161      }
162      FALLTHROUGH;
163   case VARYING_SLOT_VAR0:
164   default:
165      assert(attr >= VARYING_SLOT_VAR0 ||
166             (attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7));
167      if (attr >= VARYING_SLOT_PATCH0) {
168         *semantic_name = TGSI_SEMANTIC_PATCH;
169         *semantic_index = attr - VARYING_SLOT_PATCH0;
170      } else {
171         *semantic_name = TGSI_SEMANTIC_GENERIC;
172         *semantic_index =
173            tgsi_get_generic_gl_varying_index(attr, needs_texcoord_semantic);
174      }
175      break;
176   }
177}
178
179/**
180 * Determine the semantic name and index used for the given fragment shader
181 * result.
182 */
183void
184tgsi_get_gl_frag_result_semantic(gl_frag_result frag_result,
185                                 unsigned *semantic_name,
186                                 unsigned *semantic_index)
187{
188   if (frag_result >= FRAG_RESULT_DATA0) {
189      *semantic_name = TGSI_SEMANTIC_COLOR;
190      *semantic_index = frag_result - FRAG_RESULT_DATA0;
191      return;
192   }
193
194   *semantic_index = 0;
195
196   switch (frag_result) {
197   case FRAG_RESULT_DEPTH:
198      *semantic_name = TGSI_SEMANTIC_POSITION;
199      break;
200   case FRAG_RESULT_STENCIL:
201      *semantic_name = TGSI_SEMANTIC_STENCIL;
202      break;
203   case FRAG_RESULT_COLOR:
204      *semantic_name = TGSI_SEMANTIC_COLOR;
205      break;
206   case FRAG_RESULT_SAMPLE_MASK:
207      *semantic_name = TGSI_SEMANTIC_SAMPLEMASK;
208      break;
209   default:
210      assert(false);
211   }
212}
213
214/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
215enum tgsi_semantic
216tgsi_get_sysval_semantic(unsigned sysval)
217{
218   switch (sysval) {
219   /* Vertex shader */
220   case SYSTEM_VALUE_VERTEX_ID:
221      return TGSI_SEMANTIC_VERTEXID;
222   case SYSTEM_VALUE_INSTANCE_ID:
223      return TGSI_SEMANTIC_INSTANCEID;
224   case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
225      return TGSI_SEMANTIC_VERTEXID_NOBASE;
226   case SYSTEM_VALUE_BASE_VERTEX:
227      return TGSI_SEMANTIC_BASEVERTEX;
228   case SYSTEM_VALUE_BASE_INSTANCE:
229      return TGSI_SEMANTIC_BASEINSTANCE;
230   case SYSTEM_VALUE_DRAW_ID:
231      return TGSI_SEMANTIC_DRAWID;
232
233   /* Geometry shader */
234   case SYSTEM_VALUE_INVOCATION_ID:
235      return TGSI_SEMANTIC_INVOCATIONID;
236
237   /* Fragment shader */
238   case SYSTEM_VALUE_FRAG_COORD:
239      return TGSI_SEMANTIC_POSITION;
240   case SYSTEM_VALUE_POINT_COORD:
241      return TGSI_SEMANTIC_PCOORD;
242   case SYSTEM_VALUE_FRONT_FACE:
243      return TGSI_SEMANTIC_FACE;
244   case SYSTEM_VALUE_SAMPLE_ID:
245      return TGSI_SEMANTIC_SAMPLEID;
246   case SYSTEM_VALUE_SAMPLE_POS:
247      return TGSI_SEMANTIC_SAMPLEPOS;
248   case SYSTEM_VALUE_SAMPLE_MASK_IN:
249      return TGSI_SEMANTIC_SAMPLEMASK;
250   case SYSTEM_VALUE_HELPER_INVOCATION:
251      return TGSI_SEMANTIC_HELPER_INVOCATION;
252
253   /* Tessellation shader */
254   case SYSTEM_VALUE_TESS_COORD:
255      return TGSI_SEMANTIC_TESSCOORD;
256   case SYSTEM_VALUE_VERTICES_IN:
257      return TGSI_SEMANTIC_VERTICESIN;
258   case SYSTEM_VALUE_PRIMITIVE_ID:
259      return TGSI_SEMANTIC_PRIMID;
260   case SYSTEM_VALUE_TESS_LEVEL_OUTER:
261      return TGSI_SEMANTIC_TESSOUTER;
262   case SYSTEM_VALUE_TESS_LEVEL_INNER:
263      return TGSI_SEMANTIC_TESSINNER;
264
265   /* Compute shader */
266   case SYSTEM_VALUE_LOCAL_INVOCATION_ID:
267      return TGSI_SEMANTIC_THREAD_ID;
268   case SYSTEM_VALUE_WORKGROUP_ID:
269      return TGSI_SEMANTIC_BLOCK_ID;
270   case SYSTEM_VALUE_NUM_WORKGROUPS:
271      return TGSI_SEMANTIC_GRID_SIZE;
272   case SYSTEM_VALUE_WORKGROUP_SIZE:
273      return TGSI_SEMANTIC_BLOCK_SIZE;
274
275   /* ARB_shader_ballot */
276   case SYSTEM_VALUE_SUBGROUP_SIZE:
277      return TGSI_SEMANTIC_SUBGROUP_SIZE;
278   case SYSTEM_VALUE_SUBGROUP_INVOCATION:
279      return TGSI_SEMANTIC_SUBGROUP_INVOCATION;
280   case SYSTEM_VALUE_SUBGROUP_EQ_MASK:
281      return TGSI_SEMANTIC_SUBGROUP_EQ_MASK;
282   case SYSTEM_VALUE_SUBGROUP_GE_MASK:
283      return TGSI_SEMANTIC_SUBGROUP_GE_MASK;
284   case SYSTEM_VALUE_SUBGROUP_GT_MASK:
285      return TGSI_SEMANTIC_SUBGROUP_GT_MASK;
286   case SYSTEM_VALUE_SUBGROUP_LE_MASK:
287      return TGSI_SEMANTIC_SUBGROUP_LE_MASK;
288   case SYSTEM_VALUE_SUBGROUP_LT_MASK:
289      return TGSI_SEMANTIC_SUBGROUP_LT_MASK;
290
291   default:
292      unreachable("Unexpected system value to TGSI");
293   }
294}
295
296enum tgsi_interpolate_mode
297tgsi_get_interp_mode(enum glsl_interp_mode mode, bool color)
298{
299   switch (mode) {
300   case INTERP_MODE_NONE:
301      return color ? TGSI_INTERPOLATE_COLOR : TGSI_INTERPOLATE_PERSPECTIVE;
302   case INTERP_MODE_FLAT:
303      return TGSI_INTERPOLATE_CONSTANT;
304   case INTERP_MODE_NOPERSPECTIVE:
305      return TGSI_INTERPOLATE_LINEAR;
306   case INTERP_MODE_SMOOTH:
307      return TGSI_INTERPOLATE_PERSPECTIVE;
308   default:
309      unreachable("unknown interpolation mode");
310   }
311}
312