2 * Copyright © 2019 Red Hat.
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:
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
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
24 #include "val_private.h"
26 #include "glsl_types.h"
27 #include "spirv/nir_spirv.h"
28 #include "nir/nir_builder.h"
29 #include "val_lower_vulkan_resource.h"
30 #include "pipe/p_state.h"
31 #include "pipe/p_context.h"
33 #define SPIR_V_MAGIC_NUMBER 0x07230203
35 VkResult
val_CreateShaderModule(
37 const VkShaderModuleCreateInfo
* pCreateInfo
,
38 const VkAllocationCallbacks
* pAllocator
,
39 VkShaderModule
* pShaderModule
)
41 VAL_FROM_HANDLE(val_device
, device
, _device
);
42 struct val_shader_module
*module
;
44 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
);
45 assert(pCreateInfo
->flags
== 0);
47 module
= vk_alloc2(&device
->alloc
, pAllocator
,
48 sizeof(*module
) + pCreateInfo
->codeSize
, 8,
49 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
51 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
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
);
58 *pShaderModule
= val_shader_module_to_handle(module
);
64 void val_DestroyShaderModule(
66 VkShaderModule _module
,
67 const VkAllocationCallbacks
* pAllocator
)
69 VAL_FROM_HANDLE(val_device
, device
, _device
);
70 VAL_FROM_HANDLE(val_shader_module
, module
, _module
);
74 vk_object_base_finish(&module
->base
);
75 vk_free2(&device
->alloc
, pAllocator
, module
);
78 void val_DestroyPipeline(
81 const VkAllocationCallbacks
* pAllocator
)
83 VAL_FROM_HANDLE(val_device
, device
, _device
);
84 VAL_FROM_HANDLE(val_pipeline
, pipeline
, _pipeline
);
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
]);
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
);
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
);
116 free((void *)pipeline
->graphics_create_info
.pViewportState
);
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
);
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
->alloc
, pAllocator
, pipeline
);
137 deep_copy_shader_stage(struct VkPipelineShaderStageCreateInfo
*dst
,
138 const struct VkPipelineShaderStageCreateInfo
*src
)
140 dst
->sType
= src
->sType
;
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
) +
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
;
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
;
168 deep_copy_vertex_input_state(struct VkPipelineVertexInputStateCreateInfo
*dst
,
169 const struct VkPipelineVertexInputStateCreateInfo
*src
)
172 VkVertexInputBindingDescription
*dst_binding_descriptions
;
173 VkVertexInputAttributeDescription
*dst_attrib_descriptions
;
174 dst
->sType
= src
->sType
;
176 dst
->flags
= src
->flags
;
177 dst
->vertexBindingDescriptionCount
= src
->vertexBindingDescriptionCount
;
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
));
185 dst
->pVertexBindingDescriptions
= dst_binding_descriptions
;
187 dst
->vertexAttributeDescriptionCount
= src
->vertexAttributeDescriptionCount
;
189 dst_attrib_descriptions
= malloc(src
->vertexAttributeDescriptionCount
* sizeof(VkVertexInputAttributeDescription
));
190 if (!dst_attrib_descriptions
)
191 return VK_ERROR_OUT_OF_HOST_MEMORY
;
193 for (i
= 0; i
< dst
->vertexAttributeDescriptionCount
; i
++) {
194 memcpy(&dst_attrib_descriptions
[i
], &src
->pVertexAttributeDescriptions
[i
], sizeof(VkVertexInputAttributeDescription
));
196 dst
->pVertexAttributeDescriptions
= dst_attrib_descriptions
;
201 deep_copy_viewport_state(VkPipelineViewportStateCreateInfo
*dst
,
202 const VkPipelineViewportStateCreateInfo
*src
)
205 VkViewport
*viewports
;
207 dst
->sType
= src
->sType
;
208 dst
->pNext
= src
->pNext
;
210 dst
->flags
= src
->flags
;
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
;
218 dst
->pViewports
= NULL
;
219 dst
->viewportCount
= src
->viewportCount
;
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
;
227 dst
->pScissors
= NULL
;
228 dst
->scissorCount
= src
->scissorCount
;
234 deep_copy_color_blend_state(VkPipelineColorBlendStateCreateInfo
*dst
,
235 const VkPipelineColorBlendStateCreateInfo
*src
)
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
;
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
;
249 memcpy(&dst
->blendConstants
, &src
->blendConstants
, sizeof(float) * 4);
255 deep_copy_dynamic_state(VkPipelineDynamicStateCreateInfo
*dst
,
256 const VkPipelineDynamicStateCreateInfo
*src
)
258 VkDynamicState
*dynamic_states
;
259 dst
->sType
= src
->sType
;
260 dst
->pNext
= src
->pNext
;
261 dst
->flags
= src
->flags
;
263 dynamic_states
= malloc(src
->dynamicStateCount
* sizeof(VkDynamicState
));
265 return VK_ERROR_OUT_OF_HOST_MEMORY
;
267 memcpy(dynamic_states
, src
->pDynamicStates
, src
->dynamicStateCount
* sizeof(VkDynamicState
));
268 dst
->dynamicStateCount
= src
->dynamicStateCount
;
269 dst
->pDynamicStates
= dynamic_states
;
274 deep_copy_graphics_create_info(VkGraphicsPipelineCreateInfo
*dst
,
275 const VkGraphicsPipelineCreateInfo
*src
)
279 VkPipelineShaderStageCreateInfo
*stages
;
280 VkPipelineVertexInputStateCreateInfo
*vertex_input
;
281 VkPipelineInputAssemblyStateCreateInfo
*input_assembly
;
282 VkPipelineRasterizationStateCreateInfo
* raster_state
;
284 dst
->sType
= src
->sType
;
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
;
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
)
301 dst
->pStages
= stages
;
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
)
309 dst
->pVertexInputState
= vertex_input
;
311 /* pInputAssemblyState */
312 input_assembly
= malloc(sizeof(VkPipelineInputAssemblyStateCreateInfo
));
314 return VK_ERROR_OUT_OF_HOST_MEMORY
;
315 memcpy(input_assembly
, src
->pInputAssemblyState
, sizeof(VkPipelineInputAssemblyStateCreateInfo
));
316 dst
->pInputAssemblyState
= input_assembly
;
318 /* pTessellationState */
319 if (src
->pTessellationState
) {
320 VkPipelineTessellationStateCreateInfo
*tess_state
;
321 tess_state
= malloc(sizeof(VkPipelineTessellationStateCreateInfo
));
323 return VK_ERROR_OUT_OF_HOST_MEMORY
;
324 memcpy(tess_state
, src
->pTessellationState
, sizeof(VkPipelineTessellationStateCreateInfo
));
325 dst
->pTessellationState
= tess_state
;
330 if (src
->pViewportState
) {
331 VkPipelineViewportStateCreateInfo
*viewport_state
;
332 viewport_state
= malloc(sizeof(VkPipelineViewportStateCreateInfo
));
334 return VK_ERROR_OUT_OF_HOST_MEMORY
;
335 deep_copy_viewport_state(viewport_state
, src
->pViewportState
);
336 dst
->pViewportState
= viewport_state
;
338 dst
->pViewportState
= NULL
;
340 /* pRasterizationState */
341 raster_state
= malloc(sizeof(VkPipelineRasterizationStateCreateInfo
));
343 return VK_ERROR_OUT_OF_HOST_MEMORY
;
344 memcpy(raster_state
, src
->pRasterizationState
, sizeof(VkPipelineRasterizationStateCreateInfo
));
345 dst
->pRasterizationState
= raster_state
;
347 /* pMultisampleState */
348 if (src
->pMultisampleState
) {
349 VkPipelineMultisampleStateCreateInfo
* ms_state
;
350 ms_state
= malloc(sizeof(VkPipelineMultisampleStateCreateInfo
) + sizeof(VkSampleMask
));
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
;
360 dst
->pMultisampleState
= ms_state
;
362 dst
->pMultisampleState
= NULL
;
364 /* pDepthStencilState */
365 if (src
->pDepthStencilState
) {
366 VkPipelineDepthStencilStateCreateInfo
* ds_state
;
368 ds_state
= malloc(sizeof(VkPipelineDepthStencilStateCreateInfo
));
370 return VK_ERROR_OUT_OF_HOST_MEMORY
;
371 memcpy(ds_state
, src
->pDepthStencilState
, sizeof(VkPipelineDepthStencilStateCreateInfo
));
372 dst
->pDepthStencilState
= ds_state
;
374 dst
->pDepthStencilState
= NULL
;
376 /* pColorBlendState */
377 if (src
->pColorBlendState
) {
378 VkPipelineColorBlendStateCreateInfo
* cb_state
;
380 cb_state
= malloc(sizeof(VkPipelineColorBlendStateCreateInfo
));
382 return VK_ERROR_OUT_OF_HOST_MEMORY
;
383 deep_copy_color_blend_state(cb_state
, src
->pColorBlendState
);
384 dst
->pColorBlendState
= cb_state
;
386 dst
->pColorBlendState
= NULL
;
388 if (src
->pDynamicState
) {
389 VkPipelineDynamicStateCreateInfo
* dyn_state
;
392 dyn_state
= malloc(sizeof(VkPipelineDynamicStateCreateInfo
));
394 return VK_ERROR_OUT_OF_HOST_MEMORY
;
395 deep_copy_dynamic_state(dyn_state
, src
->pDynamicState
);
396 dst
->pDynamicState
= dyn_state
;
398 dst
->pDynamicState
= NULL
;
404 deep_copy_compute_create_info(VkComputePipelineCreateInfo
*dst
,
405 const VkComputePipelineCreateInfo
*src
)
408 dst
->sType
= src
->sType
;
410 dst
->flags
= src
->flags
;
411 dst
->layout
= src
->layout
;
412 dst
->basePipelineHandle
= src
->basePipelineHandle
;
413 dst
->basePipelineIndex
= src
->basePipelineIndex
;
415 result
= deep_copy_shader_stage(&dst
->stage
, &src
->stage
);
416 if (result
!= VK_SUCCESS
)
421 static inline unsigned
422 st_shader_stage_to_ptarget(gl_shader_stage 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
;
441 assert(!"should not be reached");
442 return PIPE_SHADER_VERTEX
;
446 shared_var_info(const struct glsl_type
*type
, unsigned *size
, unsigned *align
)
448 assert(glsl_type_is_vector_or_scalar(type
));
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
,
457 #define OPT(pass, ...) ({ \
458 bool this_progress = false; \
459 NIR_PASS(this_progress, nir, pass, ##__VA_ARGS__); \
466 val_shader_compile_to_ir(struct val_pipeline
*pipeline
,
467 struct val_shader_module
*module
,
468 const char *entrypoint_name
,
469 gl_shader_stage stage
,
470 const VkSpecializationInfo
*spec_info
)
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
));
475 uint32_t *spirv
= (uint32_t *) module
->data
;
476 assert(spirv
[0] == SPIR_V_MAGIC_NUMBER
);
477 assert(module
->size
% 4 == 0);
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
];
487 spec_info
->pData
+ entry
.offset
;
488 assert((const void *)(data
+ entry
.size
) <=
489 spec_info
->pData
+ spec_info
->dataSize
);
491 spec_entries
[i
].id
= entry
.constantID
;
492 switch (entry
.size
) {
494 spec_entries
[i
].value
.u64
= *(const uint64_t *)data
;
497 spec_entries
[i
].value
.u32
= *(const uint32_t *)data
;
500 spec_entries
[i
].value
.u16
= *(const uint16_t *)data
;
503 spec_entries
[i
].value
.u8
= *(const uint8_t *)data
;
506 assert(!"Invalid spec constant size");
511 struct val_device
*pdevice
= pipeline
->device
;
512 const struct spirv_to_nir_options spirv_options
= {
513 .environment
= NIR_SPIRV_VULKAN
,
514 .lower_ubo_ssbo_access_to_offsets
= true,
516 .float64
= (pdevice
->pscreen
->get_param(pdevice
->pscreen
, PIPE_CAP_DOUBLES
) == 1),
518 .int64
= (pdevice
->pscreen
->get_param(pdevice
->pscreen
, PIPE_CAP_INT64
) == 1),
519 .tessellation
= true,
520 .image_ms_array
= true,
521 .storage_image_ms
= true,
522 .geometry_streams
= true,
523 .storage_16bit
= true,
524 .variable_pointers
= true,
526 .ubo_addr_format
= nir_address_format_32bit_index_offset
,
527 .ssbo_addr_format
= nir_address_format_32bit_index_offset
,
528 .phys_ssbo_addr_format
= nir_address_format_64bit_global
,
529 .push_const_addr_format
= nir_address_format_logical
,
530 .shared_addr_format
= nir_address_format_32bit_offset
,
531 .frag_coord_is_sysval
= false,
534 nir
= spirv_to_nir(spirv
, module
->size
/ 4,
535 spec_entries
, num_spec_entries
,
536 stage
, entrypoint_name
, &spirv_options
, drv_options
);
538 nir_validate_shader(nir
, NULL
);
542 NIR_PASS_V(nir
, nir_lower_variable_initializers
, nir_var_function_temp
);
543 NIR_PASS_V(nir
, nir_lower_returns
);
544 NIR_PASS_V(nir
, nir_inline_functions
);
545 NIR_PASS_V(nir
, nir_copy_prop
);
546 NIR_PASS_V(nir
, nir_opt_deref
);
548 /* Pick off the single entrypoint that we want */
549 foreach_list_typed_safe(nir_function
, func
, node
, &nir
->functions
) {
550 if (!func
->is_entrypoint
)
551 exec_node_remove(&func
->node
);
553 assert(exec_list_length(&nir
->functions
) == 1);
555 NIR_PASS_V(nir
, nir_lower_variable_initializers
, ~0);
556 NIR_PASS_V(nir
, nir_split_var_copies
);
557 NIR_PASS_V(nir
, nir_split_per_member_structs
);
559 NIR_PASS_V(nir
, nir_remove_dead_variables
,
560 nir_var_shader_in
| nir_var_shader_out
| nir_var_system_value
, NULL
);
562 if (stage
== MESA_SHADER_FRAGMENT
)
563 val_lower_input_attachments(nir
, false);
564 NIR_PASS_V(nir
, nir_lower_system_values
);
566 NIR_PASS_V(nir
, nir_lower_clip_cull_distance_arrays
);
567 nir_remove_dead_variables(nir
, nir_var_uniform
, NULL
);
569 val_lower_pipeline_layout(pipeline
->device
, pipeline
->layout
, nir
);
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
);
575 if (nir
->info
.stage
== MESA_SHADER_COMPUTE
) {
576 NIR_PASS_V(nir
, nir_lower_vars_to_explicit_types
, nir_var_mem_shared
, shared_var_info
);
577 NIR_PASS_V(nir
, nir_lower_explicit_io
, nir_var_mem_shared
, nir_address_format_32bit_offset
);
580 NIR_PASS_V(nir
, nir_remove_dead_variables
, nir_var_shader_temp
, NULL
);
582 if (nir
->info
.stage
== MESA_SHADER_VERTEX
||
583 nir
->info
.stage
== MESA_SHADER_GEOMETRY
) {
584 NIR_PASS_V(nir
, nir_lower_io_arrays_to_elements_no_indirects
, false);
585 } else if (nir
->info
.stage
== MESA_SHADER_FRAGMENT
) {
586 NIR_PASS_V(nir
, nir_lower_io_arrays_to_elements_no_indirects
, true);
592 progress
|= OPT(nir_lower_flrp
, 32|64, true, false);
593 progress
|= OPT(nir_split_array_vars
, nir_var_function_temp
);
594 progress
|= OPT(nir_shrink_vec_array_vars
, nir_var_function_temp
);
595 progress
|= OPT(nir_opt_deref
);
596 progress
|= OPT(nir_lower_vars_to_ssa
);
598 progress
|= nir_copy_prop(nir
);
599 progress
|= nir_opt_dce(nir
);
600 progress
|= nir_opt_dead_cf(nir
);
601 progress
|= nir_opt_cse(nir
);
602 progress
|= nir_opt_algebraic(nir
);
603 progress
|= nir_opt_constant_folding(nir
);
604 progress
|= nir_opt_undef(nir
);
606 progress
|= nir_opt_deref(nir
);
607 progress
|= nir_lower_alu_to_scalar(nir
, NULL
, NULL
);
610 nir_lower_var_copies(nir
);
611 nir_remove_dead_variables(nir
, nir_var_function_temp
, NULL
);
613 nir_validate_shader(nir
, NULL
);
614 nir_shader_gather_info(nir
, nir_shader_get_entrypoint(nir
));
616 if (nir
->info
.stage
!= MESA_SHADER_VERTEX
)
617 nir_assign_io_var_locations(nir
, nir_var_shader_in
, &nir
->num_inputs
, nir
->info
.stage
);
619 nir
->num_inputs
= util_last_bit64(nir
->info
.inputs_read
);
620 nir_foreach_shader_in_variable(var
, nir
) {
621 var
->data
.driver_location
= var
->data
.location
- VERT_ATTRIB_GENERIC0
;
624 nir_assign_io_var_locations(nir
, nir_var_shader_out
, &nir
->num_outputs
,
626 pipeline
->pipeline_nir
[stage
] = nir
;
629 static void fill_shader_prog(struct pipe_shader_state
*state
, gl_shader_stage stage
, struct val_pipeline
*pipeline
)
631 state
->type
= PIPE_SHADER_IR_NIR
;
632 state
->ir
.nir
= pipeline
->pipeline_nir
[stage
];
636 merge_tess_info(struct shader_info
*tes_info
,
637 const struct shader_info
*tcs_info
)
639 /* The Vulkan 1.0.38 spec, section 21.1 Tessellator says:
641 * "PointMode. Controls generation of points rather than triangles
642 * or lines. This functionality defaults to disabled, and is
643 * enabled if either shader stage includes the execution mode.
645 * and about Triangles, Quads, IsoLines, VertexOrderCw, VertexOrderCcw,
646 * PointMode, SpacingEqual, SpacingFractionalEven, SpacingFractionalOdd,
647 * and OutputVertices, it says:
649 * "One mode must be set in at least one of the tessellation
652 * So, the fields can be set in either the TCS or TES, but they must
653 * agree if set in both. Our backend looks at TES, so bitwise-or in
654 * the values from the TCS.
656 assert(tcs_info
->tess
.tcs_vertices_out
== 0 ||
657 tes_info
->tess
.tcs_vertices_out
== 0 ||
658 tcs_info
->tess
.tcs_vertices_out
== tes_info
->tess
.tcs_vertices_out
);
659 tes_info
->tess
.tcs_vertices_out
|= tcs_info
->tess
.tcs_vertices_out
;
661 assert(tcs_info
->tess
.spacing
== TESS_SPACING_UNSPECIFIED
||
662 tes_info
->tess
.spacing
== TESS_SPACING_UNSPECIFIED
||
663 tcs_info
->tess
.spacing
== tes_info
->tess
.spacing
);
664 tes_info
->tess
.spacing
|= tcs_info
->tess
.spacing
;
666 assert(tcs_info
->tess
.primitive_mode
== 0 ||
667 tes_info
->tess
.primitive_mode
== 0 ||
668 tcs_info
->tess
.primitive_mode
== tes_info
->tess
.primitive_mode
);
669 tes_info
->tess
.primitive_mode
|= tcs_info
->tess
.primitive_mode
;
670 tes_info
->tess
.ccw
|= tcs_info
->tess
.ccw
;
671 tes_info
->tess
.point_mode
|= tcs_info
->tess
.point_mode
;
674 static gl_shader_stage
675 val_shader_stage(VkShaderStageFlagBits stage
)
678 case VK_SHADER_STAGE_VERTEX_BIT
:
679 return MESA_SHADER_VERTEX
;
680 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
:
681 return MESA_SHADER_TESS_CTRL
;
682 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
:
683 return MESA_SHADER_TESS_EVAL
;
684 case VK_SHADER_STAGE_GEOMETRY_BIT
:
685 return MESA_SHADER_GEOMETRY
;
686 case VK_SHADER_STAGE_FRAGMENT_BIT
:
687 return MESA_SHADER_FRAGMENT
;
688 case VK_SHADER_STAGE_COMPUTE_BIT
:
689 return MESA_SHADER_COMPUTE
;
691 unreachable("invalid VkShaderStageFlagBits");
692 return MESA_SHADER_NONE
;
697 val_pipeline_compile(struct val_pipeline
*pipeline
,
698 gl_shader_stage stage
)
700 struct val_device
*device
= pipeline
->device
;
701 device
->physical_device
->pscreen
->finalize_nir(device
->physical_device
->pscreen
, pipeline
->pipeline_nir
[stage
], true);
702 if (stage
== MESA_SHADER_COMPUTE
) {
703 struct pipe_compute_state shstate
= {};
704 shstate
.prog
= (void *)pipeline
->pipeline_nir
[MESA_SHADER_COMPUTE
];
705 shstate
.ir_type
= PIPE_SHADER_IR_NIR
;
706 shstate
.req_local_mem
= pipeline
->pipeline_nir
[MESA_SHADER_COMPUTE
]->info
.cs
.shared_size
;
707 pipeline
->shader_cso
[PIPE_SHADER_COMPUTE
] = device
->queue
.ctx
->create_compute_state(device
->queue
.ctx
, &shstate
);
709 struct pipe_shader_state shstate
= {};
710 fill_shader_prog(&shstate
, stage
, pipeline
);
712 case MESA_SHADER_FRAGMENT
:
713 pipeline
->shader_cso
[PIPE_SHADER_FRAGMENT
] = device
->queue
.ctx
->create_fs_state(device
->queue
.ctx
, &shstate
);
715 case MESA_SHADER_VERTEX
:
716 pipeline
->shader_cso
[PIPE_SHADER_VERTEX
] = device
->queue
.ctx
->create_vs_state(device
->queue
.ctx
, &shstate
);
718 case MESA_SHADER_GEOMETRY
:
719 pipeline
->shader_cso
[PIPE_SHADER_GEOMETRY
] = device
->queue
.ctx
->create_gs_state(device
->queue
.ctx
, &shstate
);
721 case MESA_SHADER_TESS_CTRL
:
722 pipeline
->shader_cso
[PIPE_SHADER_TESS_CTRL
] = device
->queue
.ctx
->create_tcs_state(device
->queue
.ctx
, &shstate
);
724 case MESA_SHADER_TESS_EVAL
:
725 pipeline
->shader_cso
[PIPE_SHADER_TESS_EVAL
] = device
->queue
.ctx
->create_tes_state(device
->queue
.ctx
, &shstate
);
728 unreachable("illegal shader");
736 val_graphics_pipeline_init(struct val_pipeline
*pipeline
,
737 struct val_device
*device
,
738 struct val_pipeline_cache
*cache
,
739 const VkGraphicsPipelineCreateInfo
*pCreateInfo
,
740 const VkAllocationCallbacks
*alloc
)
743 alloc
= &device
->alloc
;
744 pipeline
->device
= device
;
745 pipeline
->layout
= val_pipeline_layout_from_handle(pCreateInfo
->layout
);
746 pipeline
->force_min_sample
= false;
748 /* recreate createinfo */
749 deep_copy_graphics_create_info(&pipeline
->graphics_create_info
, pCreateInfo
);
750 pipeline
->is_compute_pipeline
= false;
752 for (uint32_t i
= 0; i
< pCreateInfo
->stageCount
; i
++) {
753 VAL_FROM_HANDLE(val_shader_module
, module
,
754 pCreateInfo
->pStages
[i
].module
);
755 gl_shader_stage stage
= val_shader_stage(pCreateInfo
->pStages
[i
].stage
);
756 val_shader_compile_to_ir(pipeline
, module
,
757 pCreateInfo
->pStages
[i
].pName
,
759 pCreateInfo
->pStages
[i
].pSpecializationInfo
);
762 if (pipeline
->pipeline_nir
[MESA_SHADER_FRAGMENT
]) {
763 if (pipeline
->pipeline_nir
[MESA_SHADER_FRAGMENT
]->info
.fs
.uses_sample_qualifier
||
764 pipeline
->pipeline_nir
[MESA_SHADER_FRAGMENT
]->info
.system_values_read
& (SYSTEM_BIT_SAMPLE_ID
|
765 SYSTEM_BIT_SAMPLE_POS
))
766 pipeline
->force_min_sample
= true;
768 if (pipeline
->pipeline_nir
[MESA_SHADER_TESS_CTRL
]) {
769 nir_lower_patch_vertices(pipeline
->pipeline_nir
[MESA_SHADER_TESS_EVAL
], pipeline
->pipeline_nir
[MESA_SHADER_TESS_CTRL
]->info
.tess
.tcs_vertices_out
, NULL
);
770 merge_tess_info(&pipeline
->pipeline_nir
[MESA_SHADER_TESS_EVAL
]->info
, &pipeline
->pipeline_nir
[MESA_SHADER_TESS_CTRL
]->info
);
771 pipeline
->pipeline_nir
[MESA_SHADER_TESS_EVAL
]->info
.tess
.ccw
= !pipeline
->pipeline_nir
[MESA_SHADER_TESS_EVAL
]->info
.tess
.ccw
;
775 bool has_fragment_shader
= false;
776 for (uint32_t i
= 0; i
< pCreateInfo
->stageCount
; i
++) {
777 gl_shader_stage stage
= val_shader_stage(pCreateInfo
->pStages
[i
].stage
);
778 val_pipeline_compile(pipeline
, stage
);
779 if (stage
== MESA_SHADER_FRAGMENT
)
780 has_fragment_shader
= true;
783 if (has_fragment_shader
== false) {
784 /* create a dummy fragment shader for this pipeline. */
787 nir_builder_init_simple_shader(&b
, NULL
, MESA_SHADER_FRAGMENT
, NULL
);
788 b
.shader
->info
.name
= ralloc_strdup(b
.shader
, "dummy_frag");
790 pipeline
->pipeline_nir
[MESA_SHADER_FRAGMENT
] = b
.shader
;
791 struct pipe_shader_state shstate
= {};
792 shstate
.type
= PIPE_SHADER_IR_NIR
;
793 shstate
.ir
.nir
= pipeline
->pipeline_nir
[MESA_SHADER_FRAGMENT
];
794 pipeline
->shader_cso
[PIPE_SHADER_FRAGMENT
] = device
->queue
.ctx
->create_fs_state(device
->queue
.ctx
, &shstate
);
800 val_graphics_pipeline_create(
802 VkPipelineCache _cache
,
803 const VkGraphicsPipelineCreateInfo
*pCreateInfo
,
804 const VkAllocationCallbacks
*pAllocator
,
805 VkPipeline
*pPipeline
)
807 VAL_FROM_HANDLE(val_device
, device
, _device
);
808 VAL_FROM_HANDLE(val_pipeline_cache
, cache
, _cache
);
809 struct val_pipeline
*pipeline
;
812 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
);
814 pipeline
= vk_zalloc2(&device
->alloc
, pAllocator
, sizeof(*pipeline
), 8,
815 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
816 if (pipeline
== NULL
)
817 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
819 vk_object_base_init(&device
->vk
, &pipeline
->base
,
820 VK_OBJECT_TYPE_PIPELINE
);
821 result
= val_graphics_pipeline_init(pipeline
, device
, cache
, pCreateInfo
,
823 if (result
!= VK_SUCCESS
) {
824 vk_free2(&device
->alloc
, pAllocator
, pipeline
);
828 *pPipeline
= val_pipeline_to_handle(pipeline
);
833 VkResult
val_CreateGraphicsPipelines(
835 VkPipelineCache pipelineCache
,
837 const VkGraphicsPipelineCreateInfo
* pCreateInfos
,
838 const VkAllocationCallbacks
* pAllocator
,
839 VkPipeline
* pPipelines
)
841 VkResult result
= VK_SUCCESS
;
844 for (; i
< count
; i
++) {
846 r
= val_graphics_pipeline_create(_device
,
849 pAllocator
, &pPipelines
[i
]);
850 if (r
!= VK_SUCCESS
) {
852 pPipelines
[i
] = VK_NULL_HANDLE
;
860 val_compute_pipeline_init(struct val_pipeline
*pipeline
,
861 struct val_device
*device
,
862 struct val_pipeline_cache
*cache
,
863 const VkComputePipelineCreateInfo
*pCreateInfo
,
864 const VkAllocationCallbacks
*alloc
)
866 VAL_FROM_HANDLE(val_shader_module
, module
,
867 pCreateInfo
->stage
.module
);
869 alloc
= &device
->alloc
;
870 pipeline
->device
= device
;
871 pipeline
->layout
= val_pipeline_layout_from_handle(pCreateInfo
->layout
);
872 pipeline
->force_min_sample
= false;
874 deep_copy_compute_create_info(&pipeline
->compute_create_info
, pCreateInfo
);
875 pipeline
->is_compute_pipeline
= true;
877 val_shader_compile_to_ir(pipeline
, module
,
878 pCreateInfo
->stage
.pName
,
880 pCreateInfo
->stage
.pSpecializationInfo
);
881 val_pipeline_compile(pipeline
, MESA_SHADER_COMPUTE
);
886 val_compute_pipeline_create(
888 VkPipelineCache _cache
,
889 const VkComputePipelineCreateInfo
*pCreateInfo
,
890 const VkAllocationCallbacks
*pAllocator
,
891 VkPipeline
*pPipeline
)
893 VAL_FROM_HANDLE(val_device
, device
, _device
);
894 VAL_FROM_HANDLE(val_pipeline_cache
, cache
, _cache
);
895 struct val_pipeline
*pipeline
;
898 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
);
900 pipeline
= vk_zalloc2(&device
->alloc
, pAllocator
, sizeof(*pipeline
), 8,
901 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
902 if (pipeline
== NULL
)
903 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
905 vk_object_base_init(&device
->vk
, &pipeline
->base
,
906 VK_OBJECT_TYPE_PIPELINE
);
907 result
= val_compute_pipeline_init(pipeline
, device
, cache
, pCreateInfo
,
909 if (result
!= VK_SUCCESS
) {
910 vk_free2(&device
->alloc
, pAllocator
, pipeline
);
914 *pPipeline
= val_pipeline_to_handle(pipeline
);
919 VkResult
val_CreateComputePipelines(
921 VkPipelineCache pipelineCache
,
923 const VkComputePipelineCreateInfo
* pCreateInfos
,
924 const VkAllocationCallbacks
* pAllocator
,
925 VkPipeline
* pPipelines
)
927 VkResult result
= VK_SUCCESS
;
930 for (; i
< count
; i
++) {
932 r
= val_compute_pipeline_create(_device
,
935 pAllocator
, &pPipelines
[i
]);
936 if (r
!= VK_SUCCESS
) {
938 pPipelines
[i
] = VK_NULL_HANDLE
;