1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2013 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #ifndef TOY_HELPERS_H
29 #define TOY_HELPERS_H
30
31 #include "toy_compiler.h"
32
33 /**
34 * Transpose a dst operand.
35 *
36 * Instead of processing a single vertex with each of its attributes in one
37 * register, such as
38 *
39 * r0 = [x0, y0, z0, w0]
40 *
41 * we want to process four vertices at a time
42 *
43 * r0 = [x0, y0, z0, w0]
44 * r1 = [x1, y1, z1, w1]
45 * r2 = [x2, y2, z2, w2]
46 * r3 = [x3, y3, z3, w3]
47 *
48 * but with the attribute data "transposed"
49 *
50 * r0 = [x0, x1, x2, x3]
51 * r1 = [y0, y1, y2, y3]
52 * r2 = [z0, z1, z2, z3]
53 * r3 = [w0, w1, w2, w3]
54 *
55 * This is also known as the SoA form.
56 */
57 static inline void
tdst_transpose(struct toy_dst dst,struct toy_dst * trans)58 tdst_transpose(struct toy_dst dst, struct toy_dst *trans)
59 {
60 int i;
61
62 switch (dst.file) {
63 case TOY_FILE_VRF:
64 assert(!dst.indirect);
65 for (i = 0; i < 4; i++) {
66 if (dst.writemask & (1 << i)) {
67 trans[i] = tdst_offset(dst, i, 0);
68 trans[i].writemask = TOY_WRITEMASK_XYZW;
69 }
70 else {
71 trans[i] = tdst_null();
72 }
73 }
74 break;
75 case TOY_FILE_ARF:
76 assert(tdst_is_null(dst));
77 for (i = 0; i < 4; i++)
78 trans[i] = dst;
79 break;
80 case TOY_FILE_GRF:
81 case TOY_FILE_MRF:
82 case TOY_FILE_IMM:
83 default:
84 assert(!"unexpected file in dst transposition");
85 for (i = 0; i < 4; i++)
86 trans[i] = tdst_null();
87 break;
88 }
89 }
90
91 /**
92 * Transpose a src operand.
93 */
94 static inline void
tsrc_transpose(struct toy_src src,struct toy_src * trans)95 tsrc_transpose(struct toy_src src, struct toy_src *trans)
96 {
97 const enum toy_swizzle swizzle[4] = {
98 src.swizzle_x, src.swizzle_y,
99 src.swizzle_z, src.swizzle_w,
100 };
101 int i;
102
103 switch (src.file) {
104 case TOY_FILE_VRF:
105 assert(!src.indirect);
106 for (i = 0; i < 4; i++) {
107 trans[i] = tsrc_offset(src, swizzle[i], 0);
108 trans[i].swizzle_x = TOY_SWIZZLE_X;
109 trans[i].swizzle_y = TOY_SWIZZLE_Y;
110 trans[i].swizzle_z = TOY_SWIZZLE_Z;
111 trans[i].swizzle_w = TOY_SWIZZLE_W;
112 }
113 break;
114 case TOY_FILE_ARF:
115 assert(tsrc_is_null(src));
116 /* fall through */
117 case TOY_FILE_IMM:
118 for (i = 0; i < 4; i++)
119 trans[i] = src;
120 break;
121 case TOY_FILE_GRF:
122 case TOY_FILE_MRF:
123 default:
124 assert(!"unexpected file in src transposition");
125 for (i = 0; i < 4; i++)
126 trans[i] = tsrc_null();
127 break;
128 }
129 }
130
131 static inline struct toy_src
tsrc_imm_mdesc(const struct toy_compiler * tc,bool eot,unsigned message_length,unsigned response_length,bool header_present,uint32_t function_control)132 tsrc_imm_mdesc(const struct toy_compiler *tc,
133 bool eot,
134 unsigned message_length,
135 unsigned response_length,
136 bool header_present,
137 uint32_t function_control)
138 {
139 uint32_t desc;
140
141 assert(message_length >= 1 && message_length <= 15);
142 assert(response_length >= 0 && response_length <= 16);
143 assert(function_control < 1 << 19);
144
145 desc = eot << 31 |
146 message_length << 25 |
147 response_length << 20 |
148 header_present << 19 |
149 function_control;
150
151 return tsrc_imm_ud(desc);
152 }
153
154 static inline struct toy_src
tsrc_imm_mdesc_sampler(const struct toy_compiler * tc,unsigned message_length,unsigned response_length,bool header_present,unsigned simd_mode,unsigned message_type,unsigned sampler_index,unsigned binding_table_index)155 tsrc_imm_mdesc_sampler(const struct toy_compiler *tc,
156 unsigned message_length,
157 unsigned response_length,
158 bool header_present,
159 unsigned simd_mode,
160 unsigned message_type,
161 unsigned sampler_index,
162 unsigned binding_table_index)
163 {
164 const bool eot = false;
165 uint32_t ctrl;
166
167 assert(simd_mode < 4);
168 assert(sampler_index < 16);
169 assert(binding_table_index < 256);
170
171 if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
172 ctrl = simd_mode << 17 |
173 message_type << 12 |
174 sampler_index << 8 |
175 binding_table_index;
176 }
177 else {
178 ctrl = simd_mode << 16 |
179 message_type << 12 |
180 sampler_index << 8 |
181 binding_table_index;
182 }
183
184 return tsrc_imm_mdesc(tc, eot, message_length,
185 response_length, header_present, ctrl);
186 }
187
188 static inline struct toy_src
tsrc_imm_mdesc_data_port(const struct toy_compiler * tc,bool eot,unsigned message_length,unsigned response_length,bool header_present,bool send_write_commit_message,unsigned message_type,unsigned message_specific_control,unsigned binding_table_index)189 tsrc_imm_mdesc_data_port(const struct toy_compiler *tc,
190 bool eot,
191 unsigned message_length,
192 unsigned response_length,
193 bool header_present,
194 bool send_write_commit_message,
195 unsigned message_type,
196 unsigned message_specific_control,
197 unsigned binding_table_index)
198 {
199 uint32_t ctrl;
200
201 if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
202 assert(!send_write_commit_message);
203 assert((message_specific_control & 0x3f00) == message_specific_control);
204
205 ctrl = message_type << 14 |
206 (message_specific_control & 0x3f00) |
207 binding_table_index;
208 }
209 else {
210 assert(!send_write_commit_message ||
211 message_type == GEN6_MSG_DP_SVB_WRITE);
212 assert((message_specific_control & 0x1f00) == message_specific_control);
213
214 ctrl = send_write_commit_message << 17 |
215 message_type << 13 |
216 (message_specific_control & 0x1f00) |
217 binding_table_index;
218 }
219
220 return tsrc_imm_mdesc(tc, eot, message_length,
221 response_length, header_present, ctrl);
222 }
223
224 static inline struct toy_src
tsrc_imm_mdesc_data_port_scratch(const struct toy_compiler * tc,unsigned message_length,unsigned response_length,bool write_type,bool dword_mode,bool invalidate_after_read,int num_registers,int hword_offset)225 tsrc_imm_mdesc_data_port_scratch(const struct toy_compiler *tc,
226 unsigned message_length,
227 unsigned response_length,
228 bool write_type,
229 bool dword_mode,
230 bool invalidate_after_read,
231 int num_registers,
232 int hword_offset)
233 {
234 const bool eot = false;
235 const bool header_present = true;
236 uint32_t ctrl;
237
238 assert(ilo_dev_gen(tc->dev) >= ILO_GEN(7));
239 assert(num_registers == 1 || num_registers == 2 || num_registers == 4);
240
241 ctrl = 1 << 18 |
242 write_type << 17 |
243 dword_mode << 16 |
244 invalidate_after_read << 15 |
245 (num_registers - 1) << 12 |
246 hword_offset;
247
248 return tsrc_imm_mdesc(tc, eot, message_length,
249 response_length, header_present, ctrl);
250 }
251
252 static inline struct toy_src
tsrc_imm_mdesc_urb(const struct toy_compiler * tc,bool eot,unsigned message_length,unsigned response_length,bool complete,bool used,bool allocate,unsigned swizzle_control,unsigned global_offset,unsigned urb_opcode)253 tsrc_imm_mdesc_urb(const struct toy_compiler *tc,
254 bool eot,
255 unsigned message_length,
256 unsigned response_length,
257 bool complete,
258 bool used,
259 bool allocate,
260 unsigned swizzle_control,
261 unsigned global_offset,
262 unsigned urb_opcode)
263 {
264 const bool header_present = true;
265 uint32_t ctrl;
266
267 if (ilo_dev_gen(tc->dev) >= ILO_GEN(8)) {
268 const bool per_slot_offset = false;
269
270 ctrl = per_slot_offset << 17 |
271 swizzle_control << 15 |
272 global_offset << 4 |
273 urb_opcode;
274 } else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
275 const bool per_slot_offset = false;
276
277 ctrl = per_slot_offset << 16 |
278 complete << 15 |
279 swizzle_control << 14 |
280 global_offset << 3 |
281 urb_opcode;
282 } else {
283 ctrl = complete << 15 |
284 used << 14 |
285 allocate << 13 |
286 swizzle_control << 10 |
287 global_offset << 4 |
288 urb_opcode;
289 }
290
291 return tsrc_imm_mdesc(tc, eot, message_length,
292 response_length, header_present, ctrl);
293 }
294
295 #endif /* TOY_HELPERS_H */
296