• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
24 #include "lvp_private.h"
25 #include "vk_util.h"
26 #include "glsl_types.h"
27 #include "spirv/nir_spirv.h"
28 #include "nir/nir_builder.h"
29 #include "lvp_lower_vulkan_resource.h"
30 #include "pipe/p_state.h"
31 #include "pipe/p_context.h"
32 #include "nir/nir_xfb_info.h"
33 
34 #define SPIR_V_MAGIC_NUMBER 0x07230203
35 
36 #define LVP_PIPELINE_DUP(dst, src, type, count) do {             \
37       type *temp = ralloc_array(mem_ctx, type, count);           \
38       if (!temp) return VK_ERROR_OUT_OF_HOST_MEMORY;             \
39       memcpy(temp, (src), sizeof(type) * count);                 \
40       dst = temp;                                                \
41    } while(0)
42 
lvp_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)43 VKAPI_ATTR void VKAPI_CALL lvp_DestroyPipeline(
44    VkDevice                                    _device,
45    VkPipeline                                  _pipeline,
46    const VkAllocationCallbacks*                pAllocator)
47 {
48    LVP_FROM_HANDLE(lvp_device, device, _device);
49    LVP_FROM_HANDLE(lvp_pipeline, pipeline, _pipeline);
50 
51    if (!_pipeline)
52       return;
53 
54    if (pipeline->shader_cso[PIPE_SHADER_VERTEX])
55       device->queue.ctx->delete_vs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
56    if (pipeline->shader_cso[PIPE_SHADER_FRAGMENT])
57       device->queue.ctx->delete_fs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
58    if (pipeline->shader_cso[PIPE_SHADER_GEOMETRY])
59       device->queue.ctx->delete_gs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
60    if (pipeline->shader_cso[PIPE_SHADER_TESS_CTRL])
61       device->queue.ctx->delete_tcs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
62    if (pipeline->shader_cso[PIPE_SHADER_TESS_EVAL])
63       device->queue.ctx->delete_tes_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
64    if (pipeline->shader_cso[PIPE_SHADER_COMPUTE])
65       device->queue.ctx->delete_compute_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);
66 
67    ralloc_free(pipeline->mem_ctx);
68    vk_object_base_finish(&pipeline->base);
69    vk_free2(&device->vk.alloc, pAllocator, pipeline);
70 }
71 
72 static VkResult
deep_copy_shader_stage(void * mem_ctx,struct VkPipelineShaderStageCreateInfo * dst,const struct VkPipelineShaderStageCreateInfo * src)73 deep_copy_shader_stage(void *mem_ctx,
74                        struct VkPipelineShaderStageCreateInfo *dst,
75                        const struct VkPipelineShaderStageCreateInfo *src)
76 {
77    dst->sType = src->sType;
78    dst->pNext = NULL;
79    dst->flags = src->flags;
80    dst->stage = src->stage;
81    dst->module = src->module;
82    dst->pName = src->pName;
83    dst->pSpecializationInfo = NULL;
84    if (src->pSpecializationInfo) {
85       const VkSpecializationInfo *src_spec = src->pSpecializationInfo;
86       VkSpecializationInfo *dst_spec = ralloc_size(mem_ctx, sizeof(VkSpecializationInfo) +
87                                                    src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry) +
88                                                    src_spec->dataSize);
89       VkSpecializationMapEntry *maps = (VkSpecializationMapEntry *)(dst_spec + 1);
90       dst_spec->pMapEntries = maps;
91       void *pdata = (void *)(dst_spec->pMapEntries + src_spec->mapEntryCount);
92       dst_spec->pData = pdata;
93 
94 
95       dst_spec->mapEntryCount = src_spec->mapEntryCount;
96       dst_spec->dataSize = src_spec->dataSize;
97       memcpy(pdata, src_spec->pData, src->pSpecializationInfo->dataSize);
98       memcpy(maps, src_spec->pMapEntries, src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry));
99       dst->pSpecializationInfo = dst_spec;
100    }
101    return VK_SUCCESS;
102 }
103 
104 static VkResult
deep_copy_vertex_input_state(void * mem_ctx,struct VkPipelineVertexInputStateCreateInfo * dst,const struct VkPipelineVertexInputStateCreateInfo * src)105 deep_copy_vertex_input_state(void *mem_ctx,
106                              struct VkPipelineVertexInputStateCreateInfo *dst,
107                              const struct VkPipelineVertexInputStateCreateInfo *src)
108 {
109    dst->sType = src->sType;
110    dst->pNext = NULL;
111    dst->flags = src->flags;
112    dst->vertexBindingDescriptionCount = src->vertexBindingDescriptionCount;
113 
114    LVP_PIPELINE_DUP(dst->pVertexBindingDescriptions,
115                     src->pVertexBindingDescriptions,
116                     VkVertexInputBindingDescription,
117                     src->vertexBindingDescriptionCount);
118 
119    dst->vertexAttributeDescriptionCount = src->vertexAttributeDescriptionCount;
120 
121    LVP_PIPELINE_DUP(dst->pVertexAttributeDescriptions,
122                     src->pVertexAttributeDescriptions,
123                     VkVertexInputAttributeDescription,
124                     src->vertexAttributeDescriptionCount);
125 
126    if (src->pNext) {
127       vk_foreach_struct(ext, src->pNext) {
128          switch (ext->sType) {
129          case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT: {
130             VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_src = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)ext;
131             VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_dst = ralloc(mem_ctx, VkPipelineVertexInputDivisorStateCreateInfoEXT);
132 
133             ext_dst->sType = ext_src->sType;
134             ext_dst->vertexBindingDivisorCount = ext_src->vertexBindingDivisorCount;
135 
136             LVP_PIPELINE_DUP(ext_dst->pVertexBindingDivisors,
137                              ext_src->pVertexBindingDivisors,
138                              VkVertexInputBindingDivisorDescriptionEXT,
139                              ext_src->vertexBindingDivisorCount);
140 
141             dst->pNext = ext_dst;
142             break;
143          }
144          default:
145             break;
146          }
147       }
148    }
149    return VK_SUCCESS;
150 }
151 
152 static bool
dynamic_state_contains(const VkPipelineDynamicStateCreateInfo * src,VkDynamicState state)153 dynamic_state_contains(const VkPipelineDynamicStateCreateInfo *src, VkDynamicState state)
154 {
155    if (!src)
156       return false;
157 
158    for (unsigned i = 0; i < src->dynamicStateCount; i++)
159       if (src->pDynamicStates[i] == state)
160          return true;
161    return false;
162 }
163 
164 static VkResult
deep_copy_viewport_state(void * mem_ctx,const VkPipelineDynamicStateCreateInfo * dyn_state,VkPipelineViewportStateCreateInfo * dst,const VkPipelineViewportStateCreateInfo * src)165 deep_copy_viewport_state(void *mem_ctx,
166                          const VkPipelineDynamicStateCreateInfo *dyn_state,
167                          VkPipelineViewportStateCreateInfo *dst,
168                          const VkPipelineViewportStateCreateInfo *src)
169 {
170    dst->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
171    dst->pNext = NULL;
172    dst->pViewports = NULL;
173    dst->pScissors = NULL;
174 
175    if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_VIEWPORT) &&
176        !dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)) {
177       LVP_PIPELINE_DUP(dst->pViewports,
178                        src->pViewports,
179                        VkViewport,
180                        src->viewportCount);
181    }
182    if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT))
183       dst->viewportCount = src->viewportCount;
184    else
185       dst->viewportCount = 0;
186 
187    if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_SCISSOR) &&
188        !dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)) {
189       if (src->pScissors)
190          LVP_PIPELINE_DUP(dst->pScissors,
191                           src->pScissors,
192                           VkRect2D,
193                           src->scissorCount);
194    }
195    if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT))
196       dst->scissorCount = src->scissorCount;
197    else
198       dst->scissorCount = 0;
199 
200    return VK_SUCCESS;
201 }
202 
203 static VkResult
deep_copy_color_blend_state(void * mem_ctx,VkPipelineColorBlendStateCreateInfo * dst,const VkPipelineColorBlendStateCreateInfo * src)204 deep_copy_color_blend_state(void *mem_ctx,
205                             VkPipelineColorBlendStateCreateInfo *dst,
206                             const VkPipelineColorBlendStateCreateInfo *src)
207 {
208    dst->sType = src->sType;
209    dst->pNext = NULL;
210    dst->flags = src->flags;
211    dst->logicOpEnable = src->logicOpEnable;
212    dst->logicOp = src->logicOp;
213 
214    LVP_PIPELINE_DUP(dst->pAttachments,
215                     src->pAttachments,
216                     VkPipelineColorBlendAttachmentState,
217                     src->attachmentCount);
218    dst->attachmentCount = src->attachmentCount;
219 
220    memcpy(&dst->blendConstants, &src->blendConstants, sizeof(float) * 4);
221 
222    return VK_SUCCESS;
223 }
224 
225 static VkResult
deep_copy_dynamic_state(void * mem_ctx,VkPipelineDynamicStateCreateInfo * dst,const VkPipelineDynamicStateCreateInfo * src)226 deep_copy_dynamic_state(void *mem_ctx,
227                         VkPipelineDynamicStateCreateInfo *dst,
228                         const VkPipelineDynamicStateCreateInfo *src)
229 {
230    dst->sType = src->sType;
231    dst->pNext = NULL;
232    dst->flags = src->flags;
233 
234    LVP_PIPELINE_DUP(dst->pDynamicStates,
235                     src->pDynamicStates,
236                     VkDynamicState,
237                     src->dynamicStateCount);
238    dst->dynamicStateCount = src->dynamicStateCount;
239    return VK_SUCCESS;
240 }
241 
242 
243 static VkResult
deep_copy_rasterization_state(void * mem_ctx,VkPipelineRasterizationStateCreateInfo * dst,const VkPipelineRasterizationStateCreateInfo * src)244 deep_copy_rasterization_state(void *mem_ctx,
245                               VkPipelineRasterizationStateCreateInfo *dst,
246                               const VkPipelineRasterizationStateCreateInfo *src)
247 {
248    memcpy(dst, src, sizeof(VkPipelineRasterizationStateCreateInfo));
249    dst->pNext = NULL;
250 
251    if (src->pNext) {
252       vk_foreach_struct(ext, src->pNext) {
253          switch (ext->sType) {
254          case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
255             VkPipelineRasterizationDepthClipStateCreateInfoEXT *ext_src = (VkPipelineRasterizationDepthClipStateCreateInfoEXT *)ext;
256             VkPipelineRasterizationDepthClipStateCreateInfoEXT *ext_dst = ralloc(mem_ctx, VkPipelineRasterizationDepthClipStateCreateInfoEXT);
257             ext_dst->sType = ext_src->sType;
258             ext_dst->flags = ext_src->flags;
259             ext_dst->depthClipEnable = ext_src->depthClipEnable;
260             dst->pNext = ext_dst;
261             break;
262          }
263          default:
264             break;
265          }
266       }
267    }
268    return VK_SUCCESS;
269 }
270 
271 static VkResult
deep_copy_graphics_create_info(void * mem_ctx,VkGraphicsPipelineCreateInfo * dst,const VkGraphicsPipelineCreateInfo * src)272 deep_copy_graphics_create_info(void *mem_ctx,
273                                VkGraphicsPipelineCreateInfo *dst,
274                                const VkGraphicsPipelineCreateInfo *src)
275 {
276    int i;
277    VkResult result;
278    VkPipelineShaderStageCreateInfo *stages;
279    VkPipelineVertexInputStateCreateInfo *vertex_input;
280    VkPipelineRasterizationStateCreateInfo *rasterization_state;
281    LVP_FROM_HANDLE(lvp_render_pass, pass, src->renderPass);
282 
283    dst->sType = src->sType;
284    dst->pNext = NULL;
285    dst->flags = src->flags;
286    dst->layout = src->layout;
287    dst->renderPass = src->renderPass;
288    dst->subpass = src->subpass;
289    dst->basePipelineHandle = src->basePipelineHandle;
290    dst->basePipelineIndex = src->basePipelineIndex;
291 
292    /* pStages */
293    VkShaderStageFlags stages_present = 0;
294    dst->stageCount = src->stageCount;
295    stages = ralloc_array(mem_ctx, VkPipelineShaderStageCreateInfo, dst->stageCount);
296    for (i = 0 ; i < dst->stageCount; i++) {
297       result = deep_copy_shader_stage(mem_ctx, &stages[i], &src->pStages[i]);
298       if (result != VK_SUCCESS)
299          return result;
300       stages_present |= src->pStages[i].stage;
301    }
302    dst->pStages = stages;
303 
304    /* pVertexInputState */
305    if (!dynamic_state_contains(src->pDynamicState, VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)) {
306       vertex_input = ralloc(mem_ctx, VkPipelineVertexInputStateCreateInfo);
307       result = deep_copy_vertex_input_state(mem_ctx, vertex_input,
308                                             src->pVertexInputState);
309       if (result != VK_SUCCESS)
310          return result;
311       dst->pVertexInputState = vertex_input;
312    } else
313       dst->pVertexInputState = NULL;
314 
315    /* pInputAssemblyState */
316    LVP_PIPELINE_DUP(dst->pInputAssemblyState,
317                     src->pInputAssemblyState,
318                     VkPipelineInputAssemblyStateCreateInfo,
319                     1);
320 
321    /* pTessellationState */
322    if (src->pTessellationState &&
323       (stages_present & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) ==
324                         (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) {
325       LVP_PIPELINE_DUP(dst->pTessellationState,
326                        src->pTessellationState,
327                        VkPipelineTessellationStateCreateInfo,
328                        1);
329    }
330 
331    /* pViewportState */
332    bool rasterization_disabled = !dynamic_state_contains(src->pDynamicState, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT) &&
333                                  src->pRasterizationState->rasterizerDiscardEnable;
334    if (src->pViewportState && !rasterization_disabled) {
335       VkPipelineViewportStateCreateInfo *viewport_state;
336       viewport_state = ralloc(mem_ctx, VkPipelineViewportStateCreateInfo);
337       if (!viewport_state)
338          return VK_ERROR_OUT_OF_HOST_MEMORY;
339       deep_copy_viewport_state(mem_ctx, src->pDynamicState,
340 			       viewport_state, src->pViewportState);
341       dst->pViewportState = viewport_state;
342    } else
343       dst->pViewportState = NULL;
344 
345    /* pRasterizationState */
346    rasterization_state = ralloc(mem_ctx, VkPipelineRasterizationStateCreateInfo);
347    if (!rasterization_state)
348       return VK_ERROR_OUT_OF_HOST_MEMORY;
349    deep_copy_rasterization_state(mem_ctx, rasterization_state, src->pRasterizationState);
350    dst->pRasterizationState = rasterization_state;
351 
352    /* pMultisampleState */
353    if (src->pMultisampleState && !rasterization_disabled) {
354       VkPipelineMultisampleStateCreateInfo*   ms_state;
355       ms_state = ralloc_size(mem_ctx, sizeof(VkPipelineMultisampleStateCreateInfo) + sizeof(VkSampleMask));
356       if (!ms_state)
357          return VK_ERROR_OUT_OF_HOST_MEMORY;
358       /* does samplemask need deep copy? */
359       memcpy(ms_state, src->pMultisampleState, sizeof(VkPipelineMultisampleStateCreateInfo));
360       if (src->pMultisampleState->pSampleMask) {
361          VkSampleMask *sample_mask = (VkSampleMask *)(ms_state + 1);
362          sample_mask[0] = src->pMultisampleState->pSampleMask[0];
363          ms_state->pSampleMask = sample_mask;
364       }
365       dst->pMultisampleState = ms_state;
366    } else
367       dst->pMultisampleState = NULL;
368 
369    /* pDepthStencilState */
370    if (src->pDepthStencilState && !rasterization_disabled && pass->has_zs_attachment) {
371       LVP_PIPELINE_DUP(dst->pDepthStencilState,
372                        src->pDepthStencilState,
373                        VkPipelineDepthStencilStateCreateInfo,
374                        1);
375    } else
376       dst->pDepthStencilState = NULL;
377 
378    /* pColorBlendState */
379    if (src->pColorBlendState && !rasterization_disabled && pass->has_color_attachment) {
380       VkPipelineColorBlendStateCreateInfo*    cb_state;
381 
382       cb_state = ralloc(mem_ctx, VkPipelineColorBlendStateCreateInfo);
383       if (!cb_state)
384          return VK_ERROR_OUT_OF_HOST_MEMORY;
385       deep_copy_color_blend_state(mem_ctx, cb_state, src->pColorBlendState);
386       dst->pColorBlendState = cb_state;
387    } else
388       dst->pColorBlendState = NULL;
389 
390    if (src->pDynamicState) {
391       VkPipelineDynamicStateCreateInfo*       dyn_state;
392 
393       /* pDynamicState */
394       dyn_state = ralloc(mem_ctx, VkPipelineDynamicStateCreateInfo);
395       if (!dyn_state)
396          return VK_ERROR_OUT_OF_HOST_MEMORY;
397       deep_copy_dynamic_state(mem_ctx, dyn_state, src->pDynamicState);
398       dst->pDynamicState = dyn_state;
399    } else
400       dst->pDynamicState = NULL;
401 
402    return VK_SUCCESS;
403 }
404 
405 static VkResult
deep_copy_compute_create_info(void * mem_ctx,VkComputePipelineCreateInfo * dst,const VkComputePipelineCreateInfo * src)406 deep_copy_compute_create_info(void *mem_ctx,
407                               VkComputePipelineCreateInfo *dst,
408                               const VkComputePipelineCreateInfo *src)
409 {
410    VkResult result;
411    dst->sType = src->sType;
412    dst->pNext = NULL;
413    dst->flags = src->flags;
414    dst->layout = src->layout;
415    dst->basePipelineHandle = src->basePipelineHandle;
416    dst->basePipelineIndex = src->basePipelineIndex;
417 
418    result = deep_copy_shader_stage(mem_ctx, &dst->stage, &src->stage);
419    if (result != VK_SUCCESS)
420       return result;
421    return VK_SUCCESS;
422 }
423 
424 static inline unsigned
st_shader_stage_to_ptarget(gl_shader_stage stage)425 st_shader_stage_to_ptarget(gl_shader_stage stage)
426 {
427    switch (stage) {
428    case MESA_SHADER_VERTEX:
429       return PIPE_SHADER_VERTEX;
430    case MESA_SHADER_FRAGMENT:
431       return PIPE_SHADER_FRAGMENT;
432    case MESA_SHADER_GEOMETRY:
433       return PIPE_SHADER_GEOMETRY;
434    case MESA_SHADER_TESS_CTRL:
435       return PIPE_SHADER_TESS_CTRL;
436    case MESA_SHADER_TESS_EVAL:
437       return PIPE_SHADER_TESS_EVAL;
438    case MESA_SHADER_COMPUTE:
439       return PIPE_SHADER_COMPUTE;
440    default:
441       break;
442    }
443 
444    assert(!"should not be reached");
445    return PIPE_SHADER_VERTEX;
446 }
447 
448 static void
shared_var_info(const struct glsl_type * type,unsigned * size,unsigned * align)449 shared_var_info(const struct glsl_type *type, unsigned *size, unsigned *align)
450 {
451    assert(glsl_type_is_vector_or_scalar(type));
452 
453    uint32_t comp_size = glsl_type_is_boolean(type)
454       ? 4 : glsl_get_bit_size(type) / 8;
455    unsigned length = glsl_get_vector_elements(type);
456    *size = comp_size * length,
457       *align = comp_size;
458 }
459 
460 static void
lvp_shader_compile_to_ir(struct lvp_pipeline * pipeline,struct vk_shader_module * module,const char * entrypoint_name,gl_shader_stage stage,const VkSpecializationInfo * spec_info)461 lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
462                          struct vk_shader_module *module,
463                          const char *entrypoint_name,
464                          gl_shader_stage stage,
465                          const VkSpecializationInfo *spec_info)
466 {
467    nir_shader *nir;
468    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));
469    bool progress;
470    uint32_t *spirv = (uint32_t *) module->data;
471    assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
472    assert(module->size % 4 == 0);
473 
474    uint32_t num_spec_entries = 0;
475    struct nir_spirv_specialization *spec_entries =
476       vk_spec_info_to_nir_spirv(spec_info, &num_spec_entries);
477 
478    struct lvp_device *pdevice = pipeline->device;
479    const struct spirv_to_nir_options spirv_options = {
480       .environment = NIR_SPIRV_VULKAN,
481       .caps = {
482          .float64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),
483          .int16 = true,
484          .int64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),
485          .tessellation = true,
486          .float_controls = true,
487          .image_ms_array = true,
488          .image_read_without_format = true,
489          .image_write_without_format = true,
490          .storage_image_ms = true,
491          .geometry_streams = true,
492          .storage_8bit = true,
493          .storage_16bit = true,
494          .variable_pointers = true,
495          .stencil_export = true,
496          .post_depth_coverage = true,
497          .transform_feedback = true,
498          .device_group = true,
499          .draw_parameters = true,
500          .shader_viewport_index_layer = true,
501          .multiview = true,
502          .physical_storage_buffer_address = true,
503          .int64_atomics = true,
504          .subgroup_arithmetic = true,
505          .subgroup_basic = true,
506          .subgroup_ballot = true,
507          .subgroup_quad = true,
508          .subgroup_vote = true,
509          .int8 = true,
510          .float16 = true,
511       },
512       .ubo_addr_format = nir_address_format_32bit_index_offset,
513       .ssbo_addr_format = nir_address_format_32bit_index_offset,
514       .phys_ssbo_addr_format = nir_address_format_64bit_global,
515       .push_const_addr_format = nir_address_format_logical,
516       .shared_addr_format = nir_address_format_32bit_offset,
517    };
518 
519    nir = spirv_to_nir(spirv, module->size / 4,
520                       spec_entries, num_spec_entries,
521                       stage, entrypoint_name, &spirv_options, drv_options);
522 
523    if (!nir) {
524       free(spec_entries);
525       return;
526    }
527    nir_validate_shader(nir, NULL);
528 
529    free(spec_entries);
530 
531    const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = {
532       .frag_coord = true,
533       .point_coord = true,
534    };
535    NIR_PASS_V(nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
536 
537    NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
538    NIR_PASS_V(nir, nir_lower_returns);
539    NIR_PASS_V(nir, nir_inline_functions);
540    NIR_PASS_V(nir, nir_copy_prop);
541    NIR_PASS_V(nir, nir_opt_deref);
542 
543    /* Pick off the single entrypoint that we want */
544    foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
545       if (!func->is_entrypoint)
546          exec_node_remove(&func->node);
547    }
548    assert(exec_list_length(&nir->functions) == 1);
549 
550    NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
551    NIR_PASS_V(nir, nir_split_var_copies);
552    NIR_PASS_V(nir, nir_split_per_member_structs);
553 
554    NIR_PASS_V(nir, nir_remove_dead_variables,
555               nir_var_shader_in | nir_var_shader_out | nir_var_system_value, NULL);
556 
557    if (stage == MESA_SHADER_FRAGMENT)
558       lvp_lower_input_attachments(nir, false);
559    NIR_PASS_V(nir, nir_lower_system_values);
560    NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);
561 
562    NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
563    NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_uniform, NULL);
564 
565    lvp_lower_pipeline_layout(pipeline->device, pipeline->layout, nir);
566 
567    NIR_PASS_V(nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir), true, true);
568    NIR_PASS_V(nir, nir_split_var_copies);
569    NIR_PASS_V(nir, nir_lower_global_vars_to_local);
570 
571    NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const,
572               nir_address_format_32bit_offset);
573 
574    NIR_PASS_V(nir, nir_lower_explicit_io,
575               nir_var_mem_ubo | nir_var_mem_ssbo,
576               nir_address_format_32bit_index_offset);
577 
578    NIR_PASS_V(nir, nir_lower_explicit_io,
579               nir_var_mem_global,
580               nir_address_format_64bit_global);
581 
582    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 
599       NIR_PASS(progress, nir, nir_lower_flrp, 32|64, true);
600       NIR_PASS(progress, nir, nir_split_array_vars, nir_var_function_temp);
601       NIR_PASS(progress, nir, nir_shrink_vec_array_vars, nir_var_function_temp);
602       NIR_PASS(progress, nir, nir_opt_deref);
603       NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
604 
605       NIR_PASS(progress, nir, nir_copy_prop);
606       NIR_PASS(progress, nir, nir_opt_dce);
607       NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true);
608 
609       NIR_PASS(progress, nir, nir_opt_algebraic);
610       NIR_PASS(progress, nir, nir_opt_constant_folding);
611 
612       NIR_PASS(progress, nir, nir_opt_remove_phis);
613       bool trivial_continues = false;
614       NIR_PASS(trivial_continues, nir, nir_opt_trivial_continues);
615       progress |= trivial_continues;
616       if (trivial_continues) {
617          /* If nir_opt_trivial_continues makes progress, then we need to clean
618           * things up if we want any hope of nir_opt_if or nir_opt_loop_unroll
619           * to make progress.
620           */
621          NIR_PASS(progress, nir, nir_copy_prop);
622          NIR_PASS(progress, nir, nir_opt_dce);
623          NIR_PASS(progress, nir, nir_opt_remove_phis);
624       }
625       NIR_PASS(progress, nir, nir_opt_if, true);
626       NIR_PASS(progress, nir, nir_opt_dead_cf);
627       NIR_PASS(progress, nir, nir_opt_conditional_discard);
628       NIR_PASS(progress, nir, nir_opt_remove_phis);
629       NIR_PASS(progress, nir, nir_opt_cse);
630       NIR_PASS(progress, nir, nir_opt_undef);
631 
632       NIR_PASS(progress, nir, nir_opt_deref);
633       NIR_PASS(progress, nir, nir_lower_alu_to_scalar, NULL, NULL);
634    } while (progress);
635 
636    NIR_PASS_V(nir, nir_lower_var_copies);
637    NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_function_temp, NULL);
638    NIR_PASS_V(nir, nir_opt_dce);
639    nir_sweep(nir);
640 
641    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
642 
643    if (nir->info.stage != MESA_SHADER_VERTEX)
644       nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage);
645    else {
646       nir->num_inputs = util_last_bit64(nir->info.inputs_read);
647       nir_foreach_shader_in_variable(var, nir) {
648          var->data.driver_location = var->data.location - VERT_ATTRIB_GENERIC0;
649       }
650    }
651    nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
652                                nir->info.stage);
653    pipeline->pipeline_nir[stage] = nir;
654 }
655 
fill_shader_prog(struct pipe_shader_state * state,gl_shader_stage stage,struct lvp_pipeline * pipeline)656 static void fill_shader_prog(struct pipe_shader_state *state, gl_shader_stage stage, struct lvp_pipeline *pipeline)
657 {
658    state->type = PIPE_SHADER_IR_NIR;
659    state->ir.nir = pipeline->pipeline_nir[stage];
660 }
661 
662 static void
merge_tess_info(struct shader_info * tes_info,const struct shader_info * tcs_info)663 merge_tess_info(struct shader_info *tes_info,
664                 const struct shader_info *tcs_info)
665 {
666    /* The Vulkan 1.0.38 spec, section 21.1 Tessellator says:
667     *
668     *    "PointMode. Controls generation of points rather than triangles
669     *     or lines. This functionality defaults to disabled, and is
670     *     enabled if either shader stage includes the execution mode.
671     *
672     * and about Triangles, Quads, IsoLines, VertexOrderCw, VertexOrderCcw,
673     * PointMode, SpacingEqual, SpacingFractionalEven, SpacingFractionalOdd,
674     * and OutputVertices, it says:
675     *
676     *    "One mode must be set in at least one of the tessellation
677     *     shader stages."
678     *
679     * So, the fields can be set in either the TCS or TES, but they must
680     * agree if set in both.  Our backend looks at TES, so bitwise-or in
681     * the values from the TCS.
682     */
683    assert(tcs_info->tess.tcs_vertices_out == 0 ||
684           tes_info->tess.tcs_vertices_out == 0 ||
685           tcs_info->tess.tcs_vertices_out == tes_info->tess.tcs_vertices_out);
686    tes_info->tess.tcs_vertices_out |= tcs_info->tess.tcs_vertices_out;
687 
688    assert(tcs_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
689           tes_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
690           tcs_info->tess.spacing == tes_info->tess.spacing);
691    tes_info->tess.spacing |= tcs_info->tess.spacing;
692 
693    assert(tcs_info->tess.primitive_mode == 0 ||
694           tes_info->tess.primitive_mode == 0 ||
695           tcs_info->tess.primitive_mode == tes_info->tess.primitive_mode);
696    tes_info->tess.primitive_mode |= tcs_info->tess.primitive_mode;
697    tes_info->tess.ccw |= tcs_info->tess.ccw;
698    tes_info->tess.point_mode |= tcs_info->tess.point_mode;
699 }
700 
701 static gl_shader_stage
lvp_shader_stage(VkShaderStageFlagBits stage)702 lvp_shader_stage(VkShaderStageFlagBits stage)
703 {
704    switch (stage) {
705    case VK_SHADER_STAGE_VERTEX_BIT:
706       return MESA_SHADER_VERTEX;
707    case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
708       return MESA_SHADER_TESS_CTRL;
709    case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
710       return MESA_SHADER_TESS_EVAL;
711    case VK_SHADER_STAGE_GEOMETRY_BIT:
712       return MESA_SHADER_GEOMETRY;
713    case VK_SHADER_STAGE_FRAGMENT_BIT:
714       return MESA_SHADER_FRAGMENT;
715    case VK_SHADER_STAGE_COMPUTE_BIT:
716       return MESA_SHADER_COMPUTE;
717    default:
718       unreachable("invalid VkShaderStageFlagBits");
719       return MESA_SHADER_NONE;
720    }
721 }
722 
723 static VkResult
lvp_pipeline_compile(struct lvp_pipeline * pipeline,gl_shader_stage stage)724 lvp_pipeline_compile(struct lvp_pipeline *pipeline,
725                      gl_shader_stage stage)
726 {
727    struct lvp_device *device = pipeline->device;
728    device->physical_device->pscreen->finalize_nir(device->physical_device->pscreen, pipeline->pipeline_nir[stage]);
729    if (stage == MESA_SHADER_COMPUTE) {
730       struct pipe_compute_state shstate = {0};
731       shstate.prog = (void *)pipeline->pipeline_nir[MESA_SHADER_COMPUTE];
732       shstate.ir_type = PIPE_SHADER_IR_NIR;
733       shstate.req_local_mem = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.shared_size;
734       pipeline->shader_cso[PIPE_SHADER_COMPUTE] = device->queue.ctx->create_compute_state(device->queue.ctx, &shstate);
735    } else {
736       struct pipe_shader_state shstate = {0};
737       fill_shader_prog(&shstate, stage, pipeline);
738 
739       if (stage == MESA_SHADER_VERTEX ||
740           stage == MESA_SHADER_GEOMETRY ||
741           stage == MESA_SHADER_TESS_EVAL) {
742          nir_xfb_info *xfb_info = nir_gather_xfb_info(pipeline->pipeline_nir[stage], NULL);
743          if (xfb_info) {
744             uint8_t output_mapping[VARYING_SLOT_TESS_MAX];
745             memset(output_mapping, 0, sizeof(output_mapping));
746 
747             nir_foreach_shader_out_variable(var, pipeline->pipeline_nir[stage]) {
748                unsigned slots = var->data.compact ? DIV_ROUND_UP(glsl_get_length(var->type), 4)
749                                                   : glsl_count_attribute_slots(var->type, false);
750                for (unsigned i = 0; i < slots; i++)
751                   output_mapping[var->data.location + i] = var->data.driver_location + i;
752             }
753 
754             shstate.stream_output.num_outputs = xfb_info->output_count;
755             for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
756                if (xfb_info->buffers_written & (1 << i)) {
757                   shstate.stream_output.stride[i] = xfb_info->buffers[i].stride / 4;
758                }
759             }
760             for (unsigned i = 0; i < xfb_info->output_count; i++) {
761                shstate.stream_output.output[i].output_buffer = xfb_info->outputs[i].buffer;
762                shstate.stream_output.output[i].dst_offset = xfb_info->outputs[i].offset / 4;
763                shstate.stream_output.output[i].register_index = output_mapping[xfb_info->outputs[i].location];
764                shstate.stream_output.output[i].num_components = util_bitcount(xfb_info->outputs[i].component_mask);
765                shstate.stream_output.output[i].start_component = ffs(xfb_info->outputs[i].component_mask) - 1;
766                shstate.stream_output.output[i].stream = xfb_info->buffer_to_stream[xfb_info->outputs[i].buffer];
767             }
768 
769             ralloc_free(xfb_info);
770          }
771       }
772 
773       switch (stage) {
774       case MESA_SHADER_FRAGMENT:
775          pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
776          break;
777       case MESA_SHADER_VERTEX:
778          pipeline->shader_cso[PIPE_SHADER_VERTEX] = device->queue.ctx->create_vs_state(device->queue.ctx, &shstate);
779          break;
780       case MESA_SHADER_GEOMETRY:
781          pipeline->shader_cso[PIPE_SHADER_GEOMETRY] = device->queue.ctx->create_gs_state(device->queue.ctx, &shstate);
782          break;
783       case MESA_SHADER_TESS_CTRL:
784          pipeline->shader_cso[PIPE_SHADER_TESS_CTRL] = device->queue.ctx->create_tcs_state(device->queue.ctx, &shstate);
785          break;
786       case MESA_SHADER_TESS_EVAL:
787          pipeline->shader_cso[PIPE_SHADER_TESS_EVAL] = device->queue.ctx->create_tes_state(device->queue.ctx, &shstate);
788          break;
789       default:
790          unreachable("illegal shader");
791          break;
792       }
793    }
794    return VK_SUCCESS;
795 }
796 
797 static VkResult
lvp_graphics_pipeline_init(struct lvp_pipeline * pipeline,struct lvp_device * device,struct lvp_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc)798 lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
799                            struct lvp_device *device,
800                            struct lvp_pipeline_cache *cache,
801                            const VkGraphicsPipelineCreateInfo *pCreateInfo,
802                            const VkAllocationCallbacks *alloc)
803 {
804    if (alloc == NULL)
805       alloc = &device->vk.alloc;
806    pipeline->device = device;
807    pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
808    pipeline->force_min_sample = false;
809 
810    pipeline->mem_ctx = ralloc_context(NULL);
811    /* recreate createinfo */
812    deep_copy_graphics_create_info(pipeline->mem_ctx, &pipeline->graphics_create_info, pCreateInfo);
813    pipeline->is_compute_pipeline = false;
814 
815    const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_state =
816       vk_find_struct_const(pCreateInfo->pRasterizationState,
817                            PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT);
818    pipeline->provoking_vertex_last = pv_state && pv_state->provokingVertexMode == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
819 
820    const VkPipelineRasterizationLineStateCreateInfoEXT *line_state =
821       vk_find_struct_const(pCreateInfo->pRasterizationState,
822                            PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
823    if (line_state) {
824       /* always draw bresenham if !smooth */
825       pipeline->line_stipple_enable = line_state->stippledLineEnable;
826       pipeline->line_smooth = line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
827       pipeline->disable_multisample = line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT ||
828                                       line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
829       pipeline->line_rectangular = line_state->lineRasterizationMode != VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
830       if (pipeline->line_stipple_enable) {
831          if (!dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)) {
832             pipeline->line_stipple_factor = line_state->lineStippleFactor - 1;
833             pipeline->line_stipple_pattern = line_state->lineStipplePattern;
834          } else {
835             pipeline->line_stipple_factor = 0;
836             pipeline->line_stipple_pattern = UINT16_MAX;
837          }
838       }
839    } else
840       pipeline->line_rectangular = true;
841 
842    bool rasterization_disabled = !dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT) &&
843       pipeline->graphics_create_info.pRasterizationState->rasterizerDiscardEnable;
844    LVP_FROM_HANDLE(lvp_render_pass, pass, pipeline->graphics_create_info.renderPass);
845    if (!dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT) &&
846        !rasterization_disabled && pass->has_color_attachment) {
847       const VkPipelineColorWriteCreateInfoEXT *cw_state =
848          vk_find_struct_const(pCreateInfo->pColorBlendState, PIPELINE_COLOR_WRITE_CREATE_INFO_EXT);
849       if (cw_state) {
850          for (unsigned i = 0; i < cw_state->attachmentCount; i++)
851             if (!cw_state->pColorWriteEnables[i]) {
852                VkPipelineColorBlendAttachmentState *att = (void*)&pipeline->graphics_create_info.pColorBlendState->pAttachments[i];
853                att->colorWriteMask = 0;
854             }
855       }
856    }
857 
858 
859    for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
860       VK_FROM_HANDLE(vk_shader_module, module,
861                       pCreateInfo->pStages[i].module);
862       gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
863       lvp_shader_compile_to_ir(pipeline, module,
864                                pCreateInfo->pStages[i].pName,
865                                stage,
866                                pCreateInfo->pStages[i].pSpecializationInfo);
867       if (!pipeline->pipeline_nir[stage])
868          return VK_ERROR_FEATURE_NOT_PRESENT;
869    }
870 
871    if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]) {
872       if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.fs.uses_sample_qualifier ||
873           BITSET_TEST(pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID) ||
874           BITSET_TEST(pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read, SYSTEM_VALUE_SAMPLE_POS))
875          pipeline->force_min_sample = true;
876    }
877    if (pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]) {
878       nir_lower_patch_vertices(pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL], pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info.tess.tcs_vertices_out, NULL);
879       merge_tess_info(&pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info, &pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info);
880       const VkPipelineTessellationDomainOriginStateCreateInfo *domain_origin_state =
881          vk_find_struct_const(pCreateInfo->pTessellationState,
882                               PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO);
883       if (!domain_origin_state || domain_origin_state->domainOrigin == VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT)
884          pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw = !pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw;
885    }
886 
887    pipeline->gs_output_lines = pipeline->pipeline_nir[MESA_SHADER_GEOMETRY] &&
888                                pipeline->pipeline_nir[MESA_SHADER_GEOMETRY]->info.gs.output_primitive == GL_LINES;
889 
890 
891    bool has_fragment_shader = false;
892    for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
893       gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
894       lvp_pipeline_compile(pipeline, stage);
895       if (stage == MESA_SHADER_FRAGMENT)
896          has_fragment_shader = true;
897    }
898 
899    if (has_fragment_shader == false) {
900       /* create a dummy fragment shader for this pipeline. */
901       nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL,
902                                                      "dummy_frag");
903 
904       pipeline->pipeline_nir[MESA_SHADER_FRAGMENT] = b.shader;
905       struct pipe_shader_state shstate = {0};
906       shstate.type = PIPE_SHADER_IR_NIR;
907       shstate.ir.nir = pipeline->pipeline_nir[MESA_SHADER_FRAGMENT];
908       pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
909    }
910    return VK_SUCCESS;
911 }
912 
913 static VkResult
lvp_graphics_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)914 lvp_graphics_pipeline_create(
915    VkDevice _device,
916    VkPipelineCache _cache,
917    const VkGraphicsPipelineCreateInfo *pCreateInfo,
918    const VkAllocationCallbacks *pAllocator,
919    VkPipeline *pPipeline)
920 {
921    LVP_FROM_HANDLE(lvp_device, device, _device);
922    LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
923    struct lvp_pipeline *pipeline;
924    VkResult result;
925 
926    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
927 
928    pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
929                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
930    if (pipeline == NULL)
931       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
932 
933    vk_object_base_init(&device->vk, &pipeline->base,
934                        VK_OBJECT_TYPE_PIPELINE);
935    result = lvp_graphics_pipeline_init(pipeline, device, cache, pCreateInfo,
936                                        pAllocator);
937    if (result != VK_SUCCESS) {
938       vk_free2(&device->vk.alloc, pAllocator, pipeline);
939       return result;
940    }
941 
942    *pPipeline = lvp_pipeline_to_handle(pipeline);
943 
944    return VK_SUCCESS;
945 }
946 
lvp_CreateGraphicsPipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)947 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateGraphicsPipelines(
948    VkDevice                                    _device,
949    VkPipelineCache                             pipelineCache,
950    uint32_t                                    count,
951    const VkGraphicsPipelineCreateInfo*         pCreateInfos,
952    const VkAllocationCallbacks*                pAllocator,
953    VkPipeline*                                 pPipelines)
954 {
955    VkResult result = VK_SUCCESS;
956    unsigned i = 0;
957 
958    for (; i < count; i++) {
959       VkResult r;
960       r = lvp_graphics_pipeline_create(_device,
961                                        pipelineCache,
962                                        &pCreateInfos[i],
963                                        pAllocator, &pPipelines[i]);
964       if (r != VK_SUCCESS) {
965          result = r;
966          pPipelines[i] = VK_NULL_HANDLE;
967       }
968    }
969 
970    return result;
971 }
972 
973 static VkResult
lvp_compute_pipeline_init(struct lvp_pipeline * pipeline,struct lvp_device * device,struct lvp_pipeline_cache * cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc)974 lvp_compute_pipeline_init(struct lvp_pipeline *pipeline,
975                           struct lvp_device *device,
976                           struct lvp_pipeline_cache *cache,
977                           const VkComputePipelineCreateInfo *pCreateInfo,
978                           const VkAllocationCallbacks *alloc)
979 {
980    VK_FROM_HANDLE(vk_shader_module, module,
981                    pCreateInfo->stage.module);
982    if (alloc == NULL)
983       alloc = &device->vk.alloc;
984    pipeline->device = device;
985    pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
986    pipeline->force_min_sample = false;
987 
988    pipeline->mem_ctx = ralloc_context(NULL);
989    deep_copy_compute_create_info(pipeline->mem_ctx,
990                                  &pipeline->compute_create_info, pCreateInfo);
991    pipeline->is_compute_pipeline = true;
992 
993    lvp_shader_compile_to_ir(pipeline, module,
994                             pCreateInfo->stage.pName,
995                             MESA_SHADER_COMPUTE,
996                             pCreateInfo->stage.pSpecializationInfo);
997    if (!pipeline->pipeline_nir[MESA_SHADER_COMPUTE])
998       return VK_ERROR_FEATURE_NOT_PRESENT;
999    lvp_pipeline_compile(pipeline, MESA_SHADER_COMPUTE);
1000    return VK_SUCCESS;
1001 }
1002 
1003 static VkResult
lvp_compute_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)1004 lvp_compute_pipeline_create(
1005    VkDevice _device,
1006    VkPipelineCache _cache,
1007    const VkComputePipelineCreateInfo *pCreateInfo,
1008    const VkAllocationCallbacks *pAllocator,
1009    VkPipeline *pPipeline)
1010 {
1011    LVP_FROM_HANDLE(lvp_device, device, _device);
1012    LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
1013    struct lvp_pipeline *pipeline;
1014    VkResult result;
1015 
1016    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);
1017 
1018    pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
1019                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1020    if (pipeline == NULL)
1021       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1022 
1023    vk_object_base_init(&device->vk, &pipeline->base,
1024                        VK_OBJECT_TYPE_PIPELINE);
1025    result = lvp_compute_pipeline_init(pipeline, device, cache, pCreateInfo,
1026                                       pAllocator);
1027    if (result != VK_SUCCESS) {
1028       vk_free2(&device->vk.alloc, pAllocator, pipeline);
1029       return result;
1030    }
1031 
1032    *pPipeline = lvp_pipeline_to_handle(pipeline);
1033 
1034    return VK_SUCCESS;
1035 }
1036 
lvp_CreateComputePipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)1037 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateComputePipelines(
1038    VkDevice                                    _device,
1039    VkPipelineCache                             pipelineCache,
1040    uint32_t                                    count,
1041    const VkComputePipelineCreateInfo*          pCreateInfos,
1042    const VkAllocationCallbacks*                pAllocator,
1043    VkPipeline*                                 pPipelines)
1044 {
1045    VkResult result = VK_SUCCESS;
1046    unsigned i = 0;
1047 
1048    for (; i < count; i++) {
1049       VkResult r;
1050       r = lvp_compute_pipeline_create(_device,
1051                                       pipelineCache,
1052                                       &pCreateInfos[i],
1053                                       pAllocator, &pPipelines[i]);
1054       if (r != VK_SUCCESS) {
1055          result = r;
1056          pPipelines[i] = VK_NULL_HANDLE;
1057       }
1058    }
1059 
1060    return result;
1061 }
1062