02343e489d174429eed9b75656eccdfa7d7ea2cf
[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 pipeline->device = device;
193 pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
194 memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
195 VkResult result;
196
197 result = anv_reloc_list_init(&pipeline->batch_relocs, device);
198 if (result != VK_SUCCESS) {
199 anv_device_free(device, pipeline);
200 return result;
201 }
202 pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
203 pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
204 pipeline->batch.relocs = &pipeline->batch_relocs;
205
206 anv_state_stream_init(&pipeline->program_stream,
207 &device->instruction_block_pool);
208
209 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
210 pipeline->shaders[pCreateInfo->pStages[i].stage] =
211 anv_shader_from_handle(pCreateInfo->pStages[i].shader);
212 }
213
214 if (pCreateInfo->pTessellationState)
215 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
216 if (pCreateInfo->pViewportState)
217 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO");
218 if (pCreateInfo->pMultisampleState)
219 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
220
221 pipeline->use_repclear = extra && extra->use_repclear;
222
223 anv_compiler_run(device->compiler, pipeline);
224
225 const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data;
226
227 pipeline->ps_ksp2 = 0;
228 pipeline->ps_grf_start2 = 0;
229 if (pipeline->ps_simd8 != NO_KERNEL) {
230 pipeline->ps_ksp0 = pipeline->ps_simd8;
231 pipeline->ps_grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
232 if (pipeline->ps_simd16 != NO_KERNEL) {
233 pipeline->ps_ksp2 = pipeline->ps_simd16;
234 pipeline->ps_grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
235 }
236 } else if (pipeline->ps_simd16 != NO_KERNEL) {
237 pipeline->ps_ksp0 = pipeline->ps_simd16;
238 pipeline->ps_grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
239 } else {
240 unreachable("no ps shader");
241 }
242
243 const VkPipelineVertexInputStateCreateInfo *vi_info =
244 pCreateInfo->pVertexInputState;
245 pipeline->vb_used = 0;
246 for (uint32_t i = 0; i < vi_info->bindingCount; i++) {
247 const VkVertexInputBindingDescription *desc =
248 &vi_info->pVertexBindingDescriptions[i];
249
250 pipeline->vb_used |= 1 << desc->binding;
251 pipeline->binding_stride[desc->binding] = desc->strideInBytes;
252
253 /* Step rate is programmed per vertex element (attribute), not
254 * binding. Set up a map of which bindings step per instance, for
255 * reference by vertex element setup. */
256 switch (desc->stepRate) {
257 default:
258 case VK_VERTEX_INPUT_STEP_RATE_VERTEX:
259 pipeline->instancing_enable[desc->binding] = false;
260 break;
261 case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
262 pipeline->instancing_enable[desc->binding] = true;
263 break;
264 }
265 }
266
267 const VkPipelineInputAssemblyStateCreateInfo *ia_info =
268 pCreateInfo->pInputAssemblyState;
269 pipeline->primitive_restart = ia_info->primitiveRestartEnable;
270 pipeline->topology = vk_to_gen_primitive_type[ia_info->topology];
271
272 if (extra && extra->use_rectlist)
273 pipeline->topology = _3DPRIM_RECTLIST;
274
275 return VK_SUCCESS;
276 }
277
278 VkResult
279 anv_graphics_pipeline_create(
280 VkDevice _device,
281 const VkGraphicsPipelineCreateInfo *pCreateInfo,
282 const struct anv_graphics_pipeline_create_info *extra,
283 VkPipeline *pPipeline)
284 {
285 ANV_FROM_HANDLE(anv_device, device, _device);
286
287 switch (device->info.gen) {
288 case 8:
289 return gen8_graphics_pipeline_create(_device, pCreateInfo, extra, pPipeline);
290 default:
291 unreachable("unsupported gen\n");
292 }
293 }
294
295 VkResult anv_CreateGraphicsPipelines(
296 VkDevice _device,
297 VkPipelineCache pipelineCache,
298 uint32_t count,
299 const VkGraphicsPipelineCreateInfo* pCreateInfos,
300 VkPipeline* pPipelines)
301 {
302 VkResult result = VK_SUCCESS;
303
304 unsigned i = 0;
305 for (; i < count; i++) {
306 result = anv_graphics_pipeline_create(_device, &pCreateInfos[i],
307 NULL, &pPipelines[i]);
308 if (result != VK_SUCCESS) {
309 for (unsigned j = 0; j < i; j++) {
310 anv_DestroyPipeline(_device, pPipelines[j]);
311 }
312
313 return result;
314 }
315 }
316
317 return VK_SUCCESS;
318 }
319
320 static VkResult anv_compute_pipeline_create(
321 VkDevice _device,
322 const VkComputePipelineCreateInfo* pCreateInfo,
323 VkPipeline* pPipeline)
324 {
325 ANV_FROM_HANDLE(anv_device, device, _device);
326
327 switch (device->info.gen) {
328 case 8:
329 return gen8_compute_pipeline_create(_device, pCreateInfo, pPipeline);
330 default:
331 unreachable("unsupported gen\n");
332 }
333 }
334
335 VkResult anv_CreateComputePipelines(
336 VkDevice _device,
337 VkPipelineCache pipelineCache,
338 uint32_t count,
339 const VkComputePipelineCreateInfo* pCreateInfos,
340 VkPipeline* pPipelines)
341 {
342 VkResult result = VK_SUCCESS;
343
344 unsigned i = 0;
345 for (; i < count; i++) {
346 result = anv_compute_pipeline_create(_device, &pCreateInfos[i],
347 &pPipelines[i]);
348 if (result != VK_SUCCESS) {
349 for (unsigned j = 0; j < i; j++) {
350 anv_DestroyPipeline(_device, pPipelines[j]);
351 }
352
353 return result;
354 }
355 }
356
357 return VK_SUCCESS;
358 }
359
360 // Pipeline layout functions
361
362 VkResult anv_CreatePipelineLayout(
363 VkDevice _device,
364 const VkPipelineLayoutCreateInfo* pCreateInfo,
365 VkPipelineLayout* pPipelineLayout)
366 {
367 ANV_FROM_HANDLE(anv_device, device, _device);
368 struct anv_pipeline_layout *layout;
369
370 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
371
372 layout = anv_device_alloc(device, sizeof(*layout), 8,
373 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
374 if (layout == NULL)
375 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
376
377 layout->num_sets = pCreateInfo->descriptorSetCount;
378
379 uint32_t surface_start[VK_SHADER_STAGE_NUM] = { 0, };
380 uint32_t sampler_start[VK_SHADER_STAGE_NUM] = { 0, };
381
382 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
383 layout->stage[s].surface_count = 0;
384 layout->stage[s].sampler_count = 0;
385 }
386
387 for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
388 ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
389 pCreateInfo->pSetLayouts[i]);
390
391 layout->set[i].layout = set_layout;
392 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
393 layout->set[i].surface_start[s] = surface_start[s];
394 surface_start[s] += set_layout->stage[s].surface_count;
395 layout->set[i].sampler_start[s] = sampler_start[s];
396 sampler_start[s] += set_layout->stage[s].sampler_count;
397
398 layout->stage[s].surface_count += set_layout->stage[s].surface_count;
399 layout->stage[s].sampler_count += set_layout->stage[s].sampler_count;
400 }
401 }
402
403 *pPipelineLayout = anv_pipeline_layout_to_handle(layout);
404
405 return VK_SUCCESS;
406 }
407
408 VkResult anv_DestroyPipelineLayout(
409 VkDevice _device,
410 VkPipelineLayout _pipelineLayout)
411 {
412 ANV_FROM_HANDLE(anv_device, device, _device);
413 ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, _pipelineLayout);
414
415 anv_device_free(device, pipeline_layout);
416
417 return VK_SUCCESS;
418 }