• 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 
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 
33 #define SPIR_V_MAGIC_NUMBER 0x07230203
34 
lvp_CreateShaderModule(VkDevice _device,const VkShaderModuleCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkShaderModule * pShaderModule)35 VkResult lvp_CreateShaderModule(
36    VkDevice                                    _device,
37    const VkShaderModuleCreateInfo*             pCreateInfo,
38    const VkAllocationCallbacks*                pAllocator,
39    VkShaderModule*                             pShaderModule)
40 {
41    LVP_FROM_HANDLE(lvp_device, device, _device);
42    struct lvp_shader_module *module;
43 
44    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
45    assert(pCreateInfo->flags == 0);
46 
47    module = vk_alloc2(&device->vk.alloc, pAllocator,
48                       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 
58    *pShaderModule = lvp_shader_module_to_handle(module);
59 
60    return VK_SUCCESS;
61 
62 }
63 
lvp_DestroyShaderModule(VkDevice _device,VkShaderModule _module,const VkAllocationCallbacks * pAllocator)64 void lvp_DestroyShaderModule(
65    VkDevice                                    _device,
66    VkShaderModule                              _module,
67    const VkAllocationCallbacks*                pAllocator)
68 {
69    LVP_FROM_HANDLE(lvp_device, device, _device);
70    LVP_FROM_HANDLE(lvp_shader_module, module, _module);
71 
72    if (!_module)
73       return;
74    vk_object_base_finish(&module->base);
75    vk_free2(&device->vk.alloc, pAllocator, module);
76 }
77 
lvp_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)78 void lvp_DestroyPipeline(
79    VkDevice                                    _device,
80    VkPipeline                                  _pipeline,
81    const VkAllocationCallbacks*                pAllocator)
82 {
83    LVP_FROM_HANDLE(lvp_device, device, _device);
84    LVP_FROM_HANDLE(lvp_pipeline, pipeline, _pipeline);
85 
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);
133    vk_free2(&device->vk.alloc, pAllocator, pipeline);
134 }
135 
136 static VkResult
deep_copy_shader_stage(struct VkPipelineShaderStageCreateInfo * dst,const struct VkPipelineShaderStageCreateInfo * src)137 deep_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 
167 static VkResult
deep_copy_vertex_input_state(struct VkPipelineVertexInputStateCreateInfo * dst,const struct VkPipelineVertexInputStateCreateInfo * src)168 deep_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 
200 static VkResult
deep_copy_viewport_state(VkPipelineViewportStateCreateInfo * dst,const VkPipelineViewportStateCreateInfo * src)201 deep_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 
233 static VkResult
deep_copy_color_blend_state(VkPipelineColorBlendStateCreateInfo * dst,const VkPipelineColorBlendStateCreateInfo * src)234 deep_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 
254 static VkResult
deep_copy_dynamic_state(VkPipelineDynamicStateCreateInfo * dst,const VkPipelineDynamicStateCreateInfo * src)255 deep_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 
273 static VkResult
deep_copy_graphics_create_info(VkGraphicsPipelineCreateInfo * dst,const VkGraphicsPipelineCreateInfo * src)274 deep_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 
403 static VkResult
deep_copy_compute_create_info(VkComputePipelineCreateInfo * dst,const VkComputePipelineCreateInfo * src)404 deep_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 
421 static inline unsigned
st_shader_stage_to_ptarget(gl_shader_stage stage)422 st_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 
445 static void
shared_var_info(const struct glsl_type * type,unsigned * size,unsigned * align)446 shared_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 
465 static void
lvp_shader_compile_to_ir(struct lvp_pipeline * pipeline,struct lvp_shader_module * module,const char * entrypoint_name,gl_shader_stage stage,const VkSpecializationInfo * spec_info)466 lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
467                          struct lvp_shader_module *module,
468                          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    }
511    struct lvp_device *pdevice = pipeline->device;
512    const struct spirv_to_nir_options spirv_options = {
513       .environment = NIR_SPIRV_VULKAN,
514       .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)
562       lvp_lower_input_attachments(nir, false);
563    NIR_PASS_V(nir, nir_lower_system_values);
564    NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);
565 
566    NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
567    nir_remove_dead_variables(nir, nir_var_uniform, NULL);
568 
569    lvp_lower_pipeline_layout(pipeline->device, pipeline->layout, nir);
570 
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 
575    NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const,
576               nir_address_format_32bit_offset);
577 
578    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 
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       progress |= OPT(nir_lower_flrp, 32|64, true);
600       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 
fill_shader_prog(struct pipe_shader_state * state,gl_shader_stage stage,struct lvp_pipeline * pipeline)636 static void fill_shader_prog(struct pipe_shader_state *state, gl_shader_stage stage, struct lvp_pipeline *pipeline)
637 {
638    state->type = PIPE_SHADER_IR_NIR;
639    state->ir.nir = pipeline->pipeline_nir[stage];
640 }
641 
642 static void
merge_tess_info(struct shader_info * tes_info,const struct shader_info * tcs_info)643 merge_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 
681 static gl_shader_stage
lvp_shader_stage(VkShaderStageFlagBits stage)682 lvp_shader_stage(VkShaderStageFlagBits stage)
683 {
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 
703 static VkResult
lvp_pipeline_compile(struct lvp_pipeline * pipeline,gl_shader_stage stage)704 lvp_pipeline_compile(struct lvp_pipeline *pipeline,
705                      gl_shader_stage stage)
706 {
707    struct lvp_device *device = pipeline->device;
708    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 
742 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)743 lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
744                            struct lvp_device *device,
745                            struct lvp_pipeline_cache *cache,
746                            const VkGraphicsPipelineCreateInfo *pCreateInfo,
747                            const VkAllocationCallbacks *alloc)
748 {
749    if (alloc == NULL)
750       alloc = &device->vk.alloc;
751    pipeline->device = device;
752    pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
753    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++) {
760       LVP_FROM_HANDLE(lvp_shader_module, module,
761                       pCreateInfo->pStages[i].module);
762       gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
763       lvp_shader_compile_to_ir(pipeline, module,
764                                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           BITSET_TEST(pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID) ||
772           BITSET_TEST(pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read, SYSTEM_VALUE_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++) {
784       gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
785       lvp_pipeline_compile(pipeline, stage);
786       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 
806 static VkResult
lvp_graphics_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)807 lvp_graphics_pipeline_create(
808    VkDevice _device,
809    VkPipelineCache _cache,
810    const VkGraphicsPipelineCreateInfo *pCreateInfo,
811    const VkAllocationCallbacks *pAllocator,
812    VkPipeline *pPipeline)
813 {
814    LVP_FROM_HANDLE(lvp_device, device, _device);
815    LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
816    struct lvp_pipeline *pipeline;
817    VkResult result;
818 
819    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
820 
821    pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
822                          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);
828    result = lvp_graphics_pipeline_init(pipeline, device, cache, pCreateInfo,
829                                        pAllocator);
830    if (result != VK_SUCCESS) {
831       vk_free2(&device->vk.alloc, pAllocator, pipeline);
832       return result;
833    }
834 
835    *pPipeline = lvp_pipeline_to_handle(pipeline);
836 
837    return VK_SUCCESS;
838 }
839 
lvp_CreateGraphicsPipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)840 VkResult lvp_CreateGraphicsPipelines(
841    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;
853       r = lvp_graphics_pipeline_create(_device,
854                                        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 
866 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)867 lvp_compute_pipeline_init(struct lvp_pipeline *pipeline,
868                           struct lvp_device *device,
869                           struct lvp_pipeline_cache *cache,
870                           const VkComputePipelineCreateInfo *pCreateInfo,
871                           const VkAllocationCallbacks *alloc)
872 {
873    LVP_FROM_HANDLE(lvp_shader_module, module,
874                    pCreateInfo->stage.module);
875    if (alloc == NULL)
876       alloc = &device->vk.alloc;
877    pipeline->device = device;
878    pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
879    pipeline->force_min_sample = false;
880 
881    deep_copy_compute_create_info(&pipeline->compute_create_info, pCreateInfo);
882    pipeline->is_compute_pipeline = true;
883 
884    lvp_shader_compile_to_ir(pipeline, module,
885                             pCreateInfo->stage.pName,
886                             MESA_SHADER_COMPUTE,
887                             pCreateInfo->stage.pSpecializationInfo);
888    lvp_pipeline_compile(pipeline, MESA_SHADER_COMPUTE);
889    return VK_SUCCESS;
890 }
891 
892 static VkResult
lvp_compute_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)893 lvp_compute_pipeline_create(
894    VkDevice _device,
895    VkPipelineCache _cache,
896    const VkComputePipelineCreateInfo *pCreateInfo,
897    const VkAllocationCallbacks *pAllocator,
898    VkPipeline *pPipeline)
899 {
900    LVP_FROM_HANDLE(lvp_device, device, _device);
901    LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
902    struct lvp_pipeline *pipeline;
903    VkResult result;
904 
905    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);
906 
907    pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
908                          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);
914    result = lvp_compute_pipeline_init(pipeline, device, cache, pCreateInfo,
915                                       pAllocator);
916    if (result != VK_SUCCESS) {
917       vk_free2(&device->vk.alloc, pAllocator, pipeline);
918       return result;
919    }
920 
921    *pPipeline = lvp_pipeline_to_handle(pipeline);
922 
923    return VK_SUCCESS;
924 }
925 
lvp_CreateComputePipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)926 VkResult lvp_CreateComputePipelines(
927    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;
939       r = lvp_compute_pipeline_create(_device,
940                                       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 }
951