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