blob: d7c468c17fce220698d3a727a46c3b1b9181f924 [file] [log] [blame]
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06003 *
4 * Copyright (C) 2014 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.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Courtney Goeltzenleuchter <courtney@lunarg.com>
26 * Chia-I Wu <olv@lunarg.com>
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060027 */
28
Chia-I Wu8370b402014-08-29 12:28:37 +080029#include "genhw/genhw.h"
Chia-I Wu3f239832014-12-11 22:57:18 +080030#include "compiler/pipeline/pipeline_compiler_interface.h"
Chia-I Wu8370b402014-08-29 12:28:37 +080031#include "cmd.h"
Chia-I Wu1d125092014-10-08 08:49:38 +080032#include "format.h"
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060033#include "shader.h"
Chia-I Wu3f239832014-12-11 22:57:18 +080034#include "pipeline.h"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060035
Tony Barbour8205d902015-04-16 15:59:00 -060036static int translate_blend_func(VkBlendOp func)
Tony Barbourfa6cac72015-01-16 14:27:35 -070037{
38 switch (func) {
Tony Barbour8205d902015-04-16 15:59:00 -060039 case VK_BLEND_OP_ADD: return GEN6_BLENDFUNCTION_ADD;
40 case VK_BLEND_OP_SUBTRACT: return GEN6_BLENDFUNCTION_SUBTRACT;
41 case VK_BLEND_OP_REVERSE_SUBTRACT: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
42 case VK_BLEND_OP_MIN: return GEN6_BLENDFUNCTION_MIN;
43 case VK_BLEND_OP_MAX: return GEN6_BLENDFUNCTION_MAX;
Tony Barbourfa6cac72015-01-16 14:27:35 -070044 default:
45 assert(!"unknown blend func");
46 return GEN6_BLENDFUNCTION_ADD;
47 };
48}
49
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060050static int translate_blend(VkBlend blend)
Tony Barbourfa6cac72015-01-16 14:27:35 -070051{
52 switch (blend) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060053 case VK_BLEND_ZERO: return GEN6_BLENDFACTOR_ZERO;
54 case VK_BLEND_ONE: return GEN6_BLENDFACTOR_ONE;
55 case VK_BLEND_SRC_COLOR: return GEN6_BLENDFACTOR_SRC_COLOR;
56 case VK_BLEND_ONE_MINUS_SRC_COLOR: return GEN6_BLENDFACTOR_INV_SRC_COLOR;
57 case VK_BLEND_DEST_COLOR: return GEN6_BLENDFACTOR_DST_COLOR;
58 case VK_BLEND_ONE_MINUS_DEST_COLOR: return GEN6_BLENDFACTOR_INV_DST_COLOR;
59 case VK_BLEND_SRC_ALPHA: return GEN6_BLENDFACTOR_SRC_ALPHA;
60 case VK_BLEND_ONE_MINUS_SRC_ALPHA: return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
61 case VK_BLEND_DEST_ALPHA: return GEN6_BLENDFACTOR_DST_ALPHA;
62 case VK_BLEND_ONE_MINUS_DEST_ALPHA: return GEN6_BLENDFACTOR_INV_DST_ALPHA;
63 case VK_BLEND_CONSTANT_COLOR: return GEN6_BLENDFACTOR_CONST_COLOR;
64 case VK_BLEND_ONE_MINUS_CONSTANT_COLOR: return GEN6_BLENDFACTOR_INV_CONST_COLOR;
65 case VK_BLEND_CONSTANT_ALPHA: return GEN6_BLENDFACTOR_CONST_ALPHA;
66 case VK_BLEND_ONE_MINUS_CONSTANT_ALPHA: return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
67 case VK_BLEND_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
68 case VK_BLEND_SRC1_COLOR: return GEN6_BLENDFACTOR_SRC1_COLOR;
69 case VK_BLEND_ONE_MINUS_SRC1_COLOR: return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
70 case VK_BLEND_SRC1_ALPHA: return GEN6_BLENDFACTOR_SRC1_ALPHA;
71 case VK_BLEND_ONE_MINUS_SRC1_ALPHA: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
Tony Barbourfa6cac72015-01-16 14:27:35 -070072 default:
73 assert(!"unknown blend factor");
74 return GEN6_BLENDFACTOR_ONE;
75 };
76}
77
Tony Barbour8205d902015-04-16 15:59:00 -060078static int translate_compare_func(VkCompareOp func)
Tony Barbourfa6cac72015-01-16 14:27:35 -070079{
80 switch (func) {
Tony Barbour8205d902015-04-16 15:59:00 -060081 case VK_COMPARE_OP_NEVER: return GEN6_COMPAREFUNCTION_NEVER;
82 case VK_COMPARE_OP_LESS: return GEN6_COMPAREFUNCTION_LESS;
83 case VK_COMPARE_OP_EQUAL: return GEN6_COMPAREFUNCTION_EQUAL;
84 case VK_COMPARE_OP_LESS_EQUAL: return GEN6_COMPAREFUNCTION_LEQUAL;
85 case VK_COMPARE_OP_GREATER: return GEN6_COMPAREFUNCTION_GREATER;
86 case VK_COMPARE_OP_NOT_EQUAL: return GEN6_COMPAREFUNCTION_NOTEQUAL;
87 case VK_COMPARE_OP_GREATER_EQUAL: return GEN6_COMPAREFUNCTION_GEQUAL;
88 case VK_COMPARE_OP_ALWAYS: return GEN6_COMPAREFUNCTION_ALWAYS;
Tony Barbourfa6cac72015-01-16 14:27:35 -070089 default:
90 assert(!"unknown compare_func");
91 return GEN6_COMPAREFUNCTION_NEVER;
92 }
93}
94
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060095static int translate_stencil_op(VkStencilOp op)
Tony Barbourfa6cac72015-01-16 14:27:35 -070096{
97 switch (op) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060098 case VK_STENCIL_OP_KEEP: return GEN6_STENCILOP_KEEP;
99 case VK_STENCIL_OP_ZERO: return GEN6_STENCILOP_ZERO;
100 case VK_STENCIL_OP_REPLACE: return GEN6_STENCILOP_REPLACE;
101 case VK_STENCIL_OP_INC_CLAMP: return GEN6_STENCILOP_INCRSAT;
102 case VK_STENCIL_OP_DEC_CLAMP: return GEN6_STENCILOP_DECRSAT;
103 case VK_STENCIL_OP_INVERT: return GEN6_STENCILOP_INVERT;
104 case VK_STENCIL_OP_INC_WRAP: return GEN6_STENCILOP_INCR;
105 case VK_STENCIL_OP_DEC_WRAP: return GEN6_STENCILOP_DECR;
Tony Barbourfa6cac72015-01-16 14:27:35 -0700106 default:
107 assert(!"unknown stencil op");
108 return GEN6_STENCILOP_KEEP;
109 }
110}
111
Chia-I Wu3f239832014-12-11 22:57:18 +0800112struct intel_pipeline_create_info {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600113 VkGraphicsPipelineCreateInfo graphics;
114 VkPipelineVertexInputStateCreateInfo vi;
115 VkPipelineIaStateCreateInfo ia;
116 VkPipelineDsStateCreateInfo db;
117 VkPipelineCbStateCreateInfo cb;
118 VkPipelineRsStateCreateInfo rs;
119 VkPipelineTessStateCreateInfo tess;
120 VkPipelineMsStateCreateInfo ms;
121 VkPipelineVpStateCreateInfo vp;
Chia-I Wu3f239832014-12-11 22:57:18 +0800122
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600123 VkComputePipelineCreateInfo compute;
124
125 VkPipelineShaderStageCreateInfo vs;
126 VkPipelineShaderStageCreateInfo tcs;
127 VkPipelineShaderStageCreateInfo tes;
128 VkPipelineShaderStageCreateInfo gs;
129 VkPipelineShaderStageCreateInfo fs;
Chia-I Wu3f239832014-12-11 22:57:18 +0800130};
Chia-I Wu38d1ddf2015-03-02 10:51:39 -0700131
132/* in S1.3 */
133struct intel_pipeline_sample_position {
134 int8_t x, y;
135};
136
137static uint8_t pack_sample_position(const struct intel_dev *dev,
138 const struct intel_pipeline_sample_position *pos)
139{
140 return (pos->x + 8) << 4 | (pos->y + 8);
141}
142
143void intel_pipeline_init_default_sample_patterns(const struct intel_dev *dev,
144 uint8_t *pat_1x, uint8_t *pat_2x,
145 uint8_t *pat_4x, uint8_t *pat_8x,
146 uint8_t *pat_16x)
147{
148 static const struct intel_pipeline_sample_position default_1x[1] = {
149 { 0, 0 },
150 };
151 static const struct intel_pipeline_sample_position default_2x[2] = {
152 { -4, -4 },
153 { 4, 4 },
154 };
155 static const struct intel_pipeline_sample_position default_4x[4] = {
156 { -2, -6 },
157 { 6, -2 },
158 { -6, 2 },
159 { 2, 6 },
160 };
161 static const struct intel_pipeline_sample_position default_8x[8] = {
162 { -1, 1 },
163 { 1, 5 },
164 { 3, -5 },
165 { 5, 3 },
166 { -7, -1 },
167 { -3, -7 },
168 { 7, -3 },
169 { -5, 7 },
170 };
171 static const struct intel_pipeline_sample_position default_16x[16] = {
172 { 0, 2 },
173 { 3, 0 },
174 { -3, -2 },
175 { -2, -4 },
176 { 4, 3 },
177 { 5, 1 },
178 { 6, -1 },
179 { 2, -6 },
180 { -4, 5 },
181 { -5, -5 },
182 { -1, -7 },
183 { 7, -3 },
184 { -7, 4 },
185 { 1, -8 },
186 { -6, 6 },
187 { -8, 7 },
188 };
189 int i;
190
191 pat_1x[0] = pack_sample_position(dev, default_1x);
192 for (i = 0; i < 2; i++)
193 pat_2x[i] = pack_sample_position(dev, &default_2x[i]);
194 for (i = 0; i < 4; i++)
195 pat_4x[i] = pack_sample_position(dev, &default_4x[i]);
196 for (i = 0; i < 8; i++)
197 pat_8x[i] = pack_sample_position(dev, &default_8x[i]);
198 for (i = 0; i < 16; i++)
199 pat_16x[i] = pack_sample_position(dev, &default_16x[i]);
200}
201
Chia-I Wu3f239832014-12-11 22:57:18 +0800202struct intel_pipeline_shader *intel_pipeline_shader_create_meta(struct intel_dev *dev,
203 enum intel_dev_meta_shader id)
204{
205 struct intel_pipeline_shader *sh;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600206 VkResult ret;
Chia-I Wu3f239832014-12-11 22:57:18 +0800207
Tony Barbour8205d902015-04-16 15:59:00 -0600208 sh = intel_alloc(dev, sizeof(*sh), 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu3f239832014-12-11 22:57:18 +0800209 if (!sh)
210 return NULL;
211 memset(sh, 0, sizeof(*sh));
212
213 ret = intel_pipeline_shader_compile_meta(sh, dev->gpu, id);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600214 if (ret != VK_SUCCESS) {
Chia-I Wuf9c81ef2015-02-22 13:49:15 +0800215 intel_free(dev, sh);
Chia-I Wu3f239832014-12-11 22:57:18 +0800216 return NULL;
217 }
218
219 switch (id) {
220 case INTEL_DEV_META_VS_FILL_MEM:
221 case INTEL_DEV_META_VS_COPY_MEM:
222 case INTEL_DEV_META_VS_COPY_MEM_UNALIGNED:
223 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600224 VK_SHADER_STAGE_VERTEX);
Chia-I Wu3f239832014-12-11 22:57:18 +0800225 break;
226 default:
227 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600228 VK_SHADER_STAGE_FRAGMENT);
Chia-I Wu3f239832014-12-11 22:57:18 +0800229 break;
230 }
231
232 return sh;
233}
234
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800235void intel_pipeline_shader_destroy(struct intel_dev *dev,
236 struct intel_pipeline_shader *sh)
Chia-I Wu3f239832014-12-11 22:57:18 +0800237{
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800238 intel_pipeline_shader_cleanup(sh, dev->gpu);
239 intel_free(dev, sh);
Chia-I Wu3f239832014-12-11 22:57:18 +0800240}
241
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600242static VkResult pipeline_build_shader(struct intel_pipeline *pipeline,
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600243 const VkPipelineShaderStageCreateInfo *sh_info,
Chia-I Wuf8385062015-01-04 16:27:24 +0800244 struct intel_pipeline_shader *sh)
Chia-I Wu3f239832014-12-11 22:57:18 +0800245{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600246 VkResult ret;
Chia-I Wu3f239832014-12-11 22:57:18 +0800247
Cody Northropbc12f872015-04-29 13:22:07 -0600248 const struct intel_ir* ir = intel_shader(sh_info->shader)->ir;
249
Chia-I Wuf8385062015-01-04 16:27:24 +0800250 ret = intel_pipeline_shader_compile(sh,
Cody Northropbc12f872015-04-29 13:22:07 -0600251 pipeline->dev->gpu, pipeline->pipeline_layout, sh_info, ir);
252
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600253 if (ret != VK_SUCCESS)
Chia-I Wu3f239832014-12-11 22:57:18 +0800254 return ret;
255
256 sh->max_threads =
257 intel_gpu_get_max_threads(pipeline->dev->gpu, sh_info->stage);
258
259 /* 1KB aligned */
260 sh->scratch_offset = u_align(pipeline->scratch_size, 1024);
261 pipeline->scratch_size = sh->scratch_offset +
262 sh->per_thread_scratch_size * sh->max_threads;
263
264 pipeline->active_shaders |= 1 << sh_info->stage;
265
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600266 return VK_SUCCESS;
Chia-I Wu3f239832014-12-11 22:57:18 +0800267}
268
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600269static VkResult pipeline_build_shaders(struct intel_pipeline *pipeline,
Chia-I Wu3f239832014-12-11 22:57:18 +0800270 const struct intel_pipeline_create_info *info)
271{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600272 VkResult ret = VK_SUCCESS;
Chia-I Wu3f239832014-12-11 22:57:18 +0800273
Chia-I Wudf601c42015-04-17 01:58:07 +0800274 if (ret == VK_SUCCESS && info->vs.shader)
275 ret = pipeline_build_shader(pipeline, &info->vs, &pipeline->vs);
276 if (ret == VK_SUCCESS && info->tcs.shader)
277 ret = pipeline_build_shader(pipeline, &info->tcs,&pipeline->tcs);
278 if (ret == VK_SUCCESS && info->tes.shader)
279 ret = pipeline_build_shader(pipeline, &info->tes,&pipeline->tes);
280 if (ret == VK_SUCCESS && info->gs.shader)
281 ret = pipeline_build_shader(pipeline, &info->gs, &pipeline->gs);
282 if (ret == VK_SUCCESS && info->fs.shader)
283 ret = pipeline_build_shader(pipeline, &info->fs, &pipeline->fs);
Chia-I Wu3f239832014-12-11 22:57:18 +0800284
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600285 if (ret == VK_SUCCESS && info->compute.cs.shader) {
Chia-I Wudf601c42015-04-17 01:58:07 +0800286 ret = pipeline_build_shader(pipeline,
Chia-I Wuf8385062015-01-04 16:27:24 +0800287 &info->compute.cs, &pipeline->cs);
288 }
Chia-I Wu3f239832014-12-11 22:57:18 +0800289
290 return ret;
291}
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600292static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
293{
294 uint32_t *ptr;
295
296 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
297 ptr = &pipeline->cmds[pipeline->cmd_len];
298 pipeline->cmd_len += cmd_len;
299 return ptr;
300}
301
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600302static VkResult pipeline_build_ia(struct intel_pipeline *pipeline,
Chia-I Wube0a3d92014-09-02 13:20:59 +0800303 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600304{
Chia-I Wube0a3d92014-09-02 13:20:59 +0800305 pipeline->topology = info->ia.topology;
306 pipeline->disable_vs_cache = info->ia.disableVertexReuse;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600307
Chia-I Wube0a3d92014-09-02 13:20:59 +0800308 switch (info->ia.topology) {
Tony Barbour8205d902015-04-16 15:59:00 -0600309 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600310 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600311 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600312 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600313 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600314 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600315 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600316 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600317 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600318 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600319 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600320 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600321 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600322 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600323 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600324 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
Courtney Goeltzenleuchter528781d2015-03-03 11:38:12 -0700325 pipeline->prim_type = GEN6_3DPRIM_TRIFAN;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600326 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600327 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600328 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600329 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600330 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600331 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600332 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600333 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600334 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600335 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600336 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600337 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600338 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600339 case VK_PRIMITIVE_TOPOLOGY_PATCH:
Chia-I Wube0a3d92014-09-02 13:20:59 +0800340 if (!info->tess.patchControlPoints ||
341 info->tess.patchControlPoints > 32)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600342 return VK_ERROR_BAD_PIPELINE_DATA;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800343 pipeline->prim_type = GEN7_3DPRIM_PATCHLIST_1 +
344 info->tess.patchControlPoints - 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600345 break;
346 default:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600347 return VK_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600348 }
349
Chia-I Wube0a3d92014-09-02 13:20:59 +0800350 if (info->ia.primitiveRestartEnable) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600351 pipeline->primitive_restart = true;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800352 pipeline->primitive_restart_index = info->ia.primitiveRestartIndex;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600353 } else {
354 pipeline->primitive_restart = false;
355 }
356
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600357 return VK_SUCCESS;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600358}
359
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600360static VkResult pipeline_build_rs_state(struct intel_pipeline *pipeline,
Chia-I Wu6abcb0e2015-03-24 14:38:14 +0800361 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600362{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600363 const VkPipelineRsStateCreateInfo *rs_state = &info->rs;
Chia-I Wu6abcb0e2015-03-24 14:38:14 +0800364 bool ccw;
365
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600366 pipeline->depthClipEnable = rs_state->depthClipEnable;
367 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
Tony Barbourfa6cac72015-01-16 14:27:35 -0700368
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600369 if (rs_state->provokingVertex == VK_PROVOKING_VERTEX_FIRST) {
Tony Barbourfa6cac72015-01-16 14:27:35 -0700370 pipeline->provoking_vertex_tri = 0;
371 pipeline->provoking_vertex_trifan = 1;
372 pipeline->provoking_vertex_line = 0;
373 } else {
374 pipeline->provoking_vertex_tri = 2;
375 pipeline->provoking_vertex_trifan = 2;
376 pipeline->provoking_vertex_line = 1;
377 }
378
379 switch (rs_state->fillMode) {
Tony Barbour8205d902015-04-16 15:59:00 -0600380 case VK_FILL_MODE_POINTS:
Tony Barbourfa6cac72015-01-16 14:27:35 -0700381 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_POINT |
382 GEN7_SF_DW1_BACKFACE_POINT;
383 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600384 case VK_FILL_MODE_WIREFRAME:
Tony Barbourfa6cac72015-01-16 14:27:35 -0700385 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_WIREFRAME |
386 GEN7_SF_DW1_BACKFACE_WIREFRAME;
387 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600388 case VK_FILL_MODE_SOLID:
Tony Barbourfa6cac72015-01-16 14:27:35 -0700389 default:
390 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_SOLID |
391 GEN7_SF_DW1_BACKFACE_SOLID;
392 break;
393 }
394
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600395 ccw = (rs_state->frontFace == VK_FRONT_FACE_CCW);
Chia-I Wu6abcb0e2015-03-24 14:38:14 +0800396 /* flip the winding order */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600397 if (info->vp.clipOrigin == VK_COORDINATE_ORIGIN_LOWER_LEFT)
Chia-I Wu6abcb0e2015-03-24 14:38:14 +0800398 ccw = !ccw;
399
400 if (ccw) {
Tony Barbourfa6cac72015-01-16 14:27:35 -0700401 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTWINDING_CCW;
402 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_FRONTWINDING_CCW;
403 }
404
405 switch (rs_state->cullMode) {
Tony Barbour8205d902015-04-16 15:59:00 -0600406 case VK_CULL_MODE_NONE:
Tony Barbourfa6cac72015-01-16 14:27:35 -0700407 default:
408 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_NONE;
409 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_NONE;
410 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600411 case VK_CULL_MODE_FRONT:
Tony Barbourfa6cac72015-01-16 14:27:35 -0700412 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_FRONT;
413 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_FRONT;
414 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600415 case VK_CULL_MODE_BACK:
Tony Barbourfa6cac72015-01-16 14:27:35 -0700416 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BACK;
417 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BACK;
418 break;
Tony Barbour8205d902015-04-16 15:59:00 -0600419 case VK_CULL_MODE_FRONT_AND_BACK:
Tony Barbourfa6cac72015-01-16 14:27:35 -0700420 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BOTH;
421 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BOTH;
422 break;
423 }
424
425 /* only GEN7+ needs cull mode in 3DSTATE_CLIP */
426 if (intel_gpu_gen(pipeline->dev->gpu) == INTEL_GEN(6))
427 pipeline->cmd_clip_cull = 0;
428
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600429 return VK_SUCCESS;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600430}
431
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600432static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600433{
434 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
435
Chia-I Wu3f239832014-12-11 22:57:18 +0800436 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800437 intel_pipeline_shader_cleanup(&pipeline->vs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800438 }
439
440 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800441 intel_pipeline_shader_cleanup(&pipeline->tcs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800442 }
443
444 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800445 intel_pipeline_shader_cleanup(&pipeline->tes, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800446 }
447
448 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800449 intel_pipeline_shader_cleanup(&pipeline->gs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800450 }
451
452 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800453 intel_pipeline_shader_cleanup(&pipeline->fs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800454 }
455
456 if (pipeline->active_shaders & SHADER_COMPUTE_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800457 intel_pipeline_shader_cleanup(&pipeline->cs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800458 }
Chia-I Wued833872014-08-23 17:00:35 +0800459
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600460 intel_base_destroy(&pipeline->obj.base);
461}
462
Tony Barbour426b9052015-06-24 16:06:58 -0600463static VkResult pipeline_get_memory_requirements(struct intel_base *base,
464 VkMemoryRequirements* pRequirements)
Chia-I Wub1024732014-12-19 13:00:29 +0800465{
466 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
Chia-I Wub1024732014-12-19 13:00:29 +0800467
Mark Lobodzinski72346292015-07-02 16:49:40 -0600468 pRequirements->size = pipeline->scratch_size;
469 pRequirements->alignment = 1024;
470 pRequirements->memoryTypeBits = (1 << INTEL_MEMORY_TYPE_COUNT) - 1;
Chia-I Wub1024732014-12-19 13:00:29 +0800471
Tony Barbour426b9052015-06-24 16:06:58 -0600472 return VK_SUCCESS;
Chia-I Wub1024732014-12-19 13:00:29 +0800473}
474
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600475static VkResult pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800476{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600477 /*
478 * Validate required elements
479 */
480 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
481 // TODO: Log debug message: Vertex Shader required.
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600482 return VK_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600483 }
484
485 /*
486 * Tessalation control and evaluation have to both have a shader defined or
487 * neither should have a shader defined.
488 */
489 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
490 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
491 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600492 return VK_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600493 }
494
495 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
496 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
497 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
498 SHADER_FRAGMENT_FLAG))) {
499 // TODO: Log debug message: Can only specify compute shader when doing compute
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600500 return VK_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600501 }
502
503 /*
Tony Barbour8205d902015-04-16 15:59:00 -0600504 * VK_PRIMITIVE_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600505 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
506 */
507 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Tony Barbour8205d902015-04-16 15:59:00 -0600508 (pipeline->topology != VK_PRIMITIVE_TOPOLOGY_PATCH)) {
Tobin Ehlis43c973b2015-06-22 11:31:09 -0600509 // TODO: Log debug message: Invalid topology used with tessellation shader.
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600510 return VK_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600511 }
512
Tony Barbour8205d902015-04-16 15:59:00 -0600513 if ((pipeline->topology == VK_PRIMITIVE_TOPOLOGY_PATCH) &&
Tobin Ehlis43c973b2015-06-22 11:31:09 -0600514 (~pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
515 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessellation shader.
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600516 return VK_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600517 }
518
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600519 return VK_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800520}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600521
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800522static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
523 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800524{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800525 const struct intel_gpu *gpu = pipeline->dev->gpu;
526 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wua4d1b392014-10-10 13:57:29 +0800527 const struct intel_pipeline_shader *vs = &pipeline->vs;
528 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800529 int vs_entry_size, gs_entry_size;
530 int vs_size, gs_size;
531
Chia-I Wu509b3f22014-09-02 10:24:05 +0800532 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800533
534 vs_entry_size = ((vs->in_count >= vs->out_count) ?
535 vs->in_count : vs->out_count);
536 gs_entry_size = (gs) ? gs->out_count : 0;
537
538 /* in bytes */
539 vs_entry_size *= sizeof(float) * 4;
540 gs_entry_size *= sizeof(float) * 4;
541
Chia-I Wua4d1b392014-10-10 13:57:29 +0800542 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800543 vs_size = urb_size / 2;
544 gs_size = vs_size;
545 } else {
546 vs_size = urb_size;
547 gs_size = 0;
548 }
549
550 /* 3DSTATE_URB */
551 {
552 const uint8_t cmd_len = 3;
553 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
554 (cmd_len - 2);
555 int vs_alloc_size, gs_alloc_size;
556 int vs_entry_count, gs_entry_count;
557 uint32_t *dw;
558
559 /* in 1024-bit rows */
560 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
561 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
562
563 /* valid range is [1, 5] */
564 if (!vs_alloc_size)
565 vs_alloc_size = 1;
566 if (!gs_alloc_size)
567 gs_alloc_size = 1;
568 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
569
570 /* valid range is [24, 256], multiples of 4 */
571 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
572 if (vs_entry_count > 256)
573 vs_entry_count = 256;
574 assert(vs_entry_count >= 24);
575
576 /* valid range is [0, 256], multiples of 4 */
577 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
578 if (gs_entry_count > 256)
579 gs_entry_count = 256;
580
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600581 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800582
583 dw[0] = dw0;
584 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
585 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
586 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
587 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
588 }
589}
590
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800591static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
592 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800593{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800594 const struct intel_gpu *gpu = pipeline->dev->gpu;
595 const int urb_size = ((gpu->gt == 3) ? 512 :
596 (gpu->gt == 2) ? 256 : 128) * 1024;
Cody Northrop306ec352014-10-06 15:11:45 -0600597 const struct intel_pipeline_shader *vs = &pipeline->vs;
598 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800599 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800600 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800601 int vs_entry_size, gs_entry_size;
602 int vs_size, gs_size;
603
Chia-I Wu509b3f22014-09-02 10:24:05 +0800604 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800605
606 vs_entry_size = ((vs->in_count >= vs->out_count) ?
607 vs->in_count : vs->out_count);
608 gs_entry_size = (gs) ? gs->out_count : 0;
609
610 /* in bytes */
611 vs_entry_size *= sizeof(float) * 4;
612 gs_entry_size *= sizeof(float) * 4;
613
Chia-I Wua4d1b392014-10-10 13:57:29 +0800614 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800615 vs_size = (urb_size - urb_offset) / 2;
616 gs_size = vs_size;
617 } else {
618 vs_size = urb_size - urb_offset;
619 gs_size = 0;
620 }
621
622 /* 3DSTATE_URB_* */
623 {
624 const uint8_t cmd_len = 2;
625 int vs_alloc_size, gs_alloc_size;
626 int vs_entry_count, gs_entry_count;
627 uint32_t *dw;
628
629 /* in 512-bit rows */
630 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
631 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
632
633 if (!vs_alloc_size)
634 vs_alloc_size = 1;
635 if (!gs_alloc_size)
636 gs_alloc_size = 1;
637
638 /* avoid performance decrease due to banking */
639 if (vs_alloc_size == 5)
640 vs_alloc_size = 6;
641
642 /* in multiples of 8 */
643 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
644 assert(vs_entry_count >= 32);
645
646 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
647
Chia-I Wu509b3f22014-09-02 10:24:05 +0800648 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800649 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800650 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800651 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800652 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800653 if (vs_entry_count >= max_vs_entry_count)
654 vs_entry_count = max_vs_entry_count;
655 if (gs_entry_count >= max_gs_entry_count)
656 gs_entry_count = max_gs_entry_count;
657 } else {
658 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800659 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800660 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800661 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800662 if (vs_entry_count >= max_vs_entry_count)
663 vs_entry_count = max_vs_entry_count;
664 if (gs_entry_count >= max_gs_entry_count)
665 gs_entry_count = max_gs_entry_count;
666 }
667
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600668 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800669 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700670 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT |
671 (vs_alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800672 vs_entry_count;
673
674 dw += 2;
675 if (gs_size)
676 urb_offset += vs_size;
677 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700678 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT |
679 (gs_alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800680 gs_entry_count;
681
682 dw += 2;
683 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700684 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800685
686 dw += 2;
687 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700688 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800689 }
690}
691
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800692static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
693 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800694{
Cody Northrop306ec352014-10-06 15:11:45 -0600695 const struct intel_pipeline_shader *vs = &pipeline->vs;
Chia-I Wu1d125092014-10-08 08:49:38 +0800696 uint8_t cmd_len;
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800697 uint32_t *dw;
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600698 uint32_t i, j;
699 uint32_t attr_count;
700 uint32_t attrs_processed;
Chia-I Wu1d125092014-10-08 08:49:38 +0800701 int comps[4];
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800702
Chia-I Wu509b3f22014-09-02 10:24:05 +0800703 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800704
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600705 attr_count = u_popcountll(vs->inputs_read);
706 cmd_len = 1 + 2 * attr_count;
Chia-I Wu1d125092014-10-08 08:49:38 +0800707 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID))
708 cmd_len += 2;
709
710 if (cmd_len == 1)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800711 return;
712
713 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wu1d125092014-10-08 08:49:38 +0800714
715 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
716 (cmd_len - 2);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800717 dw++;
718
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800719 /* VERTEX_ELEMENT_STATE */
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600720 for (i = 0, attrs_processed = 0; attrs_processed < attr_count; i++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600721 VkVertexInputAttributeDescription *attr = NULL;
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600722
723 /*
724 * The compiler will pack the shader references and then
725 * indicate which locations are used via the bitmask in
726 * vs->inputs_read.
727 */
728 if (!(vs->inputs_read & (1L << i))) {
GregF2dc40212014-10-31 17:31:47 -0600729 continue;
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600730 }
731
732 /*
733 * For each bit set in the vs->inputs_read we'll need
734 * to find the corresponding attribute record and then
735 * set up the next HW vertex element based on that attribute.
736 */
737 for (j = 0; j < info->vi.attributeCount; j++) {
738 if (info->vi.pVertexAttributeDescriptions[j].location == i) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600739 attr = (VkVertexInputAttributeDescription *) &info->vi.pVertexAttributeDescriptions[j];
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600740 attrs_processed++;
741 break;
742 }
743 }
744 assert(attr != NULL);
745
Chia-I Wu1d125092014-10-08 08:49:38 +0800746 const int format =
747 intel_format_translate_color(pipeline->dev->gpu, attr->format);
748
749 comps[0] = GEN6_VFCOMP_STORE_0;
750 comps[1] = GEN6_VFCOMP_STORE_0;
751 comps[2] = GEN6_VFCOMP_STORE_0;
752 comps[3] = icd_format_is_int(attr->format) ?
753 GEN6_VFCOMP_STORE_1_INT : GEN6_VFCOMP_STORE_1_FP;
754
755 switch (icd_format_get_channel_count(attr->format)) {
756 case 4: comps[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
757 case 3: comps[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
758 case 2: comps[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
759 case 1: comps[0] = GEN6_VFCOMP_STORE_SRC; break;
760 default:
761 break;
762 }
763
764 assert(attr->offsetInBytes <= 2047);
765
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700766 dw[0] = attr->binding << GEN6_VE_DW0_VB_INDEX__SHIFT |
767 GEN6_VE_DW0_VALID |
768 format << GEN6_VE_DW0_FORMAT__SHIFT |
Chia-I Wu1d125092014-10-08 08:49:38 +0800769 attr->offsetInBytes;
770
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700771 dw[1] = comps[0] << GEN6_VE_DW1_COMP0__SHIFT |
772 comps[1] << GEN6_VE_DW1_COMP1__SHIFT |
773 comps[2] << GEN6_VE_DW1_COMP2__SHIFT |
774 comps[3] << GEN6_VE_DW1_COMP3__SHIFT;
Chia-I Wu1d125092014-10-08 08:49:38 +0800775
776 dw += 2;
777 }
GregF932fcf52014-10-29 17:02:11 -0600778
779 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)) {
780 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
781 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
782 comps[1] = (vs->uses & INTEL_SHADER_USE_IID) ?
783 GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_NOSTORE;
784 comps[2] = GEN6_VFCOMP_NOSTORE;
785 comps[3] = GEN6_VFCOMP_NOSTORE;
786
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700787 dw[0] = GEN6_VE_DW0_VALID;
788 dw[1] = comps[0] << GEN6_VE_DW1_COMP0__SHIFT |
789 comps[1] << GEN6_VE_DW1_COMP1__SHIFT |
790 comps[2] << GEN6_VE_DW1_COMP2__SHIFT |
791 comps[3] << GEN6_VE_DW1_COMP3__SHIFT;
GregF932fcf52014-10-29 17:02:11 -0600792
793 dw += 2;
794 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800795}
796
Chia-I Wu86a5e0c2015-03-24 11:01:50 +0800797static void pipeline_build_fragment_SBE(struct intel_pipeline *pipeline,
798 const struct intel_pipeline_create_info *info)
GregF8cd81832014-11-18 18:01:01 -0700799{
800 const struct intel_pipeline_shader *fs = &pipeline->fs;
GregF8cd81832014-11-18 18:01:01 -0700801 uint8_t cmd_len;
802 uint32_t *body;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600803 uint32_t attr_skip, attr_count;
804 uint32_t vue_offset, vue_len;
805 uint32_t i;
GregF8cd81832014-11-18 18:01:01 -0700806
Cody Northrop293d4502015-05-05 09:38:03 -0600807 // If GS is active, use its outputs
808 const struct intel_pipeline_shader *src =
809 (pipeline->active_shaders & SHADER_GEOMETRY_FLAG)
810 ? &pipeline->gs
811 : &pipeline->vs;
812
GregF8cd81832014-11-18 18:01:01 -0700813 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
814
815 cmd_len = 14;
816
Chia-I Wuf85def42015-01-29 00:34:24 +0800817 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7))
818 body = pipeline_cmd_ptr(pipeline, cmd_len);
819 else
820 body = pipeline->cmd_3dstate_sbe;
GregF8cd81832014-11-18 18:01:01 -0700821
Cody Northrop293d4502015-05-05 09:38:03 -0600822 assert(!fs->reads_user_clip || src->enable_user_clip);
823 attr_skip = src->outputs_offset;
824 if (src->enable_user_clip != fs->reads_user_clip) {
GregF8cd81832014-11-18 18:01:01 -0700825 attr_skip += 2;
826 }
Cody Northrop293d4502015-05-05 09:38:03 -0600827 assert(src->out_count >= attr_skip);
828 attr_count = src->out_count - attr_skip;
GregF8cd81832014-11-18 18:01:01 -0700829
830 // LUNARG TODO: We currently are only handling 16 attrs;
831 // ultimately, we need to handle 32
832 assert(fs->in_count <= 16);
833 assert(attr_count <= 16);
834
835 vue_offset = attr_skip / 2;
836 vue_len = (attr_count + 1) / 2;
837 if (!vue_len)
838 vue_len = 1;
839
840 body[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
841 (cmd_len - 2);
842
843 // LUNARG TODO: If the attrs needed by the FS are exactly
844 // what is written by the VS, we don't need to enable
845 // swizzling, improving performance. Even if we swizzle,
846 // we can improve performance by reducing vue_len to
847 // just include the values needed by the FS:
848 // vue_len = ceiling((max_vs_out + 1)/2)
849
850 body[1] = GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE |
851 fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
852 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
853 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
854
Chia-I Wu86a5e0c2015-03-24 11:01:50 +0800855 switch (info->rs.pointOrigin) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600856 case VK_COORDINATE_ORIGIN_UPPER_LEFT:
Chia-I Wu86a5e0c2015-03-24 11:01:50 +0800857 body[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_UPPERLEFT;
858 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600859 case VK_COORDINATE_ORIGIN_LOWER_LEFT:
Chia-I Wu86a5e0c2015-03-24 11:01:50 +0800860 body[1] |= GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_LOWERLEFT;
861 break;
862 default:
863 assert(!"unknown point origin");
864 break;
865 }
866
Cody Northrop293d4502015-05-05 09:38:03 -0600867 uint16_t src_slot[fs->in_count];
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600868 int32_t fs_in = 0;
Cody Northrop293d4502015-05-05 09:38:03 -0600869 int32_t src_out = - (vue_offset * 2 - src->outputs_offset);
GregF8cd81832014-11-18 18:01:01 -0700870 for (i=0; i < 64; i++) {
Cody Northrop293d4502015-05-05 09:38:03 -0600871 bool srcWrites = src->outputs_written & (1L << i);
872 bool fsReads = fs->inputs_read & (1L << i);
Cody Northropd75c13e2015-01-02 14:07:20 -0700873
874 if (fsReads) {
Cody Northrop293d4502015-05-05 09:38:03 -0600875 assert(src_out >= 0);
GregF8cd81832014-11-18 18:01:01 -0700876 assert(fs_in < fs->in_count);
Cody Northrop293d4502015-05-05 09:38:03 -0600877 src_slot[fs_in] = src_out;
Cody Northropd75c13e2015-01-02 14:07:20 -0700878
Cody Northrop293d4502015-05-05 09:38:03 -0600879 if (!srcWrites) {
Cody Northropd75c13e2015-01-02 14:07:20 -0700880 // If the vertex shader did not write this input, we cannot
881 // program the SBE to read it. Our choices are to allow it to
882 // read junk from a GRF, or get zero. We're choosing zero.
883 if (i >= fs->generic_input_start) {
Cody Northrop293d4502015-05-05 09:38:03 -0600884 src_slot[fs_in] = GEN8_SBE_SWIZ_CONST_0000 |
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700885 GEN8_SBE_SWIZ_OVERRIDE_X |
886 GEN8_SBE_SWIZ_OVERRIDE_Y |
887 GEN8_SBE_SWIZ_OVERRIDE_Z |
888 GEN8_SBE_SWIZ_OVERRIDE_W;
Cody Northropd75c13e2015-01-02 14:07:20 -0700889 }
890 }
891
GregF8cd81832014-11-18 18:01:01 -0700892 fs_in += 1;
893 }
Cody Northrop293d4502015-05-05 09:38:03 -0600894 if (srcWrites) {
895 src_out += 1;
GregF8cd81832014-11-18 18:01:01 -0700896 }
897 }
898
899 for (i = 0; i < 8; i++) {
900 uint16_t hi, lo;
901
902 /* no attr swizzles */
903 if (i * 2 + 1 < fs->in_count) {
Cody Northrop293d4502015-05-05 09:38:03 -0600904 lo = src_slot[i * 2];
905 hi = src_slot[i * 2 + 1];
GregF8cd81832014-11-18 18:01:01 -0700906 } else if (i * 2 < fs->in_count) {
Cody Northrop293d4502015-05-05 09:38:03 -0600907 lo = src_slot[i * 2];
GregF8cd81832014-11-18 18:01:01 -0700908 hi = 0;
909 } else {
910 hi = 0;
911 lo = 0;
912 }
913
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700914 body[2 + i] = hi << GEN8_SBE_SWIZ_HIGH__SHIFT | lo;
GregF8cd81832014-11-18 18:01:01 -0700915 }
916
Tony Barbour8205d902015-04-16 15:59:00 -0600917 if (info->ia.topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
Chia-I Wu7f390562015-03-25 08:47:18 +0800918 body[10] = fs->point_sprite_enables;
919 else
920 body[10] = 0;
Chia-I Wu86a5e0c2015-03-24 11:01:50 +0800921
GregF8cd81832014-11-18 18:01:01 -0700922 body[11] = 0; /* constant interpolation enables */
923 body[12] = 0; /* WrapShortest enables */
924 body[13] = 0;
925}
926
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800927static void pipeline_build_gs(struct intel_pipeline *pipeline,
928 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600929{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600930 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600931}
932
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800933static void pipeline_build_hs(struct intel_pipeline *pipeline,
934 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600935{
936 const uint8_t cmd_len = 7;
937 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
938 uint32_t *dw;
939
Chia-I Wu509b3f22014-09-02 10:24:05 +0800940 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600941
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800942 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600943 dw[0] = dw0;
944 dw[1] = 0;
945 dw[2] = 0;
946 dw[3] = 0;
947 dw[4] = 0;
948 dw[5] = 0;
949 dw[6] = 0;
950}
951
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800952static void pipeline_build_te(struct intel_pipeline *pipeline,
953 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600954{
955 const uint8_t cmd_len = 4;
956 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
957 uint32_t *dw;
958
Chia-I Wu509b3f22014-09-02 10:24:05 +0800959 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600960
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800961 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600962 dw[0] = dw0;
963 dw[1] = 0;
964 dw[2] = 0;
965 dw[3] = 0;
966}
967
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800968static void pipeline_build_ds(struct intel_pipeline *pipeline,
969 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600970{
971 const uint8_t cmd_len = 6;
972 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
973 uint32_t *dw;
974
Chia-I Wu509b3f22014-09-02 10:24:05 +0800975 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600976
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800977 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600978 dw[0] = dw0;
979 dw[1] = 0;
980 dw[2] = 0;
981 dw[3] = 0;
982 dw[4] = 0;
983 dw[5] = 0;
984}
985
Tony Barbourfa6cac72015-01-16 14:27:35 -0700986static void pipeline_build_depth_stencil(struct intel_pipeline *pipeline,
987 const struct intel_pipeline_create_info *info)
988{
989 pipeline->cmd_depth_stencil = 0;
990
991 if (info->db.stencilTestEnable) {
992 pipeline->cmd_depth_stencil = 1 << 31 |
Tony Barbour8205d902015-04-16 15:59:00 -0600993 translate_compare_func(info->db.front.stencilCompareOp) << 28 |
Tony Barbourfa6cac72015-01-16 14:27:35 -0700994 translate_stencil_op(info->db.front.stencilFailOp) << 25 |
995 translate_stencil_op(info->db.front.stencilDepthFailOp) << 22 |
996 translate_stencil_op(info->db.front.stencilPassOp) << 19 |
997 1 << 15 |
Tony Barbour8205d902015-04-16 15:59:00 -0600998 translate_compare_func(info->db.back.stencilCompareOp) << 12 |
Tony Barbourfa6cac72015-01-16 14:27:35 -0700999 translate_stencil_op(info->db.back.stencilFailOp) << 9 |
1000 translate_stencil_op(info->db.back.stencilDepthFailOp) << 6 |
1001 translate_stencil_op(info->db.back.stencilPassOp) << 3;
1002 }
1003
1004 pipeline->stencilTestEnable = info->db.stencilTestEnable;
1005
1006 /*
1007 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
1008 *
1009 * "Enabling the Depth Test function without defining a Depth Buffer is
1010 * UNDEFINED."
1011 *
1012 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
1013 *
1014 * "A Depth Buffer must be defined before enabling writes to it, or
1015 * operation is UNDEFINED."
1016 *
1017 * TODO We do not check these yet.
1018 */
1019 if (info->db.depthTestEnable) {
1020 pipeline->cmd_depth_test = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
Tony Barbour8205d902015-04-16 15:59:00 -06001021 translate_compare_func(info->db.depthCompareOp) << 27;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001022 } else {
1023 pipeline->cmd_depth_test = GEN6_COMPAREFUNCTION_ALWAYS << 27;
1024 }
1025
1026 if (info->db.depthWriteEnable)
1027 pipeline->cmd_depth_test |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
1028}
1029
Tony Barbourfa6cac72015-01-16 14:27:35 -07001030static void pipeline_build_msaa(struct intel_pipeline *pipeline,
1031 const struct intel_pipeline_create_info *info)
1032{
1033 uint32_t cmd, cmd_len;
1034 uint32_t *dw;
1035
1036 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1037
Tony Barboure094edf2015-06-26 10:18:34 -06001038 pipeline->sample_count = (info->ms.rasterSamples <= 1) ? 1 : info->ms.rasterSamples;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001039
1040 /* 3DSTATE_SAMPLE_MASK */
1041 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK);
1042 cmd_len = 2;
1043
Chia-I Wu8ada4242015-03-02 11:19:33 -07001044 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001045 dw[0] = cmd | (cmd_len - 2);
1046 dw[1] = info->ms.sampleMask & ((1 << pipeline->sample_count) - 1);
1047 pipeline->cmd_sample_mask = dw[1];
1048}
1049
1050static void pipeline_build_cb(struct intel_pipeline *pipeline,
1051 const struct intel_pipeline_create_info *info)
1052{
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001053 uint32_t i;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001054
1055 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1056 STATIC_ASSERT(ARRAY_SIZE(pipeline->cmd_cb) >= INTEL_MAX_RENDER_TARGETS*2);
1057 assert(info->cb.attachmentCount <= INTEL_MAX_RENDER_TARGETS);
1058
1059 uint32_t *dw = pipeline->cmd_cb;
1060
1061 for (i = 0; i < info->cb.attachmentCount; i++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001062 const VkPipelineCbAttachmentState *att = &info->cb.pAttachments[i];
Tony Barbourfa6cac72015-01-16 14:27:35 -07001063 uint32_t dw0, dw1;
1064
1065
1066 dw0 = 0;
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001067 dw1 = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
1068 GEN6_RT_DW1_PRE_BLEND_CLAMP |
1069 GEN6_RT_DW1_POST_BLEND_CLAMP;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001070
1071 if (att->blendEnable) {
1072 dw0 = 1 << 31 |
Tony Barbour8205d902015-04-16 15:59:00 -06001073 translate_blend_func(att->blendOpAlpha) << 26 |
Tony Barbourfa6cac72015-01-16 14:27:35 -07001074 translate_blend(att->srcBlendAlpha) << 20 |
1075 translate_blend(att->destBlendAlpha) << 15 |
Tony Barbour8205d902015-04-16 15:59:00 -06001076 translate_blend_func(att->blendOpColor) << 11 |
Tony Barbourfa6cac72015-01-16 14:27:35 -07001077 translate_blend(att->srcBlendColor) << 5 |
1078 translate_blend(att->destBlendColor);
1079
Tony Barbour8205d902015-04-16 15:59:00 -06001080 if (att->blendOpAlpha != att->blendOpColor ||
Tony Barbourfa6cac72015-01-16 14:27:35 -07001081 att->srcBlendAlpha != att->srcBlendColor ||
1082 att->destBlendAlpha != att->destBlendColor)
1083 dw0 |= 1 << 30;
Courtney Goeltzenleuchterdf13a4d2015-02-11 14:14:45 -07001084
1085 pipeline->dual_source_blend_enable = icd_pipeline_cb_att_needs_dual_source_blending(att);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001086 }
1087
Courtney Goeltzenleuchter72af13a2015-06-26 17:45:23 -06001088 if (info->cb.logicOpEnable && info->cb.logicOp != VK_LOGIC_OP_COPY) {
Tony Barbourfa6cac72015-01-16 14:27:35 -07001089 int logicop;
1090
1091 switch (info->cb.logicOp) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001092 case VK_LOGIC_OP_CLEAR: logicop = GEN6_LOGICOP_CLEAR; break;
1093 case VK_LOGIC_OP_AND: logicop = GEN6_LOGICOP_AND; break;
1094 case VK_LOGIC_OP_AND_REVERSE: logicop = GEN6_LOGICOP_AND_REVERSE; break;
1095 case VK_LOGIC_OP_AND_INVERTED: logicop = GEN6_LOGICOP_AND_INVERTED; break;
1096 case VK_LOGIC_OP_NOOP: logicop = GEN6_LOGICOP_NOOP; break;
1097 case VK_LOGIC_OP_XOR: logicop = GEN6_LOGICOP_XOR; break;
1098 case VK_LOGIC_OP_OR: logicop = GEN6_LOGICOP_OR; break;
1099 case VK_LOGIC_OP_NOR: logicop = GEN6_LOGICOP_NOR; break;
1100 case VK_LOGIC_OP_EQUIV: logicop = GEN6_LOGICOP_EQUIV; break;
1101 case VK_LOGIC_OP_INVERT: logicop = GEN6_LOGICOP_INVERT; break;
1102 case VK_LOGIC_OP_OR_REVERSE: logicop = GEN6_LOGICOP_OR_REVERSE; break;
1103 case VK_LOGIC_OP_COPY_INVERTED: logicop = GEN6_LOGICOP_COPY_INVERTED; break;
1104 case VK_LOGIC_OP_OR_INVERTED: logicop = GEN6_LOGICOP_OR_INVERTED; break;
1105 case VK_LOGIC_OP_NAND: logicop = GEN6_LOGICOP_NAND; break;
1106 case VK_LOGIC_OP_SET: logicop = GEN6_LOGICOP_SET; break;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001107 default:
1108 assert(!"unknown logic op");
1109 logicop = GEN6_LOGICOP_CLEAR;
1110 break;
1111 }
1112
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001113 dw1 |= GEN6_RT_DW1_LOGICOP_ENABLE |
1114 logicop << GEN6_RT_DW1_LOGICOP_FUNC__SHIFT;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001115 }
1116
1117 if (!(att->channelWriteMask & 0x1))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001118 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_R;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001119 if (!(att->channelWriteMask & 0x2))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001120 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_G;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001121 if (!(att->channelWriteMask & 0x4))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001122 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_B;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001123 if (!(att->channelWriteMask & 0x8))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001124 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_A;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001125
1126 dw[2 * i] = dw0;
1127 dw[2 * i + 1] = dw1;
1128 }
1129
1130 for (i=info->cb.attachmentCount; i < INTEL_MAX_RENDER_TARGETS; i++)
1131 {
1132 dw[2 * i] = 0;
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001133 dw[2 * i + 1] = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
1134 GEN6_RT_DW1_PRE_BLEND_CLAMP |
1135 GEN6_RT_DW1_POST_BLEND_CLAMP |
1136 GEN6_RT_DW1_WRITE_DISABLE_R |
1137 GEN6_RT_DW1_WRITE_DISABLE_G |
1138 GEN6_RT_DW1_WRITE_DISABLE_B |
1139 GEN6_RT_DW1_WRITE_DISABLE_A;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001140 }
1141
1142}
1143
1144
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001145static VkResult pipeline_build_all(struct intel_pipeline *pipeline,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001146 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +08001147{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001148 VkResult ret;
Chia-I Wu3efef432014-08-28 15:00:16 +08001149
Chia-I Wu98824592014-09-02 09:42:46 +08001150 ret = pipeline_build_shaders(pipeline, info);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001151 if (ret != VK_SUCCESS)
Chia-I Wu98824592014-09-02 09:42:46 +08001152 return ret;
1153
Chia-I Wu1d125092014-10-08 08:49:38 +08001154 if (info->vi.bindingCount > ARRAY_SIZE(pipeline->vb) ||
1155 info->vi.attributeCount > ARRAY_SIZE(pipeline->vb))
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001156 return VK_ERROR_BAD_PIPELINE_DATA;
Chia-I Wu1d125092014-10-08 08:49:38 +08001157
Chia-I Wu2f455af2015-04-22 15:54:06 +08001158 if (info->vp.clipOrigin != VK_COORDINATE_ORIGIN_UPPER_LEFT) {
1159 assert(!"only VK_COORDINATE_ORIGIN_UPPER_LEFT is supported");
1160 return VK_ERROR_INVALID_VALUE;
1161 }
1162
Chia-I Wue2504cb2015-04-22 14:20:52 +08001163 if (info->vp.depthMode != VK_DEPTH_MODE_ZERO_TO_ONE) {
1164 assert(!"only VK_DEPTH_MODE_ZERO_TO_ONE is supported");
1165 return VK_ERROR_INVALID_VALUE;
1166 }
1167
Chia-I Wu1d125092014-10-08 08:49:38 +08001168 pipeline->vb_count = info->vi.bindingCount;
1169 memcpy(pipeline->vb, info->vi.pVertexBindingDescriptions,
1170 sizeof(pipeline->vb[0]) * pipeline->vb_count);
1171
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001172 pipeline_build_vertex_elements(pipeline, info);
Chia-I Wu86a5e0c2015-03-24 11:01:50 +08001173 pipeline_build_fragment_SBE(pipeline, info);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001174 pipeline_build_msaa(pipeline, info);
Chia-I Wu5bdb0962015-01-24 12:49:28 +08001175 pipeline_build_depth_stencil(pipeline, info);
Chia-I Wu4d9ad912014-08-29 14:20:36 +08001176
Chia-I Wu509b3f22014-09-02 10:24:05 +08001177 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001178 pipeline_build_urb_alloc_gen7(pipeline, info);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001179 pipeline_build_gs(pipeline, info);
1180 pipeline_build_hs(pipeline, info);
1181 pipeline_build_te(pipeline, info);
1182 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001183
1184 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1185 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
1186 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
1187 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
1188 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001189 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001190 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001191
1192 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1193 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001194 }
1195
Chia-I Wube0a3d92014-09-02 13:20:59 +08001196 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001197
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001198 if (ret == VK_SUCCESS)
Chia-I Wu6abcb0e2015-03-24 14:38:14 +08001199 ret = pipeline_build_rs_state(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001200
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001201 if (ret == VK_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001202 pipeline->db_format = info->db.format;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001203 pipeline_build_cb(pipeline, info);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001204 pipeline->cb_state = info->cb;
1205 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +08001206 }
1207
1208 return ret;
1209}
1210
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001211static VkResult pipeline_create_info_init(struct intel_pipeline_create_info *info,
1212 const VkGraphicsPipelineCreateInfo *vkinfo)
Chia-I Wu3efef432014-08-28 15:00:16 +08001213{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001214 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +08001215
Tony Barbourfa6cac72015-01-16 14:27:35 -07001216 /*
1217 * Do we need to set safe defaults in case the app doesn't provide all of
1218 * the necessary create infos?
1219 */
Tony Barboure094edf2015-06-26 10:18:34 -06001220 info->ms.rasterSamples = 1;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001221 info->ms.sampleMask = 1;
1222
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001223 memcpy(&info->graphics, vkinfo, sizeof (info->graphics));
Chia-I Wu3efef432014-08-28 15:00:16 +08001224
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001225 void *dst;
1226 for (uint32_t i = 0; i < vkinfo->stageCount; i++) {
1227 const VkPipelineShaderStageCreateInfo *thisStage = &vkinfo->pStages[i];
1228 switch (thisStage->stage) {
1229 case VK_SHADER_STAGE_VERTEX:
1230 dst = &info->vs;
1231 break;
1232 case VK_SHADER_STAGE_TESS_CONTROL:
1233 dst = &info->tcs;
1234 break;
1235 case VK_SHADER_STAGE_TESS_EVALUATION:
1236 dst = &info->tes;
1237 break;
1238 case VK_SHADER_STAGE_GEOMETRY:
1239 dst = &info->gs;
1240 break;
1241 case VK_SHADER_STAGE_FRAGMENT:
1242 dst = &info->fs;
1243 break;
1244 case VK_SHADER_STAGE_COMPUTE:
1245 dst = &info->compute;
1246 break;
1247 default:
1248 return VK_ERROR_BAD_PIPELINE_DATA;
1249 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001250 }
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001251 memcpy(dst, thisStage, sizeof(VkPipelineShaderStageCreateInfo));
1252 }
Chia-I Wu3efef432014-08-28 15:00:16 +08001253
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001254 if (vkinfo->pVertexInputState != NULL) {
1255 memcpy(&info->vi, vkinfo->pVertexInputState, sizeof (info->vi));
1256 }
1257 if (vkinfo->pIaState != NULL) {
1258 memcpy(&info->ia, vkinfo->pIaState, sizeof (info->ia));
1259 }
1260 if (vkinfo->pDsState != NULL) {
1261 memcpy(&info->db, vkinfo->pDsState, sizeof (info->db));
1262 }
1263 if (vkinfo->pCbState != NULL) {
1264 memcpy(&info->cb, vkinfo->pCbState, sizeof (info->cb));
1265 }
1266 if (vkinfo->pRsState != NULL) {
1267 memcpy(&info->rs, vkinfo->pRsState, sizeof (info->rs));
1268 }
1269 if (vkinfo->pTessState != NULL) {
1270 memcpy(&info->tess, vkinfo->pTessState, sizeof (info->tess));
1271 }
1272 if (vkinfo->pMsState != NULL) {
1273 memcpy(&info->ms, vkinfo->pMsState, sizeof (info->ms));
1274 }
1275 if (vkinfo->pVpState != NULL) {
1276 memcpy(&info->vp, vkinfo->pVpState, sizeof (info->vp));
1277 }
1278 if (vkinfo->pVpState != NULL) {
1279 memcpy(&info->vp, vkinfo->pVpState, sizeof (info->vp));
Chia-I Wu3efef432014-08-28 15:00:16 +08001280 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001281
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001282 return VK_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +08001283}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001284
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001285static VkResult graphics_pipeline_create(struct intel_dev *dev,
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001286 const VkGraphicsPipelineCreateInfo *info_,
1287 struct intel_pipeline **pipeline_ret)
Chia-I Wu3efef432014-08-28 15:00:16 +08001288{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001289 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001290 struct intel_pipeline *pipeline;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001291 VkResult ret;
Chia-I Wu3efef432014-08-28 15:00:16 +08001292
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001293 ret = pipeline_create_info_init(&info, info_);
1294
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001295 if (ret != VK_SUCCESS)
Chia-I Wu3efef432014-08-28 15:00:16 +08001296 return ret;
1297
Chia-I Wu545c2e12015-02-22 13:19:54 +08001298 pipeline = (struct intel_pipeline *) intel_base_create(&dev->base.handle,
Jon Ashburn0d60d272015-07-09 15:02:25 -06001299 sizeof (*pipeline), dev->base.dbg,
1300 VK_OBJECT_TYPE_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +08001301 if (!pipeline)
Tony Barbour8205d902015-04-16 15:59:00 -06001302 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu3efef432014-08-28 15:00:16 +08001303
1304 pipeline->dev = dev;
Jon Ashburn0d60d272015-07-09 15:02:25 -06001305 pipeline->pipeline_layout = intel_pipeline_layout(info.graphics.layout);
Chia-I Wudf601c42015-04-17 01:58:07 +08001306
Tony Barbour426b9052015-06-24 16:06:58 -06001307 pipeline->obj.base.get_memory_requirements = pipeline_get_memory_requirements;
Chia-I Wu3efef432014-08-28 15:00:16 +08001308 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +08001309
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001310 ret = pipeline_build_all(pipeline, &info);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001311 if (ret == VK_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001312 ret = pipeline_validate(pipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001313 if (ret != VK_SUCCESS) {
Chia-I Wu3efef432014-08-28 15:00:16 +08001314 pipeline_destroy(&pipeline->obj);
1315 return ret;
1316 }
1317
1318 *pipeline_ret = pipeline;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001319 return VK_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +08001320}
1321
Jon Ashburn0d60d272015-07-09 15:02:25 -06001322ICD_EXPORT VkResult VKAPI vkCreatePipelineCache(
1323 VkDevice device,
1324 const VkPipelineCacheCreateInfo* pCreateInfo,
1325 VkPipelineCache* pPipelineCache)
Chia-I Wu3efef432014-08-28 15:00:16 +08001326{
Chia-I Wu3efef432014-08-28 15:00:16 +08001327
Jon Ashburn0d60d272015-07-09 15:02:25 -06001328 // non-dispatchable objects only need to be 64 bits currently
1329 *((uint64_t *)pPipelineCache) = 1;
1330 return VK_SUCCESS;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001331}
1332
Jon Ashburn0d60d272015-07-09 15:02:25 -06001333VkResult VKAPI vkDestroyPipelineCache(
1334 VkDevice device,
1335 VkPipelineCache pipelineCache)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001336{
Jon Ashburn0d60d272015-07-09 15:02:25 -06001337 return VK_SUCCESS;
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001338}
1339
Jon Ashburn0d60d272015-07-09 15:02:25 -06001340ICD_EXPORT size_t VKAPI vkGetPipelineCacheSize(
1341 VkDevice device,
1342 VkPipelineCache pipelineCache)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001343{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001344 return VK_ERROR_UNAVAILABLE;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001345}
1346
Jon Ashburn0d60d272015-07-09 15:02:25 -06001347ICD_EXPORT VkResult VKAPI vkGetPipelineCacheData(
1348 VkDevice device,
1349 VkPipelineCache pipelineCache,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001350 void* pData)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001351{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001352 return VK_ERROR_UNAVAILABLE;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001353}
1354
Jon Ashburn0d60d272015-07-09 15:02:25 -06001355ICD_EXPORT VkResult VKAPI vkMergePipelineCaches(
1356 VkDevice device,
1357 VkPipelineCache destCache,
1358 uint32_t srcCacheCount,
1359 const VkPipelineCache* pSrcCaches)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001360{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001361 return VK_ERROR_UNAVAILABLE;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001362}
1363
Jon Ashburn0d60d272015-07-09 15:02:25 -06001364ICD_EXPORT VkResult VKAPI vkCreateGraphicsPipelines(
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001365 VkDevice device,
Jon Ashburn0d60d272015-07-09 15:02:25 -06001366 VkPipelineCache pipelineCache,
1367 uint32_t count,
1368 const VkGraphicsPipelineCreateInfo* pCreateInfos,
1369 VkPipeline* pPipelines)
1370{
1371 struct intel_dev *dev = intel_dev(device);
1372 uint32_t i;
1373 VkResult res;
1374 bool one_succeeded = false;
1375
1376 for (i = 0; i < count; i++) {
1377 res = graphics_pipeline_create(dev, &(pCreateInfos[i]),
1378 (struct intel_pipeline **) &(pPipelines[i]));
1379 //return NULL handle for unsuccessful creates
1380 if (res != VK_SUCCESS)
1381 pPipelines[i] = 0;
1382 else
1383 one_succeeded = true;
1384 }
1385 //return VK_SUCCESS if any of count creates succeeded
1386 if (one_succeeded)
1387 return VK_SUCCESS;
1388 else
1389 return res;
1390}
1391
1392ICD_EXPORT VkResult VKAPI vkCreateComputePipelines(
1393 VkDevice device,
1394 VkPipelineCache pipelineCache,
1395 uint32_t count,
1396 const VkComputePipelineCreateInfo* pCreateInfos,
1397 VkPipeline* pPipelines)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001398{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001399 return VK_ERROR_UNAVAILABLE;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001400}