blob: 89a665d2af9bb298009fc94826f20b8b294bd3af [file] [log] [blame]
Dave Airlieb38879f2020-06-19 16:40:27 +10001/*
2 * Copyright © 2019 Red Hat.
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
Dave Airliee94fd4c2020-09-30 05:29:04 +100024#include "lvp_private.h"
Dave Airlieb38879f2020-06-19 16:40:27 +100025
26#include "glsl_types.h"
27#include "spirv/nir_spirv.h"
28#include "nir/nir_builder.h"
Dave Airliee94fd4c2020-09-30 05:29:04 +100029#include "lvp_lower_vulkan_resource.h"
Dave Airlieb38879f2020-06-19 16:40:27 +100030#include "pipe/p_state.h"
31#include "pipe/p_context.h"
32
33#define SPIR_V_MAGIC_NUMBER 0x07230203
34
Dave Airliee94fd4c2020-09-30 05:29:04 +100035VkResult lvp_CreateShaderModule(
Dave Airlieb38879f2020-06-19 16:40:27 +100036 VkDevice _device,
37 const VkShaderModuleCreateInfo* pCreateInfo,
38 const VkAllocationCallbacks* pAllocator,
39 VkShaderModule* pShaderModule)
40{
Dave Airliee94fd4c2020-09-30 05:29:04 +100041 LVP_FROM_HANDLE(lvp_device, device, _device);
42 struct lvp_shader_module *module;
Dave Airlieb38879f2020-06-19 16:40:27 +100043
44 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
45 assert(pCreateInfo->flags == 0);
46
Dave Airlie6e3894d2020-11-16 08:55:16 +100047 module = vk_alloc2(&device->vk.alloc, pAllocator,
Dave Airlieb38879f2020-06-19 16:40:27 +100048 sizeof(*module) + pCreateInfo->codeSize, 8,
49 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
50 if (module == NULL)
51 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
52
53 vk_object_base_init(&device->vk, &module->base,
54 VK_OBJECT_TYPE_SHADER_MODULE);
55 module->size = pCreateInfo->codeSize;
56 memcpy(module->data, pCreateInfo->pCode, module->size);
57
Dave Airliee94fd4c2020-09-30 05:29:04 +100058 *pShaderModule = lvp_shader_module_to_handle(module);
Dave Airlieb38879f2020-06-19 16:40:27 +100059
60 return VK_SUCCESS;
61
62}
63
Dave Airliee94fd4c2020-09-30 05:29:04 +100064void lvp_DestroyShaderModule(
Dave Airlieb38879f2020-06-19 16:40:27 +100065 VkDevice _device,
66 VkShaderModule _module,
67 const VkAllocationCallbacks* pAllocator)
68{
Dave Airliee94fd4c2020-09-30 05:29:04 +100069 LVP_FROM_HANDLE(lvp_device, device, _device);
70 LVP_FROM_HANDLE(lvp_shader_module, module, _module);
Dave Airlieb38879f2020-06-19 16:40:27 +100071
72 if (!_module)
73 return;
74 vk_object_base_finish(&module->base);
Dave Airlie6e3894d2020-11-16 08:55:16 +100075 vk_free2(&device->vk.alloc, pAllocator, module);
Dave Airlieb38879f2020-06-19 16:40:27 +100076}
77
Dave Airliee94fd4c2020-09-30 05:29:04 +100078void lvp_DestroyPipeline(
Dave Airlieb38879f2020-06-19 16:40:27 +100079 VkDevice _device,
80 VkPipeline _pipeline,
81 const VkAllocationCallbacks* pAllocator)
82{
Dave Airliee94fd4c2020-09-30 05:29:04 +100083 LVP_FROM_HANDLE(lvp_device, device, _device);
84 LVP_FROM_HANDLE(lvp_pipeline, pipeline, _pipeline);
Dave Airlieb38879f2020-06-19 16:40:27 +100085
86 if (!_pipeline)
87 return;
88
89 if (pipeline->shader_cso[PIPE_SHADER_VERTEX])
90 device->queue.ctx->delete_vs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
91 if (pipeline->shader_cso[PIPE_SHADER_FRAGMENT])
92 device->queue.ctx->delete_fs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
93 if (pipeline->shader_cso[PIPE_SHADER_GEOMETRY])
94 device->queue.ctx->delete_gs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
95 if (pipeline->shader_cso[PIPE_SHADER_TESS_CTRL])
96 device->queue.ctx->delete_tcs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
97 if (pipeline->shader_cso[PIPE_SHADER_TESS_EVAL])
98 device->queue.ctx->delete_tes_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
99 if (pipeline->shader_cso[PIPE_SHADER_COMPUTE])
100 device->queue.ctx->delete_compute_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);
101
102 if (!pipeline->is_compute_pipeline) {
103 for (unsigned i = 0; i < pipeline->graphics_create_info.stageCount; i++)
104 if (pipeline->graphics_create_info.pStages[i].pSpecializationInfo)
105 free((void *)pipeline->graphics_create_info.pStages[i].pSpecializationInfo);
106
107 free((void *)pipeline->graphics_create_info.pStages);
108 free((void *)pipeline->graphics_create_info.pVertexInputState->pVertexBindingDescriptions);
109 free((void *)pipeline->graphics_create_info.pVertexInputState->pVertexAttributeDescriptions);
110 free((void *)pipeline->graphics_create_info.pVertexInputState);
111 free((void *)pipeline->graphics_create_info.pInputAssemblyState);
112 if (pipeline->graphics_create_info.pViewportState) {
113 free((void *)pipeline->graphics_create_info.pViewportState->pViewports);
114 free((void *)pipeline->graphics_create_info.pViewportState->pScissors);
115 }
116 free((void *)pipeline->graphics_create_info.pViewportState);
117
118 if (pipeline->graphics_create_info.pTessellationState)
119 free((void *)pipeline->graphics_create_info.pTessellationState);
120 free((void *)pipeline->graphics_create_info.pRasterizationState);
121 free((void *)pipeline->graphics_create_info.pMultisampleState);
122 free((void *)pipeline->graphics_create_info.pDepthStencilState);
123 if (pipeline->graphics_create_info.pColorBlendState)
124 free((void *)pipeline->graphics_create_info.pColorBlendState->pAttachments);
125 free((void *)pipeline->graphics_create_info.pColorBlendState);
126 if (pipeline->graphics_create_info.pDynamicState)
127 free((void *)pipeline->graphics_create_info.pDynamicState->pDynamicStates);
128 free((void *)pipeline->graphics_create_info.pDynamicState);
129 } else
130 if (pipeline->compute_create_info.stage.pSpecializationInfo)
131 free((void *)pipeline->compute_create_info.stage.pSpecializationInfo);
132 vk_object_base_finish(&pipeline->base);
Dave Airlie6e3894d2020-11-16 08:55:16 +1000133 vk_free2(&device->vk.alloc, pAllocator, pipeline);
Dave Airlieb38879f2020-06-19 16:40:27 +1000134}
135
136static VkResult
137deep_copy_shader_stage(struct VkPipelineShaderStageCreateInfo *dst,
138 const struct VkPipelineShaderStageCreateInfo *src)
139{
140 dst->sType = src->sType;
141 dst->pNext = NULL;
142 dst->flags = src->flags;
143 dst->stage = src->stage;
144 dst->module = src->module;
145 dst->pName = src->pName;
146 dst->pSpecializationInfo = NULL;
147 if (src->pSpecializationInfo) {
148 const VkSpecializationInfo *src_spec = src->pSpecializationInfo;
149 VkSpecializationInfo *dst_spec = malloc(sizeof(VkSpecializationInfo) +
150 src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry) +
151 src_spec->dataSize);
152 VkSpecializationMapEntry *maps = (VkSpecializationMapEntry *)(dst_spec + 1);
153 dst_spec->pMapEntries = maps;
154 void *pdata = (void *)(dst_spec->pMapEntries + src_spec->mapEntryCount);
155 dst_spec->pData = pdata;
156
157
158 dst_spec->mapEntryCount = src_spec->mapEntryCount;
159 dst_spec->dataSize = src_spec->dataSize;
160 memcpy(pdata, src_spec->pData, src->pSpecializationInfo->dataSize);
161 memcpy(maps, src_spec->pMapEntries, src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry));
162 dst->pSpecializationInfo = dst_spec;
163 }
164 return VK_SUCCESS;
165}
166
167static VkResult
168deep_copy_vertex_input_state(struct VkPipelineVertexInputStateCreateInfo *dst,
169 const struct VkPipelineVertexInputStateCreateInfo *src)
170{
171 int i;
172 VkVertexInputBindingDescription *dst_binding_descriptions;
173 VkVertexInputAttributeDescription *dst_attrib_descriptions;
174 dst->sType = src->sType;
175 dst->pNext = NULL;
176 dst->flags = src->flags;
177 dst->vertexBindingDescriptionCount = src->vertexBindingDescriptionCount;
178
179 dst_binding_descriptions = malloc(src->vertexBindingDescriptionCount * sizeof(VkVertexInputBindingDescription));
180 if (!dst_binding_descriptions)
181 return VK_ERROR_OUT_OF_HOST_MEMORY;
182 for (i = 0; i < dst->vertexBindingDescriptionCount; i++) {
183 memcpy(&dst_binding_descriptions[i], &src->pVertexBindingDescriptions[i], sizeof(VkVertexInputBindingDescription));
184 }
185 dst->pVertexBindingDescriptions = dst_binding_descriptions;
186
187 dst->vertexAttributeDescriptionCount = src->vertexAttributeDescriptionCount;
188
189 dst_attrib_descriptions = malloc(src->vertexAttributeDescriptionCount * sizeof(VkVertexInputAttributeDescription));
190 if (!dst_attrib_descriptions)
191 return VK_ERROR_OUT_OF_HOST_MEMORY;
192
193 for (i = 0; i < dst->vertexAttributeDescriptionCount; i++) {
194 memcpy(&dst_attrib_descriptions[i], &src->pVertexAttributeDescriptions[i], sizeof(VkVertexInputAttributeDescription));
195 }
196 dst->pVertexAttributeDescriptions = dst_attrib_descriptions;
197 return VK_SUCCESS;
198}
199
200static VkResult
201deep_copy_viewport_state(VkPipelineViewportStateCreateInfo *dst,
202 const VkPipelineViewportStateCreateInfo *src)
203{
204 int i;
205 VkViewport *viewports;
206 VkRect2D *scissors;
207 dst->sType = src->sType;
208 dst->pNext = src->pNext;
209
210 dst->flags = src->flags;
211
212 if (src->pViewports) {
213 viewports = malloc(src->viewportCount * sizeof(VkViewport));
214 for (i = 0; i < src->viewportCount; i++)
215 memcpy(&viewports[i], &src->pViewports[i], sizeof(VkViewport));
216 dst->pViewports = viewports;
217 } else
218 dst->pViewports = NULL;
219 dst->viewportCount = src->viewportCount;
220
221 if (src->pScissors) {
222 scissors = malloc(src->scissorCount * sizeof(VkRect2D));
223 for (i = 0; i < src->scissorCount; i++)
224 memcpy(&scissors[i], &src->pScissors[i], sizeof(VkRect2D));
225 dst->pScissors = scissors;
226 } else
227 dst->pScissors = NULL;
228 dst->scissorCount = src->scissorCount;
229
230 return VK_SUCCESS;
231}
232
233static VkResult
234deep_copy_color_blend_state(VkPipelineColorBlendStateCreateInfo *dst,
235 const VkPipelineColorBlendStateCreateInfo *src)
236{
237 VkPipelineColorBlendAttachmentState *attachments;
238 dst->sType = src->sType;
239 dst->pNext = src->pNext;
240 dst->flags = src->flags;
241 dst->logicOpEnable = src->logicOpEnable;
242 dst->logicOp = src->logicOp;
243
244 attachments = malloc(src->attachmentCount * sizeof(VkPipelineColorBlendAttachmentState));
245 memcpy(attachments, src->pAttachments, src->attachmentCount * sizeof(VkPipelineColorBlendAttachmentState));
246 dst->attachmentCount = src->attachmentCount;
247 dst->pAttachments = attachments;
248
249 memcpy(&dst->blendConstants, &src->blendConstants, sizeof(float) * 4);
250
251 return VK_SUCCESS;
252}
253
254static VkResult
255deep_copy_dynamic_state(VkPipelineDynamicStateCreateInfo *dst,
256 const VkPipelineDynamicStateCreateInfo *src)
257{
258 VkDynamicState *dynamic_states;
259 dst->sType = src->sType;
260 dst->pNext = src->pNext;
261 dst->flags = src->flags;
262
263 dynamic_states = malloc(src->dynamicStateCount * sizeof(VkDynamicState));
264 if (!dynamic_states)
265 return VK_ERROR_OUT_OF_HOST_MEMORY;
266
267 memcpy(dynamic_states, src->pDynamicStates, src->dynamicStateCount * sizeof(VkDynamicState));
268 dst->dynamicStateCount = src->dynamicStateCount;
269 dst->pDynamicStates = dynamic_states;
270 return VK_SUCCESS;
271}
272
273static VkResult
274deep_copy_graphics_create_info(VkGraphicsPipelineCreateInfo *dst,
275 const VkGraphicsPipelineCreateInfo *src)
276{
277 int i;
278 VkResult result;
279 VkPipelineShaderStageCreateInfo *stages;
280 VkPipelineVertexInputStateCreateInfo *vertex_input;
281 VkPipelineInputAssemblyStateCreateInfo *input_assembly;
282 VkPipelineRasterizationStateCreateInfo* raster_state;
283
284 dst->sType = src->sType;
285 dst->pNext = NULL;
286 dst->flags = src->flags;
287 dst->layout = src->layout;
288 dst->renderPass = src->renderPass;
289 dst->subpass = src->subpass;
290 dst->basePipelineHandle = src->basePipelineHandle;
291 dst->basePipelineIndex = src->basePipelineIndex;
292
293 /* pStages */
294 dst->stageCount = src->stageCount;
295 stages = malloc(dst->stageCount * sizeof(VkPipelineShaderStageCreateInfo));
296 for (i = 0 ; i < dst->stageCount; i++) {
297 result = deep_copy_shader_stage(&stages[i], &src->pStages[i]);
298 if (result != VK_SUCCESS)
299 return result;
300 }
301 dst->pStages = stages;
302
303 /* pVertexInputState */
304 vertex_input = malloc(sizeof(VkPipelineVertexInputStateCreateInfo));
305 result = deep_copy_vertex_input_state(vertex_input,
306 src->pVertexInputState);
307 if (result != VK_SUCCESS)
308 return result;
309 dst->pVertexInputState = vertex_input;
310
311 /* pInputAssemblyState */
312 input_assembly = malloc(sizeof(VkPipelineInputAssemblyStateCreateInfo));
313 if (!input_assembly)
314 return VK_ERROR_OUT_OF_HOST_MEMORY;
315 memcpy(input_assembly, src->pInputAssemblyState, sizeof(VkPipelineInputAssemblyStateCreateInfo));
316 dst->pInputAssemblyState = input_assembly;
317
318 /* pTessellationState */
319 if (src->pTessellationState) {
320 VkPipelineTessellationStateCreateInfo *tess_state;
321 tess_state = malloc(sizeof(VkPipelineTessellationStateCreateInfo));
322 if (!tess_state)
323 return VK_ERROR_OUT_OF_HOST_MEMORY;
324 memcpy(tess_state, src->pTessellationState, sizeof(VkPipelineTessellationStateCreateInfo));
325 dst->pTessellationState = tess_state;
326 }
327
328
329 /* pViewportState */
330 if (src->pViewportState) {
331 VkPipelineViewportStateCreateInfo *viewport_state;
332 viewport_state = malloc(sizeof(VkPipelineViewportStateCreateInfo));
333 if (!viewport_state)
334 return VK_ERROR_OUT_OF_HOST_MEMORY;
335 deep_copy_viewport_state(viewport_state, src->pViewportState);
336 dst->pViewportState = viewport_state;
337 } else
338 dst->pViewportState = NULL;
339
340 /* pRasterizationState */
341 raster_state = malloc(sizeof(VkPipelineRasterizationStateCreateInfo));
342 if (!raster_state)
343 return VK_ERROR_OUT_OF_HOST_MEMORY;
344 memcpy(raster_state, src->pRasterizationState, sizeof(VkPipelineRasterizationStateCreateInfo));
345 dst->pRasterizationState = raster_state;
346
347 /* pMultisampleState */
348 if (src->pMultisampleState) {
349 VkPipelineMultisampleStateCreateInfo* ms_state;
350 ms_state = malloc(sizeof(VkPipelineMultisampleStateCreateInfo) + sizeof(VkSampleMask));
351 if (!ms_state)
352 return VK_ERROR_OUT_OF_HOST_MEMORY;
353 /* does samplemask need deep copy? */
354 memcpy(ms_state, src->pMultisampleState, sizeof(VkPipelineMultisampleStateCreateInfo));
355 if (src->pMultisampleState->pSampleMask) {
356 VkSampleMask *sample_mask = (VkSampleMask *)(ms_state + 1);
357 sample_mask[0] = src->pMultisampleState->pSampleMask[0];
358 ms_state->pSampleMask = sample_mask;
359 }
360 dst->pMultisampleState = ms_state;
361 } else
362 dst->pMultisampleState = NULL;
363
364 /* pDepthStencilState */
365 if (src->pDepthStencilState) {
366 VkPipelineDepthStencilStateCreateInfo* ds_state;
367
368 ds_state = malloc(sizeof(VkPipelineDepthStencilStateCreateInfo));
369 if (!ds_state)
370 return VK_ERROR_OUT_OF_HOST_MEMORY;
371 memcpy(ds_state, src->pDepthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo));
372 dst->pDepthStencilState = ds_state;
373 } else
374 dst->pDepthStencilState = NULL;
375
376 /* pColorBlendState */
377 if (src->pColorBlendState) {
378 VkPipelineColorBlendStateCreateInfo* cb_state;
379
380 cb_state = malloc(sizeof(VkPipelineColorBlendStateCreateInfo));
381 if (!cb_state)
382 return VK_ERROR_OUT_OF_HOST_MEMORY;
383 deep_copy_color_blend_state(cb_state, src->pColorBlendState);
384 dst->pColorBlendState = cb_state;
385 } else
386 dst->pColorBlendState = NULL;
387
388 if (src->pDynamicState) {
389 VkPipelineDynamicStateCreateInfo* dyn_state;
390
391 /* pDynamicState */
392 dyn_state = malloc(sizeof(VkPipelineDynamicStateCreateInfo));
393 if (!dyn_state)
394 return VK_ERROR_OUT_OF_HOST_MEMORY;
395 deep_copy_dynamic_state(dyn_state, src->pDynamicState);
396 dst->pDynamicState = dyn_state;
397 } else
398 dst->pDynamicState = NULL;
399
400 return VK_SUCCESS;
401}
402
403static VkResult
404deep_copy_compute_create_info(VkComputePipelineCreateInfo *dst,
405 const VkComputePipelineCreateInfo *src)
406{
407 VkResult result;
408 dst->sType = src->sType;
409 dst->pNext = NULL;
410 dst->flags = src->flags;
411 dst->layout = src->layout;
412 dst->basePipelineHandle = src->basePipelineHandle;
413 dst->basePipelineIndex = src->basePipelineIndex;
414
415 result = deep_copy_shader_stage(&dst->stage, &src->stage);
416 if (result != VK_SUCCESS)
417 return result;
418 return VK_SUCCESS;
419}
420
421static inline unsigned
422st_shader_stage_to_ptarget(gl_shader_stage stage)
423{
424 switch (stage) {
425 case MESA_SHADER_VERTEX:
426 return PIPE_SHADER_VERTEX;
427 case MESA_SHADER_FRAGMENT:
428 return PIPE_SHADER_FRAGMENT;
429 case MESA_SHADER_GEOMETRY:
430 return PIPE_SHADER_GEOMETRY;
431 case MESA_SHADER_TESS_CTRL:
432 return PIPE_SHADER_TESS_CTRL;
433 case MESA_SHADER_TESS_EVAL:
434 return PIPE_SHADER_TESS_EVAL;
435 case MESA_SHADER_COMPUTE:
436 return PIPE_SHADER_COMPUTE;
437 default:
438 break;
439 }
440
441 assert(!"should not be reached");
442 return PIPE_SHADER_VERTEX;
443}
444
445static void
446shared_var_info(const struct glsl_type *type, unsigned *size, unsigned *align)
447{
448 assert(glsl_type_is_vector_or_scalar(type));
449
450 uint32_t comp_size = glsl_type_is_boolean(type)
451 ? 4 : glsl_get_bit_size(type) / 8;
452 unsigned length = glsl_get_vector_elements(type);
453 *size = comp_size * length,
454 *align = comp_size;
455}
456
457#define OPT(pass, ...) ({ \
458 bool this_progress = false; \
459 NIR_PASS(this_progress, nir, pass, ##__VA_ARGS__); \
460 if (this_progress) \
461 progress = true; \
462 this_progress; \
463 })
464
465static void
Dave Airliee94fd4c2020-09-30 05:29:04 +1000466lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
467 struct lvp_shader_module *module,
Dave Airlieb38879f2020-06-19 16:40:27 +1000468 const char *entrypoint_name,
469 gl_shader_stage stage,
470 const VkSpecializationInfo *spec_info)
471{
472 nir_shader *nir;
473 const nir_shader_compiler_options *drv_options = pipeline->device->pscreen->get_compiler_options(pipeline->device->pscreen, PIPE_SHADER_IR_NIR, st_shader_stage_to_ptarget(stage));
474 bool progress;
475 uint32_t *spirv = (uint32_t *) module->data;
476 assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
477 assert(module->size % 4 == 0);
478
479 uint32_t num_spec_entries = 0;
480 struct nir_spirv_specialization *spec_entries = NULL;
481 if (spec_info && spec_info->mapEntryCount > 0) {
482 num_spec_entries = spec_info->mapEntryCount;
483 spec_entries = calloc(num_spec_entries, sizeof(*spec_entries));
484 for (uint32_t i = 0; i < num_spec_entries; i++) {
485 VkSpecializationMapEntry entry = spec_info->pMapEntries[i];
486 const void *data =
487 spec_info->pData + entry.offset;
488 assert((const void *)(data + entry.size) <=
489 spec_info->pData + spec_info->dataSize);
490
491 spec_entries[i].id = entry.constantID;
492 switch (entry.size) {
493 case 8:
494 spec_entries[i].value.u64 = *(const uint64_t *)data;
495 break;
496 case 4:
497 spec_entries[i].value.u32 = *(const uint32_t *)data;
498 break;
499 case 2:
500 spec_entries[i].value.u16 = *(const uint16_t *)data;
501 break;
502 case 1:
503 spec_entries[i].value.u8 = *(const uint8_t *)data;
504 break;
505 default:
506 assert(!"Invalid spec constant size");
507 break;
508 }
509 }
510 }
Dave Airliee94fd4c2020-09-30 05:29:04 +1000511 struct lvp_device *pdevice = pipeline->device;
Dave Airlieb38879f2020-06-19 16:40:27 +1000512 const struct spirv_to_nir_options spirv_options = {
513 .environment = NIR_SPIRV_VULKAN,
Dave Airlieb38879f2020-06-19 16:40:27 +1000514 .caps = {
515 .float64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),
516 .int16 = true,
517 .int64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),
518 .tessellation = true,
519 .image_ms_array = true,
520 .storage_image_ms = true,
521 .geometry_streams = true,
522 .storage_16bit = true,
523 .variable_pointers = true,
524 },
525 .ubo_addr_format = nir_address_format_32bit_index_offset,
526 .ssbo_addr_format = nir_address_format_32bit_index_offset,
527 .phys_ssbo_addr_format = nir_address_format_64bit_global,
528 .push_const_addr_format = nir_address_format_logical,
529 .shared_addr_format = nir_address_format_32bit_offset,
530 .frag_coord_is_sysval = false,
531 };
532
533 nir = spirv_to_nir(spirv, module->size / 4,
534 spec_entries, num_spec_entries,
535 stage, entrypoint_name, &spirv_options, drv_options);
536
537 nir_validate_shader(nir, NULL);
538
539 free(spec_entries);
540
541 NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
542 NIR_PASS_V(nir, nir_lower_returns);
543 NIR_PASS_V(nir, nir_inline_functions);
544 NIR_PASS_V(nir, nir_copy_prop);
545 NIR_PASS_V(nir, nir_opt_deref);
546
547 /* Pick off the single entrypoint that we want */
548 foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
549 if (!func->is_entrypoint)
550 exec_node_remove(&func->node);
551 }
552 assert(exec_list_length(&nir->functions) == 1);
553
554 NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
555 NIR_PASS_V(nir, nir_split_var_copies);
556 NIR_PASS_V(nir, nir_split_per_member_structs);
557
558 NIR_PASS_V(nir, nir_remove_dead_variables,
559 nir_var_shader_in | nir_var_shader_out | nir_var_system_value, NULL);
560
561 if (stage == MESA_SHADER_FRAGMENT)
Dave Airliee94fd4c2020-09-30 05:29:04 +1000562 lvp_lower_input_attachments(nir, false);
Dave Airlieb38879f2020-06-19 16:40:27 +1000563 NIR_PASS_V(nir, nir_lower_system_values);
Jesse Natalied3faac72020-08-21 10:40:45 -0700564 NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);
Dave Airlieb38879f2020-06-19 16:40:27 +1000565
566 NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
567 nir_remove_dead_variables(nir, nir_var_uniform, NULL);
568
Dave Airliee94fd4c2020-09-30 05:29:04 +1000569 lvp_lower_pipeline_layout(pipeline->device, pipeline->layout, nir);
Dave Airlieb38879f2020-06-19 16:40:27 +1000570
571 NIR_PASS_V(nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir), true, true);
572 NIR_PASS_V(nir, nir_split_var_copies);
573 NIR_PASS_V(nir, nir_lower_global_vars_to_local);
574
Jason Ekstrandd3fa7452020-05-27 17:09:33 -0500575 NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const,
576 nir_address_format_32bit_offset);
577
Jason Ekstrand1cadbe52020-09-21 17:34:23 -0500578 NIR_PASS_V(nir, nir_lower_explicit_io,
579 nir_var_mem_ubo | nir_var_mem_ssbo,
580 nir_address_format_32bit_index_offset);
581
Dave Airlieb38879f2020-06-19 16:40:27 +1000582 if (nir->info.stage == MESA_SHADER_COMPUTE) {
583 NIR_PASS_V(nir, nir_lower_vars_to_explicit_types, nir_var_mem_shared, shared_var_info);
584 NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_shared, nir_address_format_32bit_offset);
585 }
586
587 NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_temp, NULL);
588
589 if (nir->info.stage == MESA_SHADER_VERTEX ||
590 nir->info.stage == MESA_SHADER_GEOMETRY) {
591 NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
592 } else if (nir->info.stage == MESA_SHADER_FRAGMENT) {
593 NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, true);
594 }
595
596 do {
597 progress = false;
598
Marek Olšákac55b1a2020-07-22 22:13:16 -0400599 progress |= OPT(nir_lower_flrp, 32|64, true);
Dave Airlieb38879f2020-06-19 16:40:27 +1000600 progress |= OPT(nir_split_array_vars, nir_var_function_temp);
601 progress |= OPT(nir_shrink_vec_array_vars, nir_var_function_temp);
602 progress |= OPT(nir_opt_deref);
603 progress |= OPT(nir_lower_vars_to_ssa);
604
605 progress |= nir_copy_prop(nir);
606 progress |= nir_opt_dce(nir);
607 progress |= nir_opt_dead_cf(nir);
608 progress |= nir_opt_cse(nir);
609 progress |= nir_opt_algebraic(nir);
610 progress |= nir_opt_constant_folding(nir);
611 progress |= nir_opt_undef(nir);
612
613 progress |= nir_opt_deref(nir);
614 progress |= nir_lower_alu_to_scalar(nir, NULL, NULL);
615 } while (progress);
616
617 nir_lower_var_copies(nir);
618 nir_remove_dead_variables(nir, nir_var_function_temp, NULL);
619
620 nir_validate_shader(nir, NULL);
621 nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
622
623 if (nir->info.stage != MESA_SHADER_VERTEX)
624 nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage);
625 else {
626 nir->num_inputs = util_last_bit64(nir->info.inputs_read);
627 nir_foreach_shader_in_variable(var, nir) {
628 var->data.driver_location = var->data.location - VERT_ATTRIB_GENERIC0;
629 }
630 }
631 nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
632 nir->info.stage);
633 pipeline->pipeline_nir[stage] = nir;
634}
635
Dave Airliee94fd4c2020-09-30 05:29:04 +1000636static void fill_shader_prog(struct pipe_shader_state *state, gl_shader_stage stage, struct lvp_pipeline *pipeline)
Dave Airlieb38879f2020-06-19 16:40:27 +1000637{
638 state->type = PIPE_SHADER_IR_NIR;
639 state->ir.nir = pipeline->pipeline_nir[stage];
640}
641
642static void
643merge_tess_info(struct shader_info *tes_info,
644 const struct shader_info *tcs_info)
645{
646 /* The Vulkan 1.0.38 spec, section 21.1 Tessellator says:
647 *
648 * "PointMode. Controls generation of points rather than triangles
649 * or lines. This functionality defaults to disabled, and is
650 * enabled if either shader stage includes the execution mode.
651 *
652 * and about Triangles, Quads, IsoLines, VertexOrderCw, VertexOrderCcw,
653 * PointMode, SpacingEqual, SpacingFractionalEven, SpacingFractionalOdd,
654 * and OutputVertices, it says:
655 *
656 * "One mode must be set in at least one of the tessellation
657 * shader stages."
658 *
659 * So, the fields can be set in either the TCS or TES, but they must
660 * agree if set in both. Our backend looks at TES, so bitwise-or in
661 * the values from the TCS.
662 */
663 assert(tcs_info->tess.tcs_vertices_out == 0 ||
664 tes_info->tess.tcs_vertices_out == 0 ||
665 tcs_info->tess.tcs_vertices_out == tes_info->tess.tcs_vertices_out);
666 tes_info->tess.tcs_vertices_out |= tcs_info->tess.tcs_vertices_out;
667
668 assert(tcs_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
669 tes_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
670 tcs_info->tess.spacing == tes_info->tess.spacing);
671 tes_info->tess.spacing |= tcs_info->tess.spacing;
672
673 assert(tcs_info->tess.primitive_mode == 0 ||
674 tes_info->tess.primitive_mode == 0 ||
675 tcs_info->tess.primitive_mode == tes_info->tess.primitive_mode);
676 tes_info->tess.primitive_mode |= tcs_info->tess.primitive_mode;
677 tes_info->tess.ccw |= tcs_info->tess.ccw;
678 tes_info->tess.point_mode |= tcs_info->tess.point_mode;
679}
680
681static gl_shader_stage
Dave Airliee94fd4c2020-09-30 05:29:04 +1000682lvp_shader_stage(VkShaderStageFlagBits stage)
Dave Airlieb38879f2020-06-19 16:40:27 +1000683{
684 switch (stage) {
685 case VK_SHADER_STAGE_VERTEX_BIT:
686 return MESA_SHADER_VERTEX;
687 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
688 return MESA_SHADER_TESS_CTRL;
689 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
690 return MESA_SHADER_TESS_EVAL;
691 case VK_SHADER_STAGE_GEOMETRY_BIT:
692 return MESA_SHADER_GEOMETRY;
693 case VK_SHADER_STAGE_FRAGMENT_BIT:
694 return MESA_SHADER_FRAGMENT;
695 case VK_SHADER_STAGE_COMPUTE_BIT:
696 return MESA_SHADER_COMPUTE;
697 default:
698 unreachable("invalid VkShaderStageFlagBits");
699 return MESA_SHADER_NONE;
700 }
701}
702
703static VkResult
Dave Airliee94fd4c2020-09-30 05:29:04 +1000704lvp_pipeline_compile(struct lvp_pipeline *pipeline,
Dave Airlieb38879f2020-06-19 16:40:27 +1000705 gl_shader_stage stage)
706{
Dave Airliee94fd4c2020-09-30 05:29:04 +1000707 struct lvp_device *device = pipeline->device;
Dave Airlieb38879f2020-06-19 16:40:27 +1000708 device->physical_device->pscreen->finalize_nir(device->physical_device->pscreen, pipeline->pipeline_nir[stage], true);
709 if (stage == MESA_SHADER_COMPUTE) {
710 struct pipe_compute_state shstate = {};
711 shstate.prog = (void *)pipeline->pipeline_nir[MESA_SHADER_COMPUTE];
712 shstate.ir_type = PIPE_SHADER_IR_NIR;
713 shstate.req_local_mem = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.cs.shared_size;
714 pipeline->shader_cso[PIPE_SHADER_COMPUTE] = device->queue.ctx->create_compute_state(device->queue.ctx, &shstate);
715 } else {
716 struct pipe_shader_state shstate = {};
717 fill_shader_prog(&shstate, stage, pipeline);
718 switch (stage) {
719 case MESA_SHADER_FRAGMENT:
720 pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
721 break;
722 case MESA_SHADER_VERTEX:
723 pipeline->shader_cso[PIPE_SHADER_VERTEX] = device->queue.ctx->create_vs_state(device->queue.ctx, &shstate);
724 break;
725 case MESA_SHADER_GEOMETRY:
726 pipeline->shader_cso[PIPE_SHADER_GEOMETRY] = device->queue.ctx->create_gs_state(device->queue.ctx, &shstate);
727 break;
728 case MESA_SHADER_TESS_CTRL:
729 pipeline->shader_cso[PIPE_SHADER_TESS_CTRL] = device->queue.ctx->create_tcs_state(device->queue.ctx, &shstate);
730 break;
731 case MESA_SHADER_TESS_EVAL:
732 pipeline->shader_cso[PIPE_SHADER_TESS_EVAL] = device->queue.ctx->create_tes_state(device->queue.ctx, &shstate);
733 break;
734 default:
735 unreachable("illegal shader");
736 break;
737 }
738 }
739 return VK_SUCCESS;
740}
741
742static VkResult
Dave Airliee94fd4c2020-09-30 05:29:04 +1000743lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
744 struct lvp_device *device,
745 struct lvp_pipeline_cache *cache,
Dave Airlieb38879f2020-06-19 16:40:27 +1000746 const VkGraphicsPipelineCreateInfo *pCreateInfo,
747 const VkAllocationCallbacks *alloc)
748{
749 if (alloc == NULL)
Dave Airlie6e3894d2020-11-16 08:55:16 +1000750 alloc = &device->vk.alloc;
Dave Airlieb38879f2020-06-19 16:40:27 +1000751 pipeline->device = device;
Dave Airliee94fd4c2020-09-30 05:29:04 +1000752 pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
Dave Airlieb38879f2020-06-19 16:40:27 +1000753 pipeline->force_min_sample = false;
754
755 /* recreate createinfo */
756 deep_copy_graphics_create_info(&pipeline->graphics_create_info, pCreateInfo);
757 pipeline->is_compute_pipeline = false;
758
759 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
Dave Airliee94fd4c2020-09-30 05:29:04 +1000760 LVP_FROM_HANDLE(lvp_shader_module, module,
Dave Airlieb38879f2020-06-19 16:40:27 +1000761 pCreateInfo->pStages[i].module);
Dave Airliee94fd4c2020-09-30 05:29:04 +1000762 gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
763 lvp_shader_compile_to_ir(pipeline, module,
Dave Airlieb38879f2020-06-19 16:40:27 +1000764 pCreateInfo->pStages[i].pName,
765 stage,
766 pCreateInfo->pStages[i].pSpecializationInfo);
767 }
768
769 if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]) {
770 if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.fs.uses_sample_qualifier ||
771 pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read & (SYSTEM_BIT_SAMPLE_ID |
772 SYSTEM_BIT_SAMPLE_POS))
773 pipeline->force_min_sample = true;
774 }
775 if (pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]) {
776 nir_lower_patch_vertices(pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL], pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info.tess.tcs_vertices_out, NULL);
777 merge_tess_info(&pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info, &pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info);
778 pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw = !pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw;
779 }
780
781
782 bool has_fragment_shader = false;
783 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
Dave Airliee94fd4c2020-09-30 05:29:04 +1000784 gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
785 lvp_pipeline_compile(pipeline, stage);
Dave Airlieb38879f2020-06-19 16:40:27 +1000786 if (stage == MESA_SHADER_FRAGMENT)
787 has_fragment_shader = true;
788 }
789
790 if (has_fragment_shader == false) {
791 /* create a dummy fragment shader for this pipeline. */
792 nir_builder b;
793
794 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL);
795 b.shader->info.name = ralloc_strdup(b.shader, "dummy_frag");
796
797 pipeline->pipeline_nir[MESA_SHADER_FRAGMENT] = b.shader;
798 struct pipe_shader_state shstate = {};
799 shstate.type = PIPE_SHADER_IR_NIR;
800 shstate.ir.nir = pipeline->pipeline_nir[MESA_SHADER_FRAGMENT];
801 pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
802 }
803 return VK_SUCCESS;
804}
805
806static VkResult
Dave Airliee94fd4c2020-09-30 05:29:04 +1000807lvp_graphics_pipeline_create(
Dave Airlieb38879f2020-06-19 16:40:27 +1000808 VkDevice _device,
809 VkPipelineCache _cache,
810 const VkGraphicsPipelineCreateInfo *pCreateInfo,
811 const VkAllocationCallbacks *pAllocator,
812 VkPipeline *pPipeline)
813{
Dave Airliee94fd4c2020-09-30 05:29:04 +1000814 LVP_FROM_HANDLE(lvp_device, device, _device);
815 LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
816 struct lvp_pipeline *pipeline;
Dave Airlieb38879f2020-06-19 16:40:27 +1000817 VkResult result;
818
819 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
820
Dave Airlie6e3894d2020-11-16 08:55:16 +1000821 pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
Dave Airlieb38879f2020-06-19 16:40:27 +1000822 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
823 if (pipeline == NULL)
824 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
825
826 vk_object_base_init(&device->vk, &pipeline->base,
827 VK_OBJECT_TYPE_PIPELINE);
Dave Airliee94fd4c2020-09-30 05:29:04 +1000828 result = lvp_graphics_pipeline_init(pipeline, device, cache, pCreateInfo,
Dave Airlieb38879f2020-06-19 16:40:27 +1000829 pAllocator);
830 if (result != VK_SUCCESS) {
Dave Airlie6e3894d2020-11-16 08:55:16 +1000831 vk_free2(&device->vk.alloc, pAllocator, pipeline);
Dave Airlieb38879f2020-06-19 16:40:27 +1000832 return result;
833 }
834
Dave Airliee94fd4c2020-09-30 05:29:04 +1000835 *pPipeline = lvp_pipeline_to_handle(pipeline);
Dave Airlieb38879f2020-06-19 16:40:27 +1000836
837 return VK_SUCCESS;
838}
839
Dave Airliee94fd4c2020-09-30 05:29:04 +1000840VkResult lvp_CreateGraphicsPipelines(
Dave Airlieb38879f2020-06-19 16:40:27 +1000841 VkDevice _device,
842 VkPipelineCache pipelineCache,
843 uint32_t count,
844 const VkGraphicsPipelineCreateInfo* pCreateInfos,
845 const VkAllocationCallbacks* pAllocator,
846 VkPipeline* pPipelines)
847{
848 VkResult result = VK_SUCCESS;
849 unsigned i = 0;
850
851 for (; i < count; i++) {
852 VkResult r;
Dave Airliee94fd4c2020-09-30 05:29:04 +1000853 r = lvp_graphics_pipeline_create(_device,
Dave Airlieb38879f2020-06-19 16:40:27 +1000854 pipelineCache,
855 &pCreateInfos[i],
856 pAllocator, &pPipelines[i]);
857 if (r != VK_SUCCESS) {
858 result = r;
859 pPipelines[i] = VK_NULL_HANDLE;
860 }
861 }
862
863 return result;
864}
865
866static VkResult
Dave Airliee94fd4c2020-09-30 05:29:04 +1000867lvp_compute_pipeline_init(struct lvp_pipeline *pipeline,
868 struct lvp_device *device,
869 struct lvp_pipeline_cache *cache,
Dave Airlieb38879f2020-06-19 16:40:27 +1000870 const VkComputePipelineCreateInfo *pCreateInfo,
871 const VkAllocationCallbacks *alloc)
872{
Dave Airliee94fd4c2020-09-30 05:29:04 +1000873 LVP_FROM_HANDLE(lvp_shader_module, module,
Dave Airlieb38879f2020-06-19 16:40:27 +1000874 pCreateInfo->stage.module);
875 if (alloc == NULL)
Dave Airlie6e3894d2020-11-16 08:55:16 +1000876 alloc = &device->vk.alloc;
Dave Airlieb38879f2020-06-19 16:40:27 +1000877 pipeline->device = device;
Dave Airliee94fd4c2020-09-30 05:29:04 +1000878 pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
Dave Airlieb38879f2020-06-19 16:40:27 +1000879 pipeline->force_min_sample = false;
880
881 deep_copy_compute_create_info(&pipeline->compute_create_info, pCreateInfo);
882 pipeline->is_compute_pipeline = true;
883
Dave Airliee94fd4c2020-09-30 05:29:04 +1000884 lvp_shader_compile_to_ir(pipeline, module,
Dave Airlieb38879f2020-06-19 16:40:27 +1000885 pCreateInfo->stage.pName,
886 MESA_SHADER_COMPUTE,
887 pCreateInfo->stage.pSpecializationInfo);
Dave Airliee94fd4c2020-09-30 05:29:04 +1000888 lvp_pipeline_compile(pipeline, MESA_SHADER_COMPUTE);
Dave Airlieb38879f2020-06-19 16:40:27 +1000889 return VK_SUCCESS;
890}
891
892static VkResult
Dave Airliee94fd4c2020-09-30 05:29:04 +1000893lvp_compute_pipeline_create(
Dave Airlieb38879f2020-06-19 16:40:27 +1000894 VkDevice _device,
895 VkPipelineCache _cache,
896 const VkComputePipelineCreateInfo *pCreateInfo,
897 const VkAllocationCallbacks *pAllocator,
898 VkPipeline *pPipeline)
899{
Dave Airliee94fd4c2020-09-30 05:29:04 +1000900 LVP_FROM_HANDLE(lvp_device, device, _device);
901 LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
902 struct lvp_pipeline *pipeline;
Dave Airlieb38879f2020-06-19 16:40:27 +1000903 VkResult result;
904
905 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);
906
Dave Airlie6e3894d2020-11-16 08:55:16 +1000907 pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
Dave Airlieb38879f2020-06-19 16:40:27 +1000908 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
909 if (pipeline == NULL)
910 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
911
912 vk_object_base_init(&device->vk, &pipeline->base,
913 VK_OBJECT_TYPE_PIPELINE);
Dave Airliee94fd4c2020-09-30 05:29:04 +1000914 result = lvp_compute_pipeline_init(pipeline, device, cache, pCreateInfo,
Dave Airlieb38879f2020-06-19 16:40:27 +1000915 pAllocator);
916 if (result != VK_SUCCESS) {
Dave Airlie6e3894d2020-11-16 08:55:16 +1000917 vk_free2(&device->vk.alloc, pAllocator, pipeline);
Dave Airlieb38879f2020-06-19 16:40:27 +1000918 return result;
919 }
920
Dave Airliee94fd4c2020-09-30 05:29:04 +1000921 *pPipeline = lvp_pipeline_to_handle(pipeline);
Dave Airlieb38879f2020-06-19 16:40:27 +1000922
923 return VK_SUCCESS;
924}
925
Dave Airliee94fd4c2020-09-30 05:29:04 +1000926VkResult lvp_CreateComputePipelines(
Dave Airlieb38879f2020-06-19 16:40:27 +1000927 VkDevice _device,
928 VkPipelineCache pipelineCache,
929 uint32_t count,
930 const VkComputePipelineCreateInfo* pCreateInfos,
931 const VkAllocationCallbacks* pAllocator,
932 VkPipeline* pPipelines)
933{
934 VkResult result = VK_SUCCESS;
935 unsigned i = 0;
936
937 for (; i < count; i++) {
938 VkResult r;
Dave Airliee94fd4c2020-09-30 05:29:04 +1000939 r = lvp_compute_pipeline_create(_device,
Dave Airlieb38879f2020-06-19 16:40:27 +1000940 pipelineCache,
941 &pCreateInfos[i],
942 pAllocator, &pPipelines[i]);
943 if (r != VK_SUCCESS) {
944 result = r;
945 pPipelines[i] = VK_NULL_HANDLE;
946 }
947 }
948
949 return result;
950}