Merge branch 'nir-spirv' into vulkan
[mesa.git] / src / vulkan / anv_pipeline.c
1 /*
2 * Copyright © 2015 Intel Corporation
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "anv_private.h"
31
32 // Shader functions
33
34 VkResult anv_CreateShaderModule(
35 VkDevice _device,
36 const VkShaderModuleCreateInfo* pCreateInfo,
37 VkShaderModule* pShaderModule)
38 {
39 ANV_FROM_HANDLE(anv_device, device, _device);
40 struct anv_shader_module *module;
41
42 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
43 assert(pCreateInfo->flags == 0);
44
45 module = anv_device_alloc(device, sizeof(*module) + pCreateInfo->codeSize, 8,
46 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
47 if (module == NULL)
48 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
49
50 module->size = pCreateInfo->codeSize;
51 memcpy(module->data, pCreateInfo->pCode, module->size);
52
53 *pShaderModule = anv_shader_module_to_handle(module);
54
55 return VK_SUCCESS;
56 }
57
58 VkResult anv_DestroyShaderModule(
59 VkDevice _device,
60 VkShaderModule _module)
61 {
62 ANV_FROM_HANDLE(anv_device, device, _device);
63 ANV_FROM_HANDLE(anv_shader_module, module, _module);
64
65 anv_device_free(device, module);
66
67 return VK_SUCCESS;
68 }
69
70 VkResult anv_CreateShader(
71 VkDevice _device,
72 const VkShaderCreateInfo* pCreateInfo,
73 VkShader* pShader)
74 {
75 ANV_FROM_HANDLE(anv_device, device, _device);
76 ANV_FROM_HANDLE(anv_shader_module, module, pCreateInfo->module);
77 struct anv_shader *shader;
78
79 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_CREATE_INFO);
80 assert(pCreateInfo->flags == 0);
81
82 const char *name = pCreateInfo->pName ? pCreateInfo->pName : "main";
83 size_t name_len = strlen(name);
84
85 if (strcmp(name, "main") != 0) {
86 anv_finishme("Multiple shaders per module not really supported");
87 }
88
89 shader = anv_device_alloc(device, sizeof(*shader) + name_len + 1, 8,
90 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
91 if (shader == NULL)
92 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
93
94 shader->module = module;
95 memcpy(shader->entrypoint, name, name_len + 1);
96
97 *pShader = anv_shader_to_handle(shader);
98
99 return VK_SUCCESS;
100 }
101
102 VkResult anv_DestroyShader(
103 VkDevice _device,
104 VkShader _shader)
105 {
106 ANV_FROM_HANDLE(anv_device, device, _device);
107 ANV_FROM_HANDLE(anv_shader, shader, _shader);
108
109 anv_device_free(device, shader);
110
111 return VK_SUCCESS;
112 }
113
114
115 VkResult anv_CreatePipelineCache(
116 VkDevice device,
117 const VkPipelineCacheCreateInfo* pCreateInfo,
118 VkPipelineCache* pPipelineCache)
119 {
120 pPipelineCache->handle = 1;
121
122 stub_return(VK_SUCCESS);
123 }
124
125 VkResult anv_DestroyPipelineCache(
126 VkDevice _device,
127 VkPipelineCache _cache)
128 {
129 /* VkPipelineCache is a dummy object. */
130 return VK_SUCCESS;
131 }
132
133 size_t anv_GetPipelineCacheSize(
134 VkDevice device,
135 VkPipelineCache pipelineCache)
136 {
137 stub_return(0);
138 }
139
140 VkResult anv_GetPipelineCacheData(
141 VkDevice device,
142 VkPipelineCache pipelineCache,
143 void* pData)
144 {
145 stub_return(VK_UNSUPPORTED);
146 }
147
148 VkResult anv_MergePipelineCaches(
149 VkDevice device,
150 VkPipelineCache destCache,
151 uint32_t srcCacheCount,
152 const VkPipelineCache* pSrcCaches)
153 {
154 stub_return(VK_UNSUPPORTED);
155 }
156
157 VkResult anv_DestroyPipeline(
158 VkDevice _device,
159 VkPipeline _pipeline)
160 {
161 ANV_FROM_HANDLE(anv_device, device, _device);
162 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
163
164 anv_compiler_free(pipeline);
165 anv_reloc_list_finish(&pipeline->batch_relocs, pipeline->device);
166 anv_state_stream_finish(&pipeline->program_stream);
167 anv_state_pool_free(&device->dynamic_state_pool, pipeline->blend_state);
168 anv_device_free(pipeline->device, pipeline);
169
170 return VK_SUCCESS;
171 }
172
173 static const uint32_t vk_to_gen_primitive_type[] = {
174 [VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = _3DPRIM_POINTLIST,
175 [VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = _3DPRIM_LINELIST,
176 [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = _3DPRIM_LINESTRIP,
177 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = _3DPRIM_TRILIST,
178 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = _3DPRIM_TRISTRIP,
179 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = _3DPRIM_TRIFAN,
180 [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ] = _3DPRIM_LINELIST_ADJ,
181 [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ] = _3DPRIM_LINESTRIP_ADJ,
182 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ] = _3DPRIM_TRILIST_ADJ,
183 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ] = _3DPRIM_TRISTRIP_ADJ,
184 [VK_PRIMITIVE_TOPOLOGY_PATCH] = _3DPRIM_PATCHLIST_1
185 };
186
187 VkResult
188 anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
189 const VkGraphicsPipelineCreateInfo *pCreateInfo,
190 const struct anv_graphics_pipeline_create_info *extra)
191 {
192 VkResult result;
193
194 pipeline->device = device;
195 pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
196 memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
197
198 result = anv_reloc_list_init(&pipeline->batch_relocs, device);
199 if (result != VK_SUCCESS) {
200 anv_device_free(device, pipeline);
201 return result;
202 }
203 pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
204 pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
205 pipeline->batch.relocs = &pipeline->batch_relocs;
206
207 anv_state_stream_init(&pipeline->program_stream,
208 &device->instruction_block_pool);
209
210 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
211 pipeline->shaders[pCreateInfo->pStages[i].stage] =
212 anv_shader_from_handle(pCreateInfo->pStages[i].shader);
213 }
214
215 if (pCreateInfo->pTessellationState)
216 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
217 if (pCreateInfo->pViewportState)
218 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO");
219 if (pCreateInfo->pMultisampleState)
220 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
221
222 pipeline->use_repclear = extra && extra->use_repclear;
223
224 anv_compiler_run(device->compiler, pipeline);
225
226 const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data;
227
228 pipeline->ps_ksp2 = 0;
229 pipeline->ps_grf_start2 = 0;
230 if (pipeline->ps_simd8 != NO_KERNEL) {
231 pipeline->ps_ksp0 = pipeline->ps_simd8;
232 pipeline->ps_grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
233 if (pipeline->ps_simd16 != NO_KERNEL) {
234 pipeline->ps_ksp2 = pipeline->ps_simd16;
235 pipeline->ps_grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
236 }
237 } else if (pipeline->ps_simd16 != NO_KERNEL) {
238 pipeline->ps_ksp0 = pipeline->ps_simd16;
239 pipeline->ps_grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
240 } else {
241 unreachable("no ps shader");
242 }
243
244 const VkPipelineVertexInputStateCreateInfo *vi_info =
245 pCreateInfo->pVertexInputState;
246 pipeline->vb_used = 0;
247 for (uint32_t i = 0; i < vi_info->bindingCount; i++) {
248 const VkVertexInputBindingDescription *desc =
249 &vi_info->pVertexBindingDescriptions[i];
250
251 pipeline->vb_used |= 1 << desc->binding;
252 pipeline->binding_stride[desc->binding] = desc->strideInBytes;
253
254 /* Step rate is programmed per vertex element (attribute), not
255 * binding. Set up a map of which bindings step per instance, for
256 * reference by vertex element setup. */
257 switch (desc->stepRate) {
258 default:
259 case VK_VERTEX_INPUT_STEP_RATE_VERTEX:
260 pipeline->instancing_enable[desc->binding] = false;
261 break;
262 case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
263 pipeline->instancing_enable[desc->binding] = true;
264 break;
265 }
266 }
267
268 const VkPipelineInputAssemblyStateCreateInfo *ia_info =
269 pCreateInfo->pInputAssemblyState;
270 pipeline->primitive_restart = ia_info->primitiveRestartEnable;
271 pipeline->topology = vk_to_gen_primitive_type[ia_info->topology];
272
273 if (extra && extra->use_rectlist)
274 pipeline->topology = _3DPRIM_RECTLIST;
275
276 return VK_SUCCESS;
277 }
278
279 VkResult
280 anv_graphics_pipeline_create(
281 VkDevice _device,
282 const VkGraphicsPipelineCreateInfo *pCreateInfo,
283 const struct anv_graphics_pipeline_create_info *extra,
284 VkPipeline *pPipeline)
285 {
286 ANV_FROM_HANDLE(anv_device, device, _device);
287
288 switch (device->info.gen) {
289 case 7:
290 return gen7_graphics_pipeline_create(_device, pCreateInfo, extra, pPipeline);
291 case 8:
292 return gen8_graphics_pipeline_create(_device, pCreateInfo, extra, pPipeline);
293 default:
294 unreachable("unsupported gen\n");
295 }
296 }
297
298 VkResult anv_CreateGraphicsPipelines(
299 VkDevice _device,
300 VkPipelineCache pipelineCache,
301 uint32_t count,
302 const VkGraphicsPipelineCreateInfo* pCreateInfos,
303 VkPipeline* pPipelines)
304 {
305 VkResult result = VK_SUCCESS;
306
307 unsigned i = 0;
308 for (; i < count; i++) {
309 result = anv_graphics_pipeline_create(_device, &pCreateInfos[i],
310 NULL, &pPipelines[i]);
311 if (result != VK_SUCCESS) {
312 for (unsigned j = 0; j < i; j++) {
313 anv_DestroyPipeline(_device, pPipelines[j]);
314 }
315
316 return result;
317 }
318 }
319
320 return VK_SUCCESS;
321 }
322
323 static VkResult anv_compute_pipeline_create(
324 VkDevice _device,
325 const VkComputePipelineCreateInfo* pCreateInfo,
326 VkPipeline* pPipeline)
327 {
328 ANV_FROM_HANDLE(anv_device, device, _device);
329
330 switch (device->info.gen) {
331 case 7:
332 return gen7_compute_pipeline_create(_device, pCreateInfo, pPipeline);
333 case 8:
334 return gen8_compute_pipeline_create(_device, pCreateInfo, pPipeline);
335 default:
336 unreachable("unsupported gen\n");
337 }
338 }
339
340 VkResult anv_CreateComputePipelines(
341 VkDevice _device,
342 VkPipelineCache pipelineCache,
343 uint32_t count,
344 const VkComputePipelineCreateInfo* pCreateInfos,
345 VkPipeline* pPipelines)
346 {
347 VkResult result = VK_SUCCESS;
348
349 unsigned i = 0;
350 for (; i < count; i++) {
351 result = anv_compute_pipeline_create(_device, &pCreateInfos[i],
352 &pPipelines[i]);
353 if (result != VK_SUCCESS) {
354 for (unsigned j = 0; j < i; j++) {
355 anv_DestroyPipeline(_device, pPipelines[j]);
356 }
357
358 return result;
359 }
360 }
361
362 return VK_SUCCESS;
363 }
364
365 // Pipeline layout functions
366
367 VkResult anv_CreatePipelineLayout(
368 VkDevice _device,
369 const VkPipelineLayoutCreateInfo* pCreateInfo,
370 VkPipelineLayout* pPipelineLayout)
371 {
372 ANV_FROM_HANDLE(anv_device, device, _device);
373 struct anv_pipeline_layout *layout;
374
375 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
376
377 layout = anv_device_alloc(device, sizeof(*layout), 8,
378 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
379 if (layout == NULL)
380 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
381
382 layout->num_sets = pCreateInfo->descriptorSetCount;
383
384 uint32_t surface_start[VK_SHADER_STAGE_NUM] = { 0, };
385 uint32_t sampler_start[VK_SHADER_STAGE_NUM] = { 0, };
386
387 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
388 layout->stage[s].surface_count = 0;
389 layout->stage[s].sampler_count = 0;
390 }
391
392 for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
393 ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
394 pCreateInfo->pSetLayouts[i]);
395
396 layout->set[i].layout = set_layout;
397 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
398 layout->set[i].surface_start[s] = surface_start[s];
399 surface_start[s] += set_layout->stage[s].surface_count;
400 layout->set[i].sampler_start[s] = sampler_start[s];
401 sampler_start[s] += set_layout->stage[s].sampler_count;
402
403 layout->stage[s].surface_count += set_layout->stage[s].surface_count;
404 layout->stage[s].sampler_count += set_layout->stage[s].sampler_count;
405 }
406 }
407
408 *pPipelineLayout = anv_pipeline_layout_to_handle(layout);
409
410 return VK_SUCCESS;
411 }
412
413 VkResult anv_DestroyPipelineLayout(
414 VkDevice _device,
415 VkPipelineLayout _pipelineLayout)
416 {
417 ANV_FROM_HANDLE(anv_device, device, _device);
418 ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, _pipelineLayout);
419
420 anv_device_free(device, pipeline_layout);
421
422 return VK_SUCCESS;
423 }