1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright 2019 Google LLC
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker *
5*61046927SAndroid Build Coastguard Worker * based in part on anv and radv which are:
6*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
7*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Red Hat.
8*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Bas Nieuwenhuizen
9*61046927SAndroid Build Coastguard Worker */
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "vn_pipeline.h"
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_pipeline.h"
14*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_pipeline_cache.h"
15*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_pipeline_layout.h"
16*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_shader_module.h"
17*61046927SAndroid Build Coastguard Worker
18*61046927SAndroid Build Coastguard Worker #include "vn_descriptor_set.h"
19*61046927SAndroid Build Coastguard Worker #include "vn_device.h"
20*61046927SAndroid Build Coastguard Worker #include "vn_physical_device.h"
21*61046927SAndroid Build Coastguard Worker #include "vn_render_pass.h"
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker /**
24*61046927SAndroid Build Coastguard Worker * Fields in the VkGraphicsPipelineCreateInfo pNext chain that we must track
25*61046927SAndroid Build Coastguard Worker * to determine which fields are valid and which must be erased.
26*61046927SAndroid Build Coastguard Worker */
27*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_info_self {
28*61046927SAndroid Build Coastguard Worker union {
29*61046927SAndroid Build Coastguard Worker /* Bitmask exists for testing if any field is set. */
30*61046927SAndroid Build Coastguard Worker uint32_t mask;
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker /* Group the fixes by Vulkan struct. Within each group, sort by struct
33*61046927SAndroid Build Coastguard Worker * order.
34*61046927SAndroid Build Coastguard Worker */
35*61046927SAndroid Build Coastguard Worker struct {
36*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pStages */
37*61046927SAndroid Build Coastguard Worker bool shader_stages : 1;
38*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pVertexInputState */
39*61046927SAndroid Build Coastguard Worker bool vertex_input_state : 1;
40*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pInputAssemblyState */
41*61046927SAndroid Build Coastguard Worker bool input_assembly_state : 1;
42*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pTessellationState */
43*61046927SAndroid Build Coastguard Worker bool tessellation_state : 1;
44*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pViewportState */
45*61046927SAndroid Build Coastguard Worker bool viewport_state : 1;
46*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pRasterizationState */
47*61046927SAndroid Build Coastguard Worker bool rasterization_state : 1;
48*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pMultisampleState */
49*61046927SAndroid Build Coastguard Worker bool multisample_state : 1;
50*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pDepthStencilState */
51*61046927SAndroid Build Coastguard Worker bool depth_stencil_state : 1;
52*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::pColorBlendState */
53*61046927SAndroid Build Coastguard Worker bool color_blend_state : 1;
54*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::layout */
55*61046927SAndroid Build Coastguard Worker bool pipeline_layout : 1;
56*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::renderPass */
57*61046927SAndroid Build Coastguard Worker bool render_pass : 1;
58*61046927SAndroid Build Coastguard Worker /** VkGraphicsPipelineCreateInfo::basePipelineHandle */
59*61046927SAndroid Build Coastguard Worker bool base_pipeline_handle : 1;
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker /** VkPipelineViewportStateCreateInfo::pViewports */
62*61046927SAndroid Build Coastguard Worker bool viewport_state_viewports : 1;
63*61046927SAndroid Build Coastguard Worker /** VkPipelineViewportStateCreateInfo::pScissors */
64*61046927SAndroid Build Coastguard Worker bool viewport_state_scissors : 1;
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker /** VkPipelineMultisampleStateCreateInfo::pSampleMask */
67*61046927SAndroid Build Coastguard Worker bool multisample_state_sample_mask : 1;
68*61046927SAndroid Build Coastguard Worker };
69*61046927SAndroid Build Coastguard Worker };
70*61046927SAndroid Build Coastguard Worker };
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct vn_graphics_pipeline_info_self) ==
73*61046927SAndroid Build Coastguard Worker sizeof(((struct vn_graphics_pipeline_info_self){}).mask),
74*61046927SAndroid Build Coastguard Worker "vn_graphics_pipeline_create_info_self::mask is too small");
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker /**
77*61046927SAndroid Build Coastguard Worker * Fields in the VkGraphicsPipelineCreateInfo pNext chain that we must track
78*61046927SAndroid Build Coastguard Worker * to determine which fields are valid and which must be erased.
79*61046927SAndroid Build Coastguard Worker */
80*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_info_pnext {
81*61046927SAndroid Build Coastguard Worker union {
82*61046927SAndroid Build Coastguard Worker /* Bitmask exists for testing if any field is set. */
83*61046927SAndroid Build Coastguard Worker uint32_t mask;
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker /* Group the fixes by Vulkan struct. Within each group, sort by struct
86*61046927SAndroid Build Coastguard Worker * order.
87*61046927SAndroid Build Coastguard Worker */
88*61046927SAndroid Build Coastguard Worker struct {
89*61046927SAndroid Build Coastguard Worker /** VkPipelineRenderingCreateInfo, all format fields */
90*61046927SAndroid Build Coastguard Worker bool rendering_info_formats : 1;
91*61046927SAndroid Build Coastguard Worker };
92*61046927SAndroid Build Coastguard Worker };
93*61046927SAndroid Build Coastguard Worker };
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct vn_graphics_pipeline_info_pnext) ==
96*61046927SAndroid Build Coastguard Worker sizeof(((struct vn_graphics_pipeline_info_pnext){}).mask),
97*61046927SAndroid Build Coastguard Worker "vn_graphics_pipeline_create_info_pnext::mask is too small");
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker /**
100*61046927SAndroid Build Coastguard Worker * Description of fixes needed for a single VkGraphicsPipelineCreateInfo
101*61046927SAndroid Build Coastguard Worker * pNext chain.
102*61046927SAndroid Build Coastguard Worker */
103*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_desc {
104*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_info_self self;
105*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_info_pnext pnext;
106*61046927SAndroid Build Coastguard Worker };
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker /**
109*61046927SAndroid Build Coastguard Worker * Typesafe bitmask for VkGraphicsPipelineLibraryFlagsEXT. Named members
110*61046927SAndroid Build Coastguard Worker * reduce long lines.
111*61046927SAndroid Build Coastguard Worker *
112*61046927SAndroid Build Coastguard Worker * From the Vulkan 1.3.215 spec:
113*61046927SAndroid Build Coastguard Worker *
114*61046927SAndroid Build Coastguard Worker * The state required for a graphics pipeline is divided into vertex input
115*61046927SAndroid Build Coastguard Worker * state, pre-rasterization shader state, fragment shader state, and
116*61046927SAndroid Build Coastguard Worker * fragment output state.
117*61046927SAndroid Build Coastguard Worker */
118*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_library_state {
119*61046927SAndroid Build Coastguard Worker union {
120*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineLibraryFlagsEXT mask;
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker struct {
123*61046927SAndroid Build Coastguard Worker /** VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT */
124*61046927SAndroid Build Coastguard Worker bool vertex_input : 1;
125*61046927SAndroid Build Coastguard Worker /** VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT */
126*61046927SAndroid Build Coastguard Worker bool pre_raster_shaders : 1;
127*61046927SAndroid Build Coastguard Worker /** VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT */
128*61046927SAndroid Build Coastguard Worker bool fragment_shader : 1;
129*61046927SAndroid Build Coastguard Worker /** VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT */
130*61046927SAndroid Build Coastguard Worker bool fragment_output : 1;
131*61046927SAndroid Build Coastguard Worker };
132*61046927SAndroid Build Coastguard Worker };
133*61046927SAndroid Build Coastguard Worker };
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker /**
136*61046927SAndroid Build Coastguard Worker * Compact bitmask for the subset of graphics VkDynamicState that
137*61046927SAndroid Build Coastguard Worker * venus needs to track. Named members reduce long lines.
138*61046927SAndroid Build Coastguard Worker *
139*61046927SAndroid Build Coastguard Worker * We want a *compact* bitmask because enum VkDynamicState has large gaps due
140*61046927SAndroid Build Coastguard Worker * to extensions.
141*61046927SAndroid Build Coastguard Worker */
142*61046927SAndroid Build Coastguard Worker struct vn_graphics_dynamic_state {
143*61046927SAndroid Build Coastguard Worker union {
144*61046927SAndroid Build Coastguard Worker uint32_t mask;
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker struct {
147*61046927SAndroid Build Coastguard Worker /** VK_DYNAMIC_STATE_VERTEX_INPUT_EXT **/
148*61046927SAndroid Build Coastguard Worker bool vertex_input : 1;
149*61046927SAndroid Build Coastguard Worker /** VK_DYNAMIC_STATE_VIEWPORT */
150*61046927SAndroid Build Coastguard Worker bool viewport : 1;
151*61046927SAndroid Build Coastguard Worker /** VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT */
152*61046927SAndroid Build Coastguard Worker bool viewport_with_count : 1;
153*61046927SAndroid Build Coastguard Worker /** VK_DYNAMIC_STATE_SAMPLE_MASK_EXT */
154*61046927SAndroid Build Coastguard Worker bool sample_mask : 1;
155*61046927SAndroid Build Coastguard Worker /** VK_DYNAMIC_STATE_SCISSOR */
156*61046927SAndroid Build Coastguard Worker bool scissor : 1;
157*61046927SAndroid Build Coastguard Worker /** VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT */
158*61046927SAndroid Build Coastguard Worker bool scissor_with_count : 1;
159*61046927SAndroid Build Coastguard Worker /** VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE */
160*61046927SAndroid Build Coastguard Worker bool rasterizer_discard_enable : 1;
161*61046927SAndroid Build Coastguard Worker };
162*61046927SAndroid Build Coastguard Worker };
163*61046927SAndroid Build Coastguard Worker };
164*61046927SAndroid Build Coastguard Worker
165*61046927SAndroid Build Coastguard Worker /**
166*61046927SAndroid Build Coastguard Worker * Graphics pipeline state that Venus tracks to determine which fixes are
167*61046927SAndroid Build Coastguard Worker * required in the VkGraphicsPipelineCreateInfo pNext chain.
168*61046927SAndroid Build Coastguard Worker *
169*61046927SAndroid Build Coastguard Worker * This is the pipeline's fully linked state. That is, it includes the state
170*61046927SAndroid Build Coastguard Worker * provided directly in VkGraphicsPipelineCreateInfo and the state provided
171*61046927SAndroid Build Coastguard Worker * indirectly in VkPipelineLibraryCreateInfoKHR.
172*61046927SAndroid Build Coastguard Worker */
173*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_state {
174*61046927SAndroid Build Coastguard Worker /** The GPL state subsets that the pipeline provides. */
175*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_library_state gpl;
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Worker struct vn_graphics_dynamic_state dynamic;
178*61046927SAndroid Build Coastguard Worker VkShaderStageFlags shader_stages;
179*61046927SAndroid Build Coastguard Worker
180*61046927SAndroid Build Coastguard Worker struct vn_render_pass_state {
181*61046927SAndroid Build Coastguard Worker /**
182*61046927SAndroid Build Coastguard Worker * The attachment aspects accessed by the pipeline.
183*61046927SAndroid Build Coastguard Worker *
184*61046927SAndroid Build Coastguard Worker * Valid if and only if VK_IMAGE_ASPECT_METADATA_BIT is unset.
185*61046927SAndroid Build Coastguard Worker *
186*61046927SAndroid Build Coastguard Worker * In a complete pipeline, this must be valid (and may be empty). In
187*61046927SAndroid Build Coastguard Worker * a pipeline library, this may be invalid. We initialize this to be
188*61046927SAndroid Build Coastguard Worker * invalid, and it remains invalid until we read the attachment info in
189*61046927SAndroid Build Coastguard Worker * the VkGraphicsPipelineCreateInfo chain.
190*61046927SAndroid Build Coastguard Worker *
191*61046927SAndroid Build Coastguard Worker * The app provides the attachment info in
192*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo::renderPass or
193*61046927SAndroid Build Coastguard Worker * VkPipelineRenderingCreateInfo, but the validity of that info depends
194*61046927SAndroid Build Coastguard Worker * on VkGraphicsPipelineLibraryFlagsEXT.
195*61046927SAndroid Build Coastguard Worker */
196*61046927SAndroid Build Coastguard Worker VkImageAspectFlags attachment_aspects;
197*61046927SAndroid Build Coastguard Worker } render_pass;
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker /** VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable
200*61046927SAndroid Build Coastguard Worker *
201*61046927SAndroid Build Coastguard Worker * Valid if and only if gpl.pre_raster_shaders is set.
202*61046927SAndroid Build Coastguard Worker */
203*61046927SAndroid Build Coastguard Worker bool rasterizer_discard_enable;
204*61046927SAndroid Build Coastguard Worker };
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline {
207*61046927SAndroid Build Coastguard Worker struct vn_pipeline base;
208*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_state state;
209*61046927SAndroid Build Coastguard Worker };
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker /**
212*61046927SAndroid Build Coastguard Worker * Temporary storage for fixes in vkCreateGraphicsPipelines.
213*61046927SAndroid Build Coastguard Worker *
214*61046927SAndroid Build Coastguard Worker * Length of each array is vkCreateGraphicsPipelines::createInfoCount.
215*61046927SAndroid Build Coastguard Worker */
216*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp {
217*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineCreateInfo *infos;
218*61046927SAndroid Build Coastguard Worker VkPipelineMultisampleStateCreateInfo *multisample_state_infos;
219*61046927SAndroid Build Coastguard Worker VkPipelineViewportStateCreateInfo *viewport_state_infos;
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker /* Fixing the pNext chain
222*61046927SAndroid Build Coastguard Worker *
223*61046927SAndroid Build Coastguard Worker * TODO: extend when below or more extensions are supported:
224*61046927SAndroid Build Coastguard Worker * - VK_KHR_maintenance5
225*61046927SAndroid Build Coastguard Worker * - VK_EXT_pipeline_robustness
226*61046927SAndroid Build Coastguard Worker */
227*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineLibraryCreateInfoEXT *gpl_infos;
228*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedbackCreateInfo *feedback_infos;
229*61046927SAndroid Build Coastguard Worker VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_infos;
230*61046927SAndroid Build Coastguard Worker VkPipelineLibraryCreateInfoKHR *library_infos;
231*61046927SAndroid Build Coastguard Worker VkPipelineRenderingCreateInfo *rendering_infos;
232*61046927SAndroid Build Coastguard Worker };
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker /* shader module commands */
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateShaderModule(VkDevice device,const VkShaderModuleCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkShaderModule * pShaderModule)237*61046927SAndroid Build Coastguard Worker vn_CreateShaderModule(VkDevice device,
238*61046927SAndroid Build Coastguard Worker const VkShaderModuleCreateInfo *pCreateInfo,
239*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
240*61046927SAndroid Build Coastguard Worker VkShaderModule *pShaderModule)
241*61046927SAndroid Build Coastguard Worker {
242*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
243*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc =
244*61046927SAndroid Build Coastguard Worker pAllocator ? pAllocator : &dev->base.base.alloc;
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker struct vn_shader_module *mod =
247*61046927SAndroid Build Coastguard Worker vk_zalloc(alloc, sizeof(*mod), VN_DEFAULT_ALIGN,
248*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
249*61046927SAndroid Build Coastguard Worker if (!mod)
250*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker vn_object_base_init(&mod->base, VK_OBJECT_TYPE_SHADER_MODULE, &dev->base);
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker VkShaderModule mod_handle = vn_shader_module_to_handle(mod);
255*61046927SAndroid Build Coastguard Worker vn_async_vkCreateShaderModule(dev->primary_ring, device, pCreateInfo, NULL,
256*61046927SAndroid Build Coastguard Worker &mod_handle);
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker *pShaderModule = mod_handle;
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker void
vn_DestroyShaderModule(VkDevice device,VkShaderModule shaderModule,const VkAllocationCallbacks * pAllocator)264*61046927SAndroid Build Coastguard Worker vn_DestroyShaderModule(VkDevice device,
265*61046927SAndroid Build Coastguard Worker VkShaderModule shaderModule,
266*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
267*61046927SAndroid Build Coastguard Worker {
268*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
269*61046927SAndroid Build Coastguard Worker struct vn_shader_module *mod = vn_shader_module_from_handle(shaderModule);
270*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc =
271*61046927SAndroid Build Coastguard Worker pAllocator ? pAllocator : &dev->base.base.alloc;
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker if (!mod)
274*61046927SAndroid Build Coastguard Worker return;
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker vn_async_vkDestroyShaderModule(dev->primary_ring, device, shaderModule,
277*61046927SAndroid Build Coastguard Worker NULL);
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker vn_object_base_fini(&mod->base);
280*61046927SAndroid Build Coastguard Worker vk_free(alloc, mod);
281*61046927SAndroid Build Coastguard Worker }
282*61046927SAndroid Build Coastguard Worker
283*61046927SAndroid Build Coastguard Worker /* pipeline layout commands */
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker static void
vn_pipeline_layout_destroy(struct vn_device * dev,struct vn_pipeline_layout * pipeline_layout)286*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_destroy(struct vn_device *dev,
287*61046927SAndroid Build Coastguard Worker struct vn_pipeline_layout *pipeline_layout)
288*61046927SAndroid Build Coastguard Worker {
289*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
290*61046927SAndroid Build Coastguard Worker if (pipeline_layout->push_descriptor_set_layout) {
291*61046927SAndroid Build Coastguard Worker vn_descriptor_set_layout_unref(
292*61046927SAndroid Build Coastguard Worker dev, pipeline_layout->push_descriptor_set_layout);
293*61046927SAndroid Build Coastguard Worker }
294*61046927SAndroid Build Coastguard Worker vn_async_vkDestroyPipelineLayout(
295*61046927SAndroid Build Coastguard Worker dev->primary_ring, vn_device_to_handle(dev),
296*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_to_handle(pipeline_layout), NULL);
297*61046927SAndroid Build Coastguard Worker
298*61046927SAndroid Build Coastguard Worker vn_object_base_fini(&pipeline_layout->base);
299*61046927SAndroid Build Coastguard Worker vk_free(alloc, pipeline_layout);
300*61046927SAndroid Build Coastguard Worker }
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker static inline struct vn_pipeline_layout *
vn_pipeline_layout_ref(struct vn_device * dev,struct vn_pipeline_layout * pipeline_layout)303*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_ref(struct vn_device *dev,
304*61046927SAndroid Build Coastguard Worker struct vn_pipeline_layout *pipeline_layout)
305*61046927SAndroid Build Coastguard Worker {
306*61046927SAndroid Build Coastguard Worker vn_refcount_inc(&pipeline_layout->refcount);
307*61046927SAndroid Build Coastguard Worker return pipeline_layout;
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker static inline void
vn_pipeline_layout_unref(struct vn_device * dev,struct vn_pipeline_layout * pipeline_layout)311*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_unref(struct vn_device *dev,
312*61046927SAndroid Build Coastguard Worker struct vn_pipeline_layout *pipeline_layout)
313*61046927SAndroid Build Coastguard Worker {
314*61046927SAndroid Build Coastguard Worker if (vn_refcount_dec(&pipeline_layout->refcount))
315*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_destroy(dev, pipeline_layout);
316*61046927SAndroid Build Coastguard Worker }
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker VkResult
vn_CreatePipelineLayout(VkDevice device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)319*61046927SAndroid Build Coastguard Worker vn_CreatePipelineLayout(VkDevice device,
320*61046927SAndroid Build Coastguard Worker const VkPipelineLayoutCreateInfo *pCreateInfo,
321*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
322*61046927SAndroid Build Coastguard Worker VkPipelineLayout *pPipelineLayout)
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
325*61046927SAndroid Build Coastguard Worker /* ignore pAllocator as the pipeline layout is reference-counted */
326*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
327*61046927SAndroid Build Coastguard Worker
328*61046927SAndroid Build Coastguard Worker struct vn_pipeline_layout *layout =
329*61046927SAndroid Build Coastguard Worker vk_zalloc(alloc, sizeof(*layout), VN_DEFAULT_ALIGN,
330*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
331*61046927SAndroid Build Coastguard Worker if (!layout)
332*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker vn_object_base_init(&layout->base, VK_OBJECT_TYPE_PIPELINE_LAYOUT,
335*61046927SAndroid Build Coastguard Worker &dev->base);
336*61046927SAndroid Build Coastguard Worker layout->refcount = VN_REFCOUNT_INIT(1);
337*61046927SAndroid Build Coastguard Worker
338*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) {
339*61046927SAndroid Build Coastguard Worker struct vn_descriptor_set_layout *descriptor_set_layout =
340*61046927SAndroid Build Coastguard Worker vn_descriptor_set_layout_from_handle(pCreateInfo->pSetLayouts[i]);
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker /* Avoid null derefs. pSetLayouts may contain VK_NULL_HANDLE.
343*61046927SAndroid Build Coastguard Worker *
344*61046927SAndroid Build Coastguard Worker * From the Vulkan 1.3.254 spec:
345*61046927SAndroid Build Coastguard Worker * VUID-VkPipelineLayoutCreateInfo-pSetLayouts-parameter
346*61046927SAndroid Build Coastguard Worker *
347*61046927SAndroid Build Coastguard Worker * If setLayoutCount is not 0, pSetLayouts must be a valid pointer to
348*61046927SAndroid Build Coastguard Worker * an array of setLayoutCount valid or VK_NULL_HANDLE
349*61046927SAndroid Build Coastguard Worker * VkDescriptorSetLayout handles
350*61046927SAndroid Build Coastguard Worker */
351*61046927SAndroid Build Coastguard Worker if (descriptor_set_layout &&
352*61046927SAndroid Build Coastguard Worker descriptor_set_layout->is_push_descriptor) {
353*61046927SAndroid Build Coastguard Worker layout->push_descriptor_set_layout =
354*61046927SAndroid Build Coastguard Worker vn_descriptor_set_layout_ref(dev, descriptor_set_layout);
355*61046927SAndroid Build Coastguard Worker break;
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker }
358*61046927SAndroid Build Coastguard Worker
359*61046927SAndroid Build Coastguard Worker layout->has_push_constant_ranges = pCreateInfo->pushConstantRangeCount > 0;
360*61046927SAndroid Build Coastguard Worker
361*61046927SAndroid Build Coastguard Worker VkPipelineLayout layout_handle = vn_pipeline_layout_to_handle(layout);
362*61046927SAndroid Build Coastguard Worker vn_async_vkCreatePipelineLayout(dev->primary_ring, device, pCreateInfo,
363*61046927SAndroid Build Coastguard Worker NULL, &layout_handle);
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker *pPipelineLayout = layout_handle;
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
368*61046927SAndroid Build Coastguard Worker }
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker void
vn_DestroyPipelineLayout(VkDevice device,VkPipelineLayout pipelineLayout,const VkAllocationCallbacks * pAllocator)371*61046927SAndroid Build Coastguard Worker vn_DestroyPipelineLayout(VkDevice device,
372*61046927SAndroid Build Coastguard Worker VkPipelineLayout pipelineLayout,
373*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
374*61046927SAndroid Build Coastguard Worker {
375*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
376*61046927SAndroid Build Coastguard Worker struct vn_pipeline_layout *layout =
377*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_from_handle(pipelineLayout);
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker if (!layout)
380*61046927SAndroid Build Coastguard Worker return;
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_unref(dev, layout);
383*61046927SAndroid Build Coastguard Worker }
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker /* pipeline cache commands */
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker VkResult
vn_CreatePipelineCache(VkDevice device,const VkPipelineCacheCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineCache * pPipelineCache)388*61046927SAndroid Build Coastguard Worker vn_CreatePipelineCache(VkDevice device,
389*61046927SAndroid Build Coastguard Worker const VkPipelineCacheCreateInfo *pCreateInfo,
390*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
391*61046927SAndroid Build Coastguard Worker VkPipelineCache *pPipelineCache)
392*61046927SAndroid Build Coastguard Worker {
393*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
394*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc =
395*61046927SAndroid Build Coastguard Worker pAllocator ? pAllocator : &dev->base.base.alloc;
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker struct vn_pipeline_cache *cache =
398*61046927SAndroid Build Coastguard Worker vk_zalloc(alloc, sizeof(*cache), VN_DEFAULT_ALIGN,
399*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
400*61046927SAndroid Build Coastguard Worker if (!cache)
401*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker vn_object_base_init(&cache->base, VK_OBJECT_TYPE_PIPELINE_CACHE,
404*61046927SAndroid Build Coastguard Worker &dev->base);
405*61046927SAndroid Build Coastguard Worker
406*61046927SAndroid Build Coastguard Worker VkPipelineCacheCreateInfo local_create_info;
407*61046927SAndroid Build Coastguard Worker if (pCreateInfo->initialDataSize) {
408*61046927SAndroid Build Coastguard Worker const struct vk_pipeline_cache_header *header =
409*61046927SAndroid Build Coastguard Worker pCreateInfo->pInitialData;
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker local_create_info = *pCreateInfo;
412*61046927SAndroid Build Coastguard Worker local_create_info.initialDataSize -= header->header_size;
413*61046927SAndroid Build Coastguard Worker local_create_info.pInitialData += header->header_size;
414*61046927SAndroid Build Coastguard Worker pCreateInfo = &local_create_info;
415*61046927SAndroid Build Coastguard Worker }
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker VkPipelineCache cache_handle = vn_pipeline_cache_to_handle(cache);
418*61046927SAndroid Build Coastguard Worker vn_async_vkCreatePipelineCache(dev->primary_ring, device, pCreateInfo,
419*61046927SAndroid Build Coastguard Worker NULL, &cache_handle);
420*61046927SAndroid Build Coastguard Worker
421*61046927SAndroid Build Coastguard Worker *pPipelineCache = cache_handle;
422*61046927SAndroid Build Coastguard Worker
423*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
424*61046927SAndroid Build Coastguard Worker }
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker void
vn_DestroyPipelineCache(VkDevice device,VkPipelineCache pipelineCache,const VkAllocationCallbacks * pAllocator)427*61046927SAndroid Build Coastguard Worker vn_DestroyPipelineCache(VkDevice device,
428*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
429*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
430*61046927SAndroid Build Coastguard Worker {
431*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
432*61046927SAndroid Build Coastguard Worker struct vn_pipeline_cache *cache =
433*61046927SAndroid Build Coastguard Worker vn_pipeline_cache_from_handle(pipelineCache);
434*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc =
435*61046927SAndroid Build Coastguard Worker pAllocator ? pAllocator : &dev->base.base.alloc;
436*61046927SAndroid Build Coastguard Worker
437*61046927SAndroid Build Coastguard Worker if (!cache)
438*61046927SAndroid Build Coastguard Worker return;
439*61046927SAndroid Build Coastguard Worker
440*61046927SAndroid Build Coastguard Worker vn_async_vkDestroyPipelineCache(dev->primary_ring, device, pipelineCache,
441*61046927SAndroid Build Coastguard Worker NULL);
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker vn_object_base_fini(&cache->base);
444*61046927SAndroid Build Coastguard Worker vk_free(alloc, cache);
445*61046927SAndroid Build Coastguard Worker }
446*61046927SAndroid Build Coastguard Worker
447*61046927SAndroid Build Coastguard Worker static struct vn_ring *
vn_get_target_ring(struct vn_device * dev)448*61046927SAndroid Build Coastguard Worker vn_get_target_ring(struct vn_device *dev)
449*61046927SAndroid Build Coastguard Worker {
450*61046927SAndroid Build Coastguard Worker if (vn_tls_get_async_pipeline_create())
451*61046927SAndroid Build Coastguard Worker return dev->primary_ring;
452*61046927SAndroid Build Coastguard Worker
453*61046927SAndroid Build Coastguard Worker struct vn_ring *ring = vn_tls_get_ring(dev->instance);
454*61046927SAndroid Build Coastguard Worker if (!ring)
455*61046927SAndroid Build Coastguard Worker return NULL;
456*61046927SAndroid Build Coastguard Worker
457*61046927SAndroid Build Coastguard Worker if (ring != dev->primary_ring) {
458*61046927SAndroid Build Coastguard Worker /* Ensure pipeline create and pipeline cache retrieval dependencies are
459*61046927SAndroid Build Coastguard Worker * ready on the renderer side.
460*61046927SAndroid Build Coastguard Worker *
461*61046927SAndroid Build Coastguard Worker * TODO:
462*61046927SAndroid Build Coastguard Worker * - For pipeline create, track ring seqnos of layout and renderpass
463*61046927SAndroid Build Coastguard Worker * objects it depends on, and only wait for those seqnos once.
464*61046927SAndroid Build Coastguard Worker * - For pipeline cache retrieval, track ring seqno of pipeline cache
465*61046927SAndroid Build Coastguard Worker * object it depends on. Treat different sync mode separately.
466*61046927SAndroid Build Coastguard Worker */
467*61046927SAndroid Build Coastguard Worker vn_ring_wait_all(dev->primary_ring);
468*61046927SAndroid Build Coastguard Worker }
469*61046927SAndroid Build Coastguard Worker return ring;
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker VkResult
vn_GetPipelineCacheData(VkDevice device,VkPipelineCache pipelineCache,size_t * pDataSize,void * pData)473*61046927SAndroid Build Coastguard Worker vn_GetPipelineCacheData(VkDevice device,
474*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
475*61046927SAndroid Build Coastguard Worker size_t *pDataSize,
476*61046927SAndroid Build Coastguard Worker void *pData)
477*61046927SAndroid Build Coastguard Worker {
478*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
479*61046927SAndroid Build Coastguard Worker struct vn_physical_device *physical_dev = dev->physical_device;
480*61046927SAndroid Build Coastguard Worker struct vn_ring *target_ring = vn_get_target_ring(dev);
481*61046927SAndroid Build Coastguard Worker
482*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache_header *header = pData;
483*61046927SAndroid Build Coastguard Worker VkResult result;
484*61046927SAndroid Build Coastguard Worker if (!pData) {
485*61046927SAndroid Build Coastguard Worker result = vn_call_vkGetPipelineCacheData(target_ring, device,
486*61046927SAndroid Build Coastguard Worker pipelineCache, pDataSize, NULL);
487*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
488*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, result);
489*61046927SAndroid Build Coastguard Worker
490*61046927SAndroid Build Coastguard Worker *pDataSize += sizeof(*header);
491*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
492*61046927SAndroid Build Coastguard Worker }
493*61046927SAndroid Build Coastguard Worker
494*61046927SAndroid Build Coastguard Worker if (*pDataSize <= sizeof(*header)) {
495*61046927SAndroid Build Coastguard Worker *pDataSize = 0;
496*61046927SAndroid Build Coastguard Worker return VK_INCOMPLETE;
497*61046927SAndroid Build Coastguard Worker }
498*61046927SAndroid Build Coastguard Worker
499*61046927SAndroid Build Coastguard Worker const struct vk_properties *props = &physical_dev->base.base.properties;
500*61046927SAndroid Build Coastguard Worker header->header_size = sizeof(*header);
501*61046927SAndroid Build Coastguard Worker header->header_version = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
502*61046927SAndroid Build Coastguard Worker header->vendor_id = props->vendorID;
503*61046927SAndroid Build Coastguard Worker header->device_id = props->deviceID;
504*61046927SAndroid Build Coastguard Worker memcpy(header->uuid, props->pipelineCacheUUID, VK_UUID_SIZE);
505*61046927SAndroid Build Coastguard Worker
506*61046927SAndroid Build Coastguard Worker *pDataSize -= header->header_size;
507*61046927SAndroid Build Coastguard Worker result =
508*61046927SAndroid Build Coastguard Worker vn_call_vkGetPipelineCacheData(target_ring, device, pipelineCache,
509*61046927SAndroid Build Coastguard Worker pDataSize, pData + header->header_size);
510*61046927SAndroid Build Coastguard Worker if (result < VK_SUCCESS)
511*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, result);
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker *pDataSize += header->header_size;
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker return result;
516*61046927SAndroid Build Coastguard Worker }
517*61046927SAndroid Build Coastguard Worker
518*61046927SAndroid Build Coastguard Worker VkResult
vn_MergePipelineCaches(VkDevice device,VkPipelineCache dstCache,uint32_t srcCacheCount,const VkPipelineCache * pSrcCaches)519*61046927SAndroid Build Coastguard Worker vn_MergePipelineCaches(VkDevice device,
520*61046927SAndroid Build Coastguard Worker VkPipelineCache dstCache,
521*61046927SAndroid Build Coastguard Worker uint32_t srcCacheCount,
522*61046927SAndroid Build Coastguard Worker const VkPipelineCache *pSrcCaches)
523*61046927SAndroid Build Coastguard Worker {
524*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
525*61046927SAndroid Build Coastguard Worker
526*61046927SAndroid Build Coastguard Worker vn_async_vkMergePipelineCaches(dev->primary_ring, device, dstCache,
527*61046927SAndroid Build Coastguard Worker srcCacheCount, pSrcCaches);
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
530*61046927SAndroid Build Coastguard Worker }
531*61046927SAndroid Build Coastguard Worker
532*61046927SAndroid Build Coastguard Worker /* pipeline commands */
533*61046927SAndroid Build Coastguard Worker
534*61046927SAndroid Build Coastguard Worker static struct vn_graphics_pipeline *
vn_graphics_pipeline_from_handle(VkPipeline pipeline_h)535*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_from_handle(VkPipeline pipeline_h)
536*61046927SAndroid Build Coastguard Worker {
537*61046927SAndroid Build Coastguard Worker struct vn_pipeline *p = vn_pipeline_from_handle(pipeline_h);
538*61046927SAndroid Build Coastguard Worker assert(p->type == VN_PIPELINE_TYPE_GRAPHICS);
539*61046927SAndroid Build Coastguard Worker return (struct vn_graphics_pipeline *)p;
540*61046927SAndroid Build Coastguard Worker }
541*61046927SAndroid Build Coastguard Worker
542*61046927SAndroid Build Coastguard Worker static bool
vn_create_pipeline_handles(struct vn_device * dev,enum vn_pipeline_type type,uint32_t pipeline_count,VkPipeline * pipeline_handles,const VkAllocationCallbacks * alloc)543*61046927SAndroid Build Coastguard Worker vn_create_pipeline_handles(struct vn_device *dev,
544*61046927SAndroid Build Coastguard Worker enum vn_pipeline_type type,
545*61046927SAndroid Build Coastguard Worker uint32_t pipeline_count,
546*61046927SAndroid Build Coastguard Worker VkPipeline *pipeline_handles,
547*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
548*61046927SAndroid Build Coastguard Worker {
549*61046927SAndroid Build Coastguard Worker size_t pipeline_size;
550*61046927SAndroid Build Coastguard Worker
551*61046927SAndroid Build Coastguard Worker switch (type) {
552*61046927SAndroid Build Coastguard Worker case VN_PIPELINE_TYPE_GRAPHICS:
553*61046927SAndroid Build Coastguard Worker pipeline_size = sizeof(struct vn_graphics_pipeline);
554*61046927SAndroid Build Coastguard Worker break;
555*61046927SAndroid Build Coastguard Worker case VN_PIPELINE_TYPE_COMPUTE:
556*61046927SAndroid Build Coastguard Worker pipeline_size = sizeof(struct vn_pipeline);
557*61046927SAndroid Build Coastguard Worker break;
558*61046927SAndroid Build Coastguard Worker }
559*61046927SAndroid Build Coastguard Worker
560*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pipeline_count; i++) {
561*61046927SAndroid Build Coastguard Worker struct vn_pipeline *pipeline =
562*61046927SAndroid Build Coastguard Worker vk_zalloc(alloc, pipeline_size, VN_DEFAULT_ALIGN,
563*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker if (!pipeline) {
566*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0; j < i; j++) {
567*61046927SAndroid Build Coastguard Worker pipeline = vn_pipeline_from_handle(pipeline_handles[j]);
568*61046927SAndroid Build Coastguard Worker vn_object_base_fini(&pipeline->base);
569*61046927SAndroid Build Coastguard Worker vk_free(alloc, pipeline);
570*61046927SAndroid Build Coastguard Worker }
571*61046927SAndroid Build Coastguard Worker
572*61046927SAndroid Build Coastguard Worker memset(pipeline_handles, 0,
573*61046927SAndroid Build Coastguard Worker pipeline_count * sizeof(pipeline_handles[0]));
574*61046927SAndroid Build Coastguard Worker return false;
575*61046927SAndroid Build Coastguard Worker }
576*61046927SAndroid Build Coastguard Worker
577*61046927SAndroid Build Coastguard Worker vn_object_base_init(&pipeline->base, VK_OBJECT_TYPE_PIPELINE,
578*61046927SAndroid Build Coastguard Worker &dev->base);
579*61046927SAndroid Build Coastguard Worker pipeline->type = type;
580*61046927SAndroid Build Coastguard Worker pipeline_handles[i] = vn_pipeline_to_handle(pipeline);
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker return true;
584*61046927SAndroid Build Coastguard Worker }
585*61046927SAndroid Build Coastguard Worker
586*61046927SAndroid Build Coastguard Worker static void
vn_destroy_pipeline_handles_internal(struct vn_device * dev,uint32_t pipeline_count,VkPipeline * pipeline_handles,const VkAllocationCallbacks * alloc,bool failed_only)587*61046927SAndroid Build Coastguard Worker vn_destroy_pipeline_handles_internal(struct vn_device *dev,
588*61046927SAndroid Build Coastguard Worker uint32_t pipeline_count,
589*61046927SAndroid Build Coastguard Worker VkPipeline *pipeline_handles,
590*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc,
591*61046927SAndroid Build Coastguard Worker bool failed_only)
592*61046927SAndroid Build Coastguard Worker {
593*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pipeline_count; i++) {
594*61046927SAndroid Build Coastguard Worker struct vn_pipeline *pipeline =
595*61046927SAndroid Build Coastguard Worker vn_pipeline_from_handle(pipeline_handles[i]);
596*61046927SAndroid Build Coastguard Worker
597*61046927SAndroid Build Coastguard Worker if (!failed_only || pipeline->base.id == 0) {
598*61046927SAndroid Build Coastguard Worker if (pipeline->layout) {
599*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_unref(dev, pipeline->layout);
600*61046927SAndroid Build Coastguard Worker }
601*61046927SAndroid Build Coastguard Worker vn_object_base_fini(&pipeline->base);
602*61046927SAndroid Build Coastguard Worker vk_free(alloc, pipeline);
603*61046927SAndroid Build Coastguard Worker pipeline_handles[i] = VK_NULL_HANDLE;
604*61046927SAndroid Build Coastguard Worker }
605*61046927SAndroid Build Coastguard Worker }
606*61046927SAndroid Build Coastguard Worker }
607*61046927SAndroid Build Coastguard Worker
608*61046927SAndroid Build Coastguard Worker static inline void
vn_destroy_pipeline_handles(struct vn_device * dev,uint32_t pipeline_count,VkPipeline * pipeline_handles,const VkAllocationCallbacks * alloc)609*61046927SAndroid Build Coastguard Worker vn_destroy_pipeline_handles(struct vn_device *dev,
610*61046927SAndroid Build Coastguard Worker uint32_t pipeline_count,
611*61046927SAndroid Build Coastguard Worker VkPipeline *pipeline_handles,
612*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
613*61046927SAndroid Build Coastguard Worker {
614*61046927SAndroid Build Coastguard Worker vn_destroy_pipeline_handles_internal(dev, pipeline_count, pipeline_handles,
615*61046927SAndroid Build Coastguard Worker alloc, false);
616*61046927SAndroid Build Coastguard Worker }
617*61046927SAndroid Build Coastguard Worker
618*61046927SAndroid Build Coastguard Worker static inline void
vn_destroy_failed_pipeline_handles(struct vn_device * dev,uint32_t pipeline_count,VkPipeline * pipeline_handles,const VkAllocationCallbacks * alloc)619*61046927SAndroid Build Coastguard Worker vn_destroy_failed_pipeline_handles(struct vn_device *dev,
620*61046927SAndroid Build Coastguard Worker uint32_t pipeline_count,
621*61046927SAndroid Build Coastguard Worker VkPipeline *pipeline_handles,
622*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
623*61046927SAndroid Build Coastguard Worker {
624*61046927SAndroid Build Coastguard Worker vn_destroy_pipeline_handles_internal(dev, pipeline_count, pipeline_handles,
625*61046927SAndroid Build Coastguard Worker alloc, true);
626*61046927SAndroid Build Coastguard Worker }
627*61046927SAndroid Build Coastguard Worker
628*61046927SAndroid Build Coastguard Worker #define VN_PIPELINE_CREATE_SYNC_MASK \
629*61046927SAndroid Build Coastguard Worker (VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT | \
630*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT)
631*61046927SAndroid Build Coastguard Worker
632*61046927SAndroid Build Coastguard Worker static struct vn_graphics_pipeline_fix_tmp *
vn_graphics_pipeline_fix_tmp_alloc(const VkAllocationCallbacks * alloc,uint32_t info_count,bool alloc_pnext)633*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_fix_tmp_alloc(const VkAllocationCallbacks *alloc,
634*61046927SAndroid Build Coastguard Worker uint32_t info_count,
635*61046927SAndroid Build Coastguard Worker bool alloc_pnext)
636*61046927SAndroid Build Coastguard Worker {
637*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp *tmp;
638*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineCreateInfo *infos;
639*61046927SAndroid Build Coastguard Worker VkPipelineMultisampleStateCreateInfo *multisample_state_infos;
640*61046927SAndroid Build Coastguard Worker VkPipelineViewportStateCreateInfo *viewport_state_infos;
641*61046927SAndroid Build Coastguard Worker
642*61046927SAndroid Build Coastguard Worker /* for pNext */
643*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineLibraryCreateInfoEXT *gpl_infos;
644*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedbackCreateInfo *feedback_infos;
645*61046927SAndroid Build Coastguard Worker VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_infos;
646*61046927SAndroid Build Coastguard Worker VkPipelineLibraryCreateInfoKHR *library_infos;
647*61046927SAndroid Build Coastguard Worker VkPipelineRenderingCreateInfo *rendering_infos;
648*61046927SAndroid Build Coastguard Worker
649*61046927SAndroid Build Coastguard Worker VK_MULTIALLOC(ma);
650*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &tmp, __typeof__(*tmp), 1);
651*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &infos, __typeof__(*infos), info_count);
652*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &multisample_state_infos,
653*61046927SAndroid Build Coastguard Worker __typeof__(*multisample_state_infos), info_count);
654*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &viewport_state_infos,
655*61046927SAndroid Build Coastguard Worker __typeof__(*viewport_state_infos), info_count);
656*61046927SAndroid Build Coastguard Worker
657*61046927SAndroid Build Coastguard Worker if (alloc_pnext) {
658*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &gpl_infos, __typeof__(*gpl_infos), info_count);
659*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &feedback_infos, __typeof__(*feedback_infos),
660*61046927SAndroid Build Coastguard Worker info_count);
661*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &fsr_infos, __typeof__(*fsr_infos), info_count);
662*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &library_infos, __typeof__(*library_infos),
663*61046927SAndroid Build Coastguard Worker info_count);
664*61046927SAndroid Build Coastguard Worker vk_multialloc_add(&ma, &rendering_infos, __typeof__(*rendering_infos),
665*61046927SAndroid Build Coastguard Worker info_count);
666*61046927SAndroid Build Coastguard Worker }
667*61046927SAndroid Build Coastguard Worker
668*61046927SAndroid Build Coastguard Worker if (!vk_multialloc_zalloc(&ma, alloc, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND))
669*61046927SAndroid Build Coastguard Worker return NULL;
670*61046927SAndroid Build Coastguard Worker
671*61046927SAndroid Build Coastguard Worker tmp->infos = infos;
672*61046927SAndroid Build Coastguard Worker tmp->multisample_state_infos = multisample_state_infos;
673*61046927SAndroid Build Coastguard Worker tmp->viewport_state_infos = viewport_state_infos;
674*61046927SAndroid Build Coastguard Worker
675*61046927SAndroid Build Coastguard Worker if (alloc_pnext) {
676*61046927SAndroid Build Coastguard Worker tmp->gpl_infos = gpl_infos;
677*61046927SAndroid Build Coastguard Worker tmp->feedback_infos = feedback_infos;
678*61046927SAndroid Build Coastguard Worker tmp->fsr_infos = fsr_infos;
679*61046927SAndroid Build Coastguard Worker tmp->library_infos = library_infos;
680*61046927SAndroid Build Coastguard Worker tmp->rendering_infos = rendering_infos;
681*61046927SAndroid Build Coastguard Worker }
682*61046927SAndroid Build Coastguard Worker
683*61046927SAndroid Build Coastguard Worker return tmp;
684*61046927SAndroid Build Coastguard Worker }
685*61046927SAndroid Build Coastguard Worker
686*61046927SAndroid Build Coastguard Worker /**
687*61046927SAndroid Build Coastguard Worker * Update \a gpl with the VkGraphicsPipelineLibraryFlagsEXT that the pipeline
688*61046927SAndroid Build Coastguard Worker * provides directly (without linking). The spec says that the pipeline always
689*61046927SAndroid Build Coastguard Worker * provides flags, but may do it implicitly.
690*61046927SAndroid Build Coastguard Worker *
691*61046927SAndroid Build Coastguard Worker * From the Vulkan 1.3.251 spec:
692*61046927SAndroid Build Coastguard Worker *
693*61046927SAndroid Build Coastguard Worker * If this structure [VkGraphicsPipelineLibraryCreateInfoEXT] is
694*61046927SAndroid Build Coastguard Worker * omitted, and either VkGraphicsPipelineCreateInfo::flags includes
695*61046927SAndroid Build Coastguard Worker * VK_PIPELINE_CREATE_LIBRARY_BIT_KHR or the
696*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo::pNext chain includes
697*61046927SAndroid Build Coastguard Worker * a VkPipelineLibraryCreateInfoKHR structure with a libraryCount
698*61046927SAndroid Build Coastguard Worker * greater than 0, it is as if flags is 0. Otherwise if this
699*61046927SAndroid Build Coastguard Worker * structure is omitted, it is as if flags includes all possible subsets
700*61046927SAndroid Build Coastguard Worker * of the graphics pipeline (i.e. a complete graphics pipeline).
701*61046927SAndroid Build Coastguard Worker */
702*61046927SAndroid Build Coastguard Worker static void
vn_graphics_pipeline_library_state_update(const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_library_state * restrict gpl)703*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_library_state_update(
704*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
705*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_library_state *restrict gpl)
706*61046927SAndroid Build Coastguard Worker {
707*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineLibraryCreateInfoEXT *gpl_info =
708*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext,
709*61046927SAndroid Build Coastguard Worker GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
710*61046927SAndroid Build Coastguard Worker const VkPipelineLibraryCreateInfoKHR *lib_info =
711*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR);
712*61046927SAndroid Build Coastguard Worker const uint32_t lib_count = lib_info ? lib_info->libraryCount : 0;
713*61046927SAndroid Build Coastguard Worker
714*61046927SAndroid Build Coastguard Worker if (gpl_info) {
715*61046927SAndroid Build Coastguard Worker gpl->mask |= gpl_info->flags;
716*61046927SAndroid Build Coastguard Worker } else if ((info->flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) ||
717*61046927SAndroid Build Coastguard Worker lib_count > 0) {
718*61046927SAndroid Build Coastguard Worker gpl->mask |= 0;
719*61046927SAndroid Build Coastguard Worker } else {
720*61046927SAndroid Build Coastguard Worker gpl->mask |=
721*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT |
722*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
723*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
724*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
725*61046927SAndroid Build Coastguard Worker }
726*61046927SAndroid Build Coastguard Worker }
727*61046927SAndroid Build Coastguard Worker
728*61046927SAndroid Build Coastguard Worker /**
729*61046927SAndroid Build Coastguard Worker * Update \a dynamic with the VkDynamicState that the pipeline provides
730*61046927SAndroid Build Coastguard Worker * directly (without linking).
731*61046927SAndroid Build Coastguard Worker *
732*61046927SAndroid Build Coastguard Worker * \a direct_gpl The VkGraphicsPipelineLibraryFlagsEXT that the pipeline sets
733*61046927SAndroid Build Coastguard Worker * directly (without linking).
734*61046927SAndroid Build Coastguard Worker */
735*61046927SAndroid Build Coastguard Worker static void
vn_graphics_dynamic_state_update(const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_library_state direct_gpl,struct vn_graphics_dynamic_state * restrict dynamic)736*61046927SAndroid Build Coastguard Worker vn_graphics_dynamic_state_update(
737*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
738*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_library_state direct_gpl,
739*61046927SAndroid Build Coastguard Worker struct vn_graphics_dynamic_state *restrict dynamic)
740*61046927SAndroid Build Coastguard Worker {
741*61046927SAndroid Build Coastguard Worker const VkPipelineDynamicStateCreateInfo *dyn_info = info->pDynamicState;
742*61046927SAndroid Build Coastguard Worker if (!dyn_info)
743*61046927SAndroid Build Coastguard Worker return;
744*61046927SAndroid Build Coastguard Worker
745*61046927SAndroid Build Coastguard Worker struct vn_graphics_dynamic_state raw = { 0 };
746*61046927SAndroid Build Coastguard Worker
747*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < dyn_info->dynamicStateCount; i++) {
748*61046927SAndroid Build Coastguard Worker switch (dyn_info->pDynamicStates[i]) {
749*61046927SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
750*61046927SAndroid Build Coastguard Worker raw.vertex_input = true;
751*61046927SAndroid Build Coastguard Worker break;
752*61046927SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VIEWPORT:
753*61046927SAndroid Build Coastguard Worker raw.viewport = true;
754*61046927SAndroid Build Coastguard Worker break;
755*61046927SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT:
756*61046927SAndroid Build Coastguard Worker raw.viewport_with_count = true;
757*61046927SAndroid Build Coastguard Worker break;
758*61046927SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_SAMPLE_MASK_EXT:
759*61046927SAndroid Build Coastguard Worker raw.sample_mask = true;
760*61046927SAndroid Build Coastguard Worker break;
761*61046927SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_SCISSOR:
762*61046927SAndroid Build Coastguard Worker raw.scissor = true;
763*61046927SAndroid Build Coastguard Worker break;
764*61046927SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT:
765*61046927SAndroid Build Coastguard Worker raw.scissor_with_count = true;
766*61046927SAndroid Build Coastguard Worker break;
767*61046927SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE:
768*61046927SAndroid Build Coastguard Worker raw.rasterizer_discard_enable = true;
769*61046927SAndroid Build Coastguard Worker break;
770*61046927SAndroid Build Coastguard Worker default:
771*61046927SAndroid Build Coastguard Worker break;
772*61046927SAndroid Build Coastguard Worker }
773*61046927SAndroid Build Coastguard Worker }
774*61046927SAndroid Build Coastguard Worker
775*61046927SAndroid Build Coastguard Worker /* We must ignore VkDynamicState unrelated to the
776*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineLibraryFlagsEXT that the pipeline provides directly
777*61046927SAndroid Build Coastguard Worker * (without linking).
778*61046927SAndroid Build Coastguard Worker *
779*61046927SAndroid Build Coastguard Worker * [Vulkan 1.3.252]
780*61046927SAndroid Build Coastguard Worker * Dynamic state values set via pDynamicState must be ignored if the
781*61046927SAndroid Build Coastguard Worker * state they correspond to is not otherwise statically set by one of
782*61046927SAndroid Build Coastguard Worker * the state subsets used to create the pipeline.
783*61046927SAndroid Build Coastguard Worker *
784*61046927SAndroid Build Coastguard Worker * In general, we must update dynamic state bits with `|=` rather than `=`
785*61046927SAndroid Build Coastguard Worker * because multiple GPL state subsets can enable the same dynamic state.
786*61046927SAndroid Build Coastguard Worker *
787*61046927SAndroid Build Coastguard Worker * [Vulkan 1.3.252]
788*61046927SAndroid Build Coastguard Worker * Any linked library that has dynamic state enabled that same dynamic
789*61046927SAndroid Build Coastguard Worker * state must also be enabled in all the other linked libraries to which
790*61046927SAndroid Build Coastguard Worker * that dynamic state applies.
791*61046927SAndroid Build Coastguard Worker */
792*61046927SAndroid Build Coastguard Worker if (direct_gpl.vertex_input) {
793*61046927SAndroid Build Coastguard Worker dynamic->vertex_input |= raw.vertex_input;
794*61046927SAndroid Build Coastguard Worker }
795*61046927SAndroid Build Coastguard Worker if (direct_gpl.pre_raster_shaders) {
796*61046927SAndroid Build Coastguard Worker dynamic->viewport |= raw.viewport;
797*61046927SAndroid Build Coastguard Worker dynamic->viewport_with_count |= raw.viewport_with_count;
798*61046927SAndroid Build Coastguard Worker dynamic->scissor |= raw.scissor;
799*61046927SAndroid Build Coastguard Worker dynamic->scissor_with_count |= raw.scissor_with_count;
800*61046927SAndroid Build Coastguard Worker dynamic->rasterizer_discard_enable |= raw.rasterizer_discard_enable;
801*61046927SAndroid Build Coastguard Worker }
802*61046927SAndroid Build Coastguard Worker if (direct_gpl.fragment_shader) {
803*61046927SAndroid Build Coastguard Worker dynamic->sample_mask |= raw.sample_mask;
804*61046927SAndroid Build Coastguard Worker }
805*61046927SAndroid Build Coastguard Worker if (direct_gpl.fragment_output) {
806*61046927SAndroid Build Coastguard Worker dynamic->sample_mask |= raw.sample_mask;
807*61046927SAndroid Build Coastguard Worker }
808*61046927SAndroid Build Coastguard Worker }
809*61046927SAndroid Build Coastguard Worker
810*61046927SAndroid Build Coastguard Worker /**
811*61046927SAndroid Build Coastguard Worker * Update \a shader_stages with the VkShaderStageFlags that the pipeline
812*61046927SAndroid Build Coastguard Worker * provides directly (without linking).
813*61046927SAndroid Build Coastguard Worker *
814*61046927SAndroid Build Coastguard Worker * \a direct_gpl The VkGraphicsPipelineLibraryFlagsEXT that the pipeline sets
815*61046927SAndroid Build Coastguard Worker * directly (without linking).
816*61046927SAndroid Build Coastguard Worker */
817*61046927SAndroid Build Coastguard Worker static void
vn_graphics_shader_stages_update(const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_library_state direct_gpl,struct vn_graphics_pipeline_fix_desc * restrict valid,VkShaderStageFlags * restrict shader_stages)818*61046927SAndroid Build Coastguard Worker vn_graphics_shader_stages_update(
819*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
820*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_library_state direct_gpl,
821*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_desc *restrict valid,
822*61046927SAndroid Build Coastguard Worker VkShaderStageFlags *restrict shader_stages)
823*61046927SAndroid Build Coastguard Worker {
824*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.3.251 spec:
825*61046927SAndroid Build Coastguard Worker *
826*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-flags-06640
827*61046927SAndroid Build Coastguard Worker *
828*61046927SAndroid Build Coastguard Worker * If VkGraphicsPipelineLibraryCreateInfoEXT::flags includes
829*61046927SAndroid Build Coastguard Worker * VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT or
830*61046927SAndroid Build Coastguard Worker * VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT, pStages must be
831*61046927SAndroid Build Coastguard Worker * a valid pointer to an array of stageCount valid
832*61046927SAndroid Build Coastguard Worker * VkPipelineShaderStageCreateInfo structures
833*61046927SAndroid Build Coastguard Worker */
834*61046927SAndroid Build Coastguard Worker if (!direct_gpl.pre_raster_shaders && !direct_gpl.fragment_shader)
835*61046927SAndroid Build Coastguard Worker return;
836*61046927SAndroid Build Coastguard Worker
837*61046927SAndroid Build Coastguard Worker valid->self.shader_stages = true;
838*61046927SAndroid Build Coastguard Worker
839*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->stageCount; i++) {
840*61046927SAndroid Build Coastguard Worker /* We do not need to ignore the stages irrelevant to the GPL flags.
841*61046927SAndroid Build Coastguard Worker * The following VUs require the app to provide only relevant stages.
842*61046927SAndroid Build Coastguard Worker *
843*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-pStages-06894
844*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-pStages-06895
845*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-pStages-06896
846*61046927SAndroid Build Coastguard Worker */
847*61046927SAndroid Build Coastguard Worker *shader_stages |= info->pStages[i].stage;
848*61046927SAndroid Build Coastguard Worker }
849*61046927SAndroid Build Coastguard Worker }
850*61046927SAndroid Build Coastguard Worker
851*61046927SAndroid Build Coastguard Worker /**
852*61046927SAndroid Build Coastguard Worker * Update the render pass state with the state that the pipeline provides
853*61046927SAndroid Build Coastguard Worker * directly (without linking).
854*61046927SAndroid Build Coastguard Worker *
855*61046927SAndroid Build Coastguard Worker * \a direct_gpl The VkGraphicsPipelineLibraryFlagsEXT that the pipeline sets
856*61046927SAndroid Build Coastguard Worker * directly (without linking).
857*61046927SAndroid Build Coastguard Worker */
858*61046927SAndroid Build Coastguard Worker static void
vn_render_pass_state_update(const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_library_state direct_gpl,struct vn_graphics_pipeline_fix_desc * restrict valid,struct vn_render_pass_state * restrict state)859*61046927SAndroid Build Coastguard Worker vn_render_pass_state_update(
860*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
861*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_library_state direct_gpl,
862*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_desc *restrict valid,
863*61046927SAndroid Build Coastguard Worker struct vn_render_pass_state *restrict state)
864*61046927SAndroid Build Coastguard Worker {
865*61046927SAndroid Build Coastguard Worker /* We must set validity before early returns, to ensure we don't erase
866*61046927SAndroid Build Coastguard Worker * valid info during fixup. We must not erase valid info because, even if
867*61046927SAndroid Build Coastguard Worker * we don't read it, the host driver may read it.
868*61046927SAndroid Build Coastguard Worker */
869*61046927SAndroid Build Coastguard Worker
870*61046927SAndroid Build Coastguard Worker /* VUID-VkGraphicsPipelineCreateInfo-flags-06643
871*61046927SAndroid Build Coastguard Worker *
872*61046927SAndroid Build Coastguard Worker * If VkGraphicsPipelineLibraryCreateInfoEXT::flags includes
873*61046927SAndroid Build Coastguard Worker * VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT, or
874*61046927SAndroid Build Coastguard Worker * VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT,
875*61046927SAndroid Build Coastguard Worker * VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT, and
876*61046927SAndroid Build Coastguard Worker * renderPass is not VK_NULL_HANDLE, renderPass must be a valid
877*61046927SAndroid Build Coastguard Worker * VkRenderPass handle
878*61046927SAndroid Build Coastguard Worker */
879*61046927SAndroid Build Coastguard Worker valid->self.render_pass |= direct_gpl.pre_raster_shaders ||
880*61046927SAndroid Build Coastguard Worker direct_gpl.fragment_shader ||
881*61046927SAndroid Build Coastguard Worker direct_gpl.fragment_output;
882*61046927SAndroid Build Coastguard Worker
883*61046927SAndroid Build Coastguard Worker /* VUID-VkGraphicsPipelineCreateInfo-renderPass-06579
884*61046927SAndroid Build Coastguard Worker *
885*61046927SAndroid Build Coastguard Worker * If the pipeline requires fragment output interface state, and renderPass
886*61046927SAndroid Build Coastguard Worker * is VK_NULL_HANDLE, and
887*61046927SAndroid Build Coastguard Worker * VkPipelineRenderingCreateInfo::colorAttachmentCount is not 0,
888*61046927SAndroid Build Coastguard Worker * VkPipelineRenderingCreateInfo::pColorAttachmentFormats must be a valid
889*61046927SAndroid Build Coastguard Worker * pointer to an array of colorAttachmentCount valid VkFormat values
890*61046927SAndroid Build Coastguard Worker *
891*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-renderPass-06580
892*61046927SAndroid Build Coastguard Worker *
893*61046927SAndroid Build Coastguard Worker * If the pipeline requires fragment output interface state, and renderPass
894*61046927SAndroid Build Coastguard Worker * is VK_NULL_HANDLE, each element of
895*61046927SAndroid Build Coastguard Worker * VkPipelineRenderingCreateInfo::pColorAttachmentFormats must be a valid
896*61046927SAndroid Build Coastguard Worker * VkFormat value
897*61046927SAndroid Build Coastguard Worker */
898*61046927SAndroid Build Coastguard Worker valid->pnext.rendering_info_formats |=
899*61046927SAndroid Build Coastguard Worker direct_gpl.fragment_output && !info->renderPass;
900*61046927SAndroid Build Coastguard Worker
901*61046927SAndroid Build Coastguard Worker if (state->attachment_aspects != VK_IMAGE_ASPECT_METADATA_BIT) {
902*61046927SAndroid Build Coastguard Worker /* We have previously collected the pipeline's attachment aspects. We
903*61046927SAndroid Build Coastguard Worker * do not need to inspect the attachment info again because VUs ensure
904*61046927SAndroid Build Coastguard Worker * that all valid render pass info used to create the pipeline and its
905*61046927SAndroid Build Coastguard Worker * linked pipelines are compatible. Ignored info is not required to be
906*61046927SAndroid Build Coastguard Worker * compatible across linked pipeline libraries. An example of ignored
907*61046927SAndroid Build Coastguard Worker * info is VkPipelineRenderingCreateInfo::pColorAttachmentFormats
908*61046927SAndroid Build Coastguard Worker * without
909*61046927SAndroid Build Coastguard Worker * VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT.
910*61046927SAndroid Build Coastguard Worker *
911*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-renderpass-06625
912*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-pLibraries-06628
913*61046927SAndroid Build Coastguard Worker */
914*61046927SAndroid Build Coastguard Worker return;
915*61046927SAndroid Build Coastguard Worker }
916*61046927SAndroid Build Coastguard Worker
917*61046927SAndroid Build Coastguard Worker if (valid->self.render_pass && info->renderPass) {
918*61046927SAndroid Build Coastguard Worker struct vn_render_pass *pass =
919*61046927SAndroid Build Coastguard Worker vn_render_pass_from_handle(info->renderPass);
920*61046927SAndroid Build Coastguard Worker state->attachment_aspects =
921*61046927SAndroid Build Coastguard Worker pass->subpasses[info->subpass].attachment_aspects;
922*61046927SAndroid Build Coastguard Worker return;
923*61046927SAndroid Build Coastguard Worker }
924*61046927SAndroid Build Coastguard Worker
925*61046927SAndroid Build Coastguard Worker if (valid->pnext.rendering_info_formats) {
926*61046927SAndroid Build Coastguard Worker state->attachment_aspects = 0;
927*61046927SAndroid Build Coastguard Worker
928*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.3.255 spec:
929*61046927SAndroid Build Coastguard Worker *
930*61046927SAndroid Build Coastguard Worker * When a pipeline is created without a VkRenderPass, if this
931*61046927SAndroid Build Coastguard Worker * structure [VkPipelineRenderingCreateInfo] is present in the pNext
932*61046927SAndroid Build Coastguard Worker * chain of VkGraphicsPipelineCreateInfo, it specifies the view mask
933*61046927SAndroid Build Coastguard Worker * and format of attachments used for rendering. If this structure
934*61046927SAndroid Build Coastguard Worker * is not specified, and the pipeline does not include
935*61046927SAndroid Build Coastguard Worker * a VkRenderPass, viewMask and colorAttachmentCount are 0, and
936*61046927SAndroid Build Coastguard Worker * depthAttachmentFormat and stencilAttachmentFormat are
937*61046927SAndroid Build Coastguard Worker * VK_FORMAT_UNDEFINED. If a graphics pipeline is created with
938*61046927SAndroid Build Coastguard Worker * a valid VkRenderPass, parameters of this structure are ignored.
939*61046927SAndroid Build Coastguard Worker *
940*61046927SAndroid Build Coastguard Worker * However, other spec text clearly states that the format members of
941*61046927SAndroid Build Coastguard Worker * VkPipelineRenderingCreateInfo are ignored unless the pipeline
942*61046927SAndroid Build Coastguard Worker * provides fragment output interface state directly (without linking).
943*61046927SAndroid Build Coastguard Worker */
944*61046927SAndroid Build Coastguard Worker const VkPipelineRenderingCreateInfo *r_info =
945*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext, PIPELINE_RENDERING_CREATE_INFO);
946*61046927SAndroid Build Coastguard Worker
947*61046927SAndroid Build Coastguard Worker if (r_info) {
948*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < r_info->colorAttachmentCount; i++) {
949*61046927SAndroid Build Coastguard Worker if (r_info->pColorAttachmentFormats[i]) {
950*61046927SAndroid Build Coastguard Worker state->attachment_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
951*61046927SAndroid Build Coastguard Worker break;
952*61046927SAndroid Build Coastguard Worker }
953*61046927SAndroid Build Coastguard Worker }
954*61046927SAndroid Build Coastguard Worker if (r_info->depthAttachmentFormat)
955*61046927SAndroid Build Coastguard Worker state->attachment_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
956*61046927SAndroid Build Coastguard Worker if (r_info->stencilAttachmentFormat)
957*61046927SAndroid Build Coastguard Worker state->attachment_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
958*61046927SAndroid Build Coastguard Worker }
959*61046927SAndroid Build Coastguard Worker
960*61046927SAndroid Build Coastguard Worker return;
961*61046927SAndroid Build Coastguard Worker }
962*61046927SAndroid Build Coastguard Worker
963*61046927SAndroid Build Coastguard Worker /* Aspects remain invalid. */
964*61046927SAndroid Build Coastguard Worker assert(state->attachment_aspects == VK_IMAGE_ASPECT_METADATA_BIT);
965*61046927SAndroid Build Coastguard Worker }
966*61046927SAndroid Build Coastguard Worker
967*61046927SAndroid Build Coastguard Worker static void
vn_graphics_pipeline_state_merge(struct vn_graphics_pipeline_state * restrict dst,const struct vn_graphics_pipeline_state * restrict src)968*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_state_merge(
969*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_state *restrict dst,
970*61046927SAndroid Build Coastguard Worker const struct vn_graphics_pipeline_state *restrict src)
971*61046927SAndroid Build Coastguard Worker {
972*61046927SAndroid Build Coastguard Worker /* The Vulkan 1.3.251 spec says:
973*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-pLibraries-06611
974*61046927SAndroid Build Coastguard Worker *
975*61046927SAndroid Build Coastguard Worker * Any pipeline libraries included via
976*61046927SAndroid Build Coastguard Worker * VkPipelineLibraryCreateInfoKHR::pLibraries must not include any state
977*61046927SAndroid Build Coastguard Worker * subset already defined by this structure or defined by any other
978*61046927SAndroid Build Coastguard Worker * pipeline library in VkPipelineLibraryCreateInfoKHR::pLibraries
979*61046927SAndroid Build Coastguard Worker */
980*61046927SAndroid Build Coastguard Worker assert(!(dst->gpl.mask & src->gpl.mask));
981*61046927SAndroid Build Coastguard Worker
982*61046927SAndroid Build Coastguard Worker dst->gpl.mask |= src->gpl.mask;
983*61046927SAndroid Build Coastguard Worker dst->dynamic.mask |= src->dynamic.mask;
984*61046927SAndroid Build Coastguard Worker dst->shader_stages |= src->shader_stages;
985*61046927SAndroid Build Coastguard Worker
986*61046927SAndroid Build Coastguard Worker VkImageAspectFlags src_aspects = src->render_pass.attachment_aspects;
987*61046927SAndroid Build Coastguard Worker VkImageAspectFlags *dst_aspects = &dst->render_pass.attachment_aspects;
988*61046927SAndroid Build Coastguard Worker
989*61046927SAndroid Build Coastguard Worker if (src_aspects != VK_IMAGE_ASPECT_METADATA_BIT) {
990*61046927SAndroid Build Coastguard Worker if (*dst_aspects != VK_IMAGE_ASPECT_METADATA_BIT) {
991*61046927SAndroid Build Coastguard Worker /* All linked pipelines must have compatible render pass info. */
992*61046927SAndroid Build Coastguard Worker assert(*dst_aspects == src_aspects);
993*61046927SAndroid Build Coastguard Worker } else {
994*61046927SAndroid Build Coastguard Worker *dst_aspects = src_aspects;
995*61046927SAndroid Build Coastguard Worker }
996*61046927SAndroid Build Coastguard Worker }
997*61046927SAndroid Build Coastguard Worker
998*61046927SAndroid Build Coastguard Worker if (dst->gpl.pre_raster_shaders)
999*61046927SAndroid Build Coastguard Worker dst->rasterizer_discard_enable = src->rasterizer_discard_enable;
1000*61046927SAndroid Build Coastguard Worker }
1001*61046927SAndroid Build Coastguard Worker
1002*61046927SAndroid Build Coastguard Worker /**
1003*61046927SAndroid Build Coastguard Worker * Fill \a state by reading the VkGraphicsPipelineCreateInfo pNext chain,
1004*61046927SAndroid Build Coastguard Worker * including any linked pipeline libraries. Return in \a out_fix_desc
1005*61046927SAndroid Build Coastguard Worker * a description of required fixes to the VkGraphicsPipelineCreateInfo chain.
1006*61046927SAndroid Build Coastguard Worker *
1007*61046927SAndroid Build Coastguard Worker * \pre state is zero-filled
1008*61046927SAndroid Build Coastguard Worker *
1009*61046927SAndroid Build Coastguard Worker * The logic for choosing which struct members to ignore, and which members
1010*61046927SAndroid Build Coastguard Worker * have valid values, is derived from the Vulkan spec sections for
1011*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo, VkGraphicsPipelineLibraryCreateInfoEXT, and
1012*61046927SAndroid Build Coastguard Worker * VkPipelineLibraryCreateInfoKHR. As of Vulkan 1.3.255, the spec text and VUs
1013*61046927SAndroid Build Coastguard Worker * still contain inconsistencies regarding the validity of struct members, so
1014*61046927SAndroid Build Coastguard Worker * read it carefully. Many of the VUs were written before
1015*61046927SAndroid Build Coastguard Worker * VK_EXT_graphics_pipeline_library and never updated. (Lina's advice: Focus
1016*61046927SAndroid Build Coastguard Worker * primarily on understanding the non-VU text, and use VUs to verify your
1017*61046927SAndroid Build Coastguard Worker * comprehension).
1018*61046927SAndroid Build Coastguard Worker */
1019*61046927SAndroid Build Coastguard Worker static void
vn_graphics_pipeline_state_fill(const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_state * restrict state,struct vn_graphics_pipeline_fix_desc * out_fix_desc)1020*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_state_fill(
1021*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
1022*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_state *restrict state,
1023*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_desc *out_fix_desc)
1024*61046927SAndroid Build Coastguard Worker {
1025*61046927SAndroid Build Coastguard Worker /* Assume that state is already zero-filled.
1026*61046927SAndroid Build Coastguard Worker *
1027*61046927SAndroid Build Coastguard Worker * Invalidate attachment_aspects.
1028*61046927SAndroid Build Coastguard Worker */
1029*61046927SAndroid Build Coastguard Worker state->render_pass.attachment_aspects = VK_IMAGE_ASPECT_METADATA_BIT;
1030*61046927SAndroid Build Coastguard Worker
1031*61046927SAndroid Build Coastguard Worker const VkPipelineRenderingCreateInfo *rendering_info =
1032*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext, PIPELINE_RENDERING_CREATE_INFO);
1033*61046927SAndroid Build Coastguard Worker const VkPipelineLibraryCreateInfoKHR *lib_info =
1034*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR);
1035*61046927SAndroid Build Coastguard Worker const uint32_t lib_count = lib_info ? lib_info->libraryCount : 0;
1036*61046927SAndroid Build Coastguard Worker
1037*61046927SAndroid Build Coastguard Worker /* This tracks which fields have valid values in the
1038*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo pNext chain.
1039*61046927SAndroid Build Coastguard Worker *
1040*61046927SAndroid Build Coastguard Worker * We initially assume that all fields are invalid. We flip fields from
1041*61046927SAndroid Build Coastguard Worker * invalid to valid as we dig through the pNext chain.
1042*61046927SAndroid Build Coastguard Worker *
1043*61046927SAndroid Build Coastguard Worker * A single field may be updated at multiple locations, therefore we update
1044*61046927SAndroid Build Coastguard Worker * with `|=` instead of `=`.
1045*61046927SAndroid Build Coastguard Worker *
1046*61046927SAndroid Build Coastguard Worker * If `valid.foo` is set, then foo has a valid value if foo exists in the
1047*61046927SAndroid Build Coastguard Worker * pNext chain. Even though NULL is not a valid pointer, NULL is considered
1048*61046927SAndroid Build Coastguard Worker * a valid *value* for a pointer-typed variable. Same for VK_NULL_HANDLE
1049*61046927SAndroid Build Coastguard Worker * and Vulkan handle-typed variables.
1050*61046927SAndroid Build Coastguard Worker *
1051*61046927SAndroid Build Coastguard Worker * Conversely, if `valid.foo` remains false at the end of this function,
1052*61046927SAndroid Build Coastguard Worker * then the Vulkan spec permits foo to have any value. If foo has a pointer
1053*61046927SAndroid Build Coastguard Worker * type, it may be an invalid pointer. If foo has a Vulkan handle type, it
1054*61046927SAndroid Build Coastguard Worker * may be an invalid handle.
1055*61046927SAndroid Build Coastguard Worker */
1056*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_desc valid = { 0 };
1057*61046927SAndroid Build Coastguard Worker
1058*61046927SAndroid Build Coastguard Worker /* Merge the linked pipeline libraries. */
1059*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < lib_count; i++) {
1060*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline *p =
1061*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_from_handle(lib_info->pLibraries[i]);
1062*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_state_merge(state, &p->state);
1063*61046927SAndroid Build Coastguard Worker }
1064*61046927SAndroid Build Coastguard Worker
1065*61046927SAndroid Build Coastguard Worker /* The VkGraphicsPipelineLibraryFlagsEXT that this pipeline provides
1066*61046927SAndroid Build Coastguard Worker * directly (without linking).
1067*61046927SAndroid Build Coastguard Worker */
1068*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_library_state direct_gpl = { 0 };
1069*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_library_state_update(info, &direct_gpl);
1070*61046927SAndroid Build Coastguard Worker
1071*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.3.251 spec:
1072*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-pLibraries-06611
1073*61046927SAndroid Build Coastguard Worker *
1074*61046927SAndroid Build Coastguard Worker * Any pipeline libraries included via
1075*61046927SAndroid Build Coastguard Worker * VkPipelineLibraryCreateInfoKHR::pLibraries must not include any state
1076*61046927SAndroid Build Coastguard Worker * subset already defined by this structure or defined by any other
1077*61046927SAndroid Build Coastguard Worker * pipeline library in VkPipelineLibraryCreateInfoKHR::pLibraries
1078*61046927SAndroid Build Coastguard Worker */
1079*61046927SAndroid Build Coastguard Worker assert(!(direct_gpl.mask & state->gpl.mask));
1080*61046927SAndroid Build Coastguard Worker
1081*61046927SAndroid Build Coastguard Worker /* Collect orthogonal state that is common to multiple GPL state subsets. */
1082*61046927SAndroid Build Coastguard Worker vn_graphics_dynamic_state_update(info, direct_gpl, &state->dynamic);
1083*61046927SAndroid Build Coastguard Worker vn_graphics_shader_stages_update(info, direct_gpl, &valid,
1084*61046927SAndroid Build Coastguard Worker &state->shader_stages);
1085*61046927SAndroid Build Coastguard Worker vn_render_pass_state_update(info, direct_gpl, &valid, &state->render_pass);
1086*61046927SAndroid Build Coastguard Worker
1087*61046927SAndroid Build Coastguard Worker /* Collect remaining pre-raster shaders state.
1088*61046927SAndroid Build Coastguard Worker *
1089*61046927SAndroid Build Coastguard Worker * Of the remaining state, we must first collect the pre-raster shaders
1090*61046927SAndroid Build Coastguard Worker * state because it influences how the other state is collected.
1091*61046927SAndroid Build Coastguard Worker */
1092*61046927SAndroid Build Coastguard Worker if (direct_gpl.pre_raster_shaders) {
1093*61046927SAndroid Build Coastguard Worker valid.self.tessellation_state |=
1094*61046927SAndroid Build Coastguard Worker (bool)(state->shader_stages &
1095*61046927SAndroid Build Coastguard Worker (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
1096*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
1097*61046927SAndroid Build Coastguard Worker valid.self.rasterization_state = true;
1098*61046927SAndroid Build Coastguard Worker valid.self.pipeline_layout = true;
1099*61046927SAndroid Build Coastguard Worker
1100*61046927SAndroid Build Coastguard Worker if (info->pRasterizationState) {
1101*61046927SAndroid Build Coastguard Worker state->rasterizer_discard_enable =
1102*61046927SAndroid Build Coastguard Worker info->pRasterizationState->rasterizerDiscardEnable;
1103*61046927SAndroid Build Coastguard Worker }
1104*61046927SAndroid Build Coastguard Worker
1105*61046927SAndroid Build Coastguard Worker const bool is_raster_statically_disabled =
1106*61046927SAndroid Build Coastguard Worker !state->dynamic.rasterizer_discard_enable &&
1107*61046927SAndroid Build Coastguard Worker state->rasterizer_discard_enable;
1108*61046927SAndroid Build Coastguard Worker
1109*61046927SAndroid Build Coastguard Worker if (!is_raster_statically_disabled) {
1110*61046927SAndroid Build Coastguard Worker valid.self.viewport_state = true;
1111*61046927SAndroid Build Coastguard Worker
1112*61046927SAndroid Build Coastguard Worker valid.self.viewport_state_viewports =
1113*61046927SAndroid Build Coastguard Worker !state->dynamic.viewport && !state->dynamic.viewport_with_count;
1114*61046927SAndroid Build Coastguard Worker
1115*61046927SAndroid Build Coastguard Worker valid.self.viewport_state_scissors =
1116*61046927SAndroid Build Coastguard Worker !state->dynamic.scissor && !state->dynamic.scissor_with_count;
1117*61046927SAndroid Build Coastguard Worker }
1118*61046927SAndroid Build Coastguard Worker
1119*61046927SAndroid Build Coastguard Worker /* Defer setting the flag until all its state is filled. */
1120*61046927SAndroid Build Coastguard Worker state->gpl.pre_raster_shaders = true;
1121*61046927SAndroid Build Coastguard Worker }
1122*61046927SAndroid Build Coastguard Worker
1123*61046927SAndroid Build Coastguard Worker /* Collect remaining vertex input interface state.
1124*61046927SAndroid Build Coastguard Worker *
1125*61046927SAndroid Build Coastguard Worker * TODO(VK_EXT_mesh_shader): Update.
1126*61046927SAndroid Build Coastguard Worker */
1127*61046927SAndroid Build Coastguard Worker if (direct_gpl.vertex_input) {
1128*61046927SAndroid Build Coastguard Worker const bool may_have_vertex_shader =
1129*61046927SAndroid Build Coastguard Worker !state->gpl.pre_raster_shaders ||
1130*61046927SAndroid Build Coastguard Worker (state->shader_stages & VK_SHADER_STAGE_VERTEX_BIT);
1131*61046927SAndroid Build Coastguard Worker
1132*61046927SAndroid Build Coastguard Worker valid.self.vertex_input_state |=
1133*61046927SAndroid Build Coastguard Worker may_have_vertex_shader && !state->dynamic.vertex_input;
1134*61046927SAndroid Build Coastguard Worker
1135*61046927SAndroid Build Coastguard Worker valid.self.input_assembly_state |= may_have_vertex_shader;
1136*61046927SAndroid Build Coastguard Worker
1137*61046927SAndroid Build Coastguard Worker /* Defer setting the flag until all its state is filled. */
1138*61046927SAndroid Build Coastguard Worker state->gpl.vertex_input = true;
1139*61046927SAndroid Build Coastguard Worker }
1140*61046927SAndroid Build Coastguard Worker
1141*61046927SAndroid Build Coastguard Worker /* Does this pipeline have rasterization statically disabled? If disabled,
1142*61046927SAndroid Build Coastguard Worker * then this pipeline does not directly provide fragment shader state nor
1143*61046927SAndroid Build Coastguard Worker * fragment output state.
1144*61046927SAndroid Build Coastguard Worker *
1145*61046927SAndroid Build Coastguard Worker * About fragment shader state, the Vulkan 1.3.254 spec says:
1146*61046927SAndroid Build Coastguard Worker *
1147*61046927SAndroid Build Coastguard Worker * If a pipeline specifies pre-rasterization state either directly or by
1148*61046927SAndroid Build Coastguard Worker * including it as a pipeline library and rasterizerDiscardEnable is set
1149*61046927SAndroid Build Coastguard Worker * to VK_FALSE or VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE is used,
1150*61046927SAndroid Build Coastguard Worker * this state must be specified to create a complete graphics pipeline.
1151*61046927SAndroid Build Coastguard Worker *
1152*61046927SAndroid Build Coastguard Worker * If a pipeline includes
1153*61046927SAndroid Build Coastguard Worker * VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT in
1154*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineLibraryCreateInfoEXT::flags either explicitly or as
1155*61046927SAndroid Build Coastguard Worker * a default, and either the conditions requiring this state for
1156*61046927SAndroid Build Coastguard Worker * a complete graphics pipeline are met or this pipeline does not
1157*61046927SAndroid Build Coastguard Worker * specify pre-rasterization state in any way, that pipeline must
1158*61046927SAndroid Build Coastguard Worker * specify this state directly.
1159*61046927SAndroid Build Coastguard Worker *
1160*61046927SAndroid Build Coastguard Worker * About fragment output state, the Vulkan 1.3.254 spec says the same, but
1161*61046927SAndroid Build Coastguard Worker * with VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT.
1162*61046927SAndroid Build Coastguard Worker */
1163*61046927SAndroid Build Coastguard Worker const bool is_raster_statically_disabled =
1164*61046927SAndroid Build Coastguard Worker state->gpl.pre_raster_shaders &&
1165*61046927SAndroid Build Coastguard Worker !state->dynamic.rasterizer_discard_enable &&
1166*61046927SAndroid Build Coastguard Worker state->rasterizer_discard_enable;
1167*61046927SAndroid Build Coastguard Worker
1168*61046927SAndroid Build Coastguard Worker /* Collect remaining fragment shader state. */
1169*61046927SAndroid Build Coastguard Worker if (direct_gpl.fragment_shader) {
1170*61046927SAndroid Build Coastguard Worker if (!is_raster_statically_disabled) {
1171*61046927SAndroid Build Coastguard Worker /* Validity of pMultisampleState is easy here.
1172*61046927SAndroid Build Coastguard Worker *
1173*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-pMultisampleState-06629
1174*61046927SAndroid Build Coastguard Worker *
1175*61046927SAndroid Build Coastguard Worker * If the pipeline requires fragment shader state
1176*61046927SAndroid Build Coastguard Worker * pMultisampleState must be NULL or a valid pointer to a valid
1177*61046927SAndroid Build Coastguard Worker * VkPipelineMultisampleStateCreateInfo structure
1178*61046927SAndroid Build Coastguard Worker */
1179*61046927SAndroid Build Coastguard Worker valid.self.multisample_state = true;
1180*61046927SAndroid Build Coastguard Worker
1181*61046927SAndroid Build Coastguard Worker valid.self.multisample_state_sample_mask =
1182*61046927SAndroid Build Coastguard Worker !state->dynamic.sample_mask;
1183*61046927SAndroid Build Coastguard Worker
1184*61046927SAndroid Build Coastguard Worker if ((state->render_pass.attachment_aspects &
1185*61046927SAndroid Build Coastguard Worker (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
1186*61046927SAndroid Build Coastguard Worker valid.self.depth_stencil_state = true;
1187*61046927SAndroid Build Coastguard Worker } else if (state->render_pass.attachment_aspects ==
1188*61046927SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_METADATA_BIT &&
1189*61046927SAndroid Build Coastguard Worker (info->flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR)) {
1190*61046927SAndroid Build Coastguard Worker /* The app has not yet provided render pass info, neither directly
1191*61046927SAndroid Build Coastguard Worker * in this VkGraphicsPipelineCreateInfo nor in any linked pipeline
1192*61046927SAndroid Build Coastguard Worker * libraries. Therefore we do not know if the final complete
1193*61046927SAndroid Build Coastguard Worker * pipeline will have any depth or stencil attachments. If the
1194*61046927SAndroid Build Coastguard Worker * final complete pipeline does have depth or stencil attachments,
1195*61046927SAndroid Build Coastguard Worker * then the pipeline will use
1196*61046927SAndroid Build Coastguard Worker * VkPipelineDepthStencilStateCreateInfo. Therefore, we must not
1197*61046927SAndroid Build Coastguard Worker * ignore it.
1198*61046927SAndroid Build Coastguard Worker */
1199*61046927SAndroid Build Coastguard Worker valid.self.depth_stencil_state = true;
1200*61046927SAndroid Build Coastguard Worker }
1201*61046927SAndroid Build Coastguard Worker
1202*61046927SAndroid Build Coastguard Worker valid.self.pipeline_layout = true;
1203*61046927SAndroid Build Coastguard Worker }
1204*61046927SAndroid Build Coastguard Worker
1205*61046927SAndroid Build Coastguard Worker /* Defer setting the flag until all its state is filled. */
1206*61046927SAndroid Build Coastguard Worker state->gpl.fragment_shader = true;
1207*61046927SAndroid Build Coastguard Worker }
1208*61046927SAndroid Build Coastguard Worker
1209*61046927SAndroid Build Coastguard Worker /* Collect remaining fragment output interface state. */
1210*61046927SAndroid Build Coastguard Worker if (direct_gpl.fragment_output) {
1211*61046927SAndroid Build Coastguard Worker if (!is_raster_statically_disabled) {
1212*61046927SAndroid Build Coastguard Worker /* Validity of pMultisampleState is easy here.
1213*61046927SAndroid Build Coastguard Worker *
1214*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751
1215*61046927SAndroid Build Coastguard Worker *
1216*61046927SAndroid Build Coastguard Worker * If the pipeline requires fragment output interface state,
1217*61046927SAndroid Build Coastguard Worker * pMultisampleState must be a valid pointer to a valid
1218*61046927SAndroid Build Coastguard Worker * VkPipelineMultisampleStateCreateInfo structure
1219*61046927SAndroid Build Coastguard Worker */
1220*61046927SAndroid Build Coastguard Worker valid.self.multisample_state = true;
1221*61046927SAndroid Build Coastguard Worker
1222*61046927SAndroid Build Coastguard Worker valid.self.multisample_state_sample_mask =
1223*61046927SAndroid Build Coastguard Worker !state->dynamic.sample_mask;
1224*61046927SAndroid Build Coastguard Worker
1225*61046927SAndroid Build Coastguard Worker valid.self.color_blend_state |=
1226*61046927SAndroid Build Coastguard Worker (bool)(state->render_pass.attachment_aspects &
1227*61046927SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT);
1228*61046927SAndroid Build Coastguard Worker valid.self.depth_stencil_state |=
1229*61046927SAndroid Build Coastguard Worker (bool)(state->render_pass.attachment_aspects &
1230*61046927SAndroid Build Coastguard Worker (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1231*61046927SAndroid Build Coastguard Worker }
1232*61046927SAndroid Build Coastguard Worker
1233*61046927SAndroid Build Coastguard Worker /* Defer setting the flag until all its state is filled. */
1234*61046927SAndroid Build Coastguard Worker state->gpl.fragment_output = true;
1235*61046927SAndroid Build Coastguard Worker }
1236*61046927SAndroid Build Coastguard Worker
1237*61046927SAndroid Build Coastguard Worker /* After direct_gpl states collection, check the final state to validate
1238*61046927SAndroid Build Coastguard Worker * VkPipelineLayout in case of being the final layout in linked pipeline.
1239*61046927SAndroid Build Coastguard Worker *
1240*61046927SAndroid Build Coastguard Worker * From the Vulkan 1.3.275 spec:
1241*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-layout-06602
1242*61046927SAndroid Build Coastguard Worker *
1243*61046927SAndroid Build Coastguard Worker * If the pipeline requires fragment shader state or pre-rasterization
1244*61046927SAndroid Build Coastguard Worker * shader state, layout must be a valid VkPipelineLayout handle
1245*61046927SAndroid Build Coastguard Worker */
1246*61046927SAndroid Build Coastguard Worker if ((state->gpl.fragment_shader && !is_raster_statically_disabled) ||
1247*61046927SAndroid Build Coastguard Worker state->gpl.pre_raster_shaders)
1248*61046927SAndroid Build Coastguard Worker valid.self.pipeline_layout = true;
1249*61046927SAndroid Build Coastguard Worker
1250*61046927SAndroid Build Coastguard Worker /* Pipeline Derivatives
1251*61046927SAndroid Build Coastguard Worker *
1252*61046927SAndroid Build Coastguard Worker * VUID-VkGraphicsPipelineCreateInfo-flags-07984
1253*61046927SAndroid Build Coastguard Worker *
1254*61046927SAndroid Build Coastguard Worker * If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and
1255*61046927SAndroid Build Coastguard Worker * basePipelineIndex is -1, basePipelineHandle must be a valid graphics
1256*61046927SAndroid Build Coastguard Worker * VkPipeline handle
1257*61046927SAndroid Build Coastguard Worker */
1258*61046927SAndroid Build Coastguard Worker if ((info->flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) &&
1259*61046927SAndroid Build Coastguard Worker info->basePipelineIndex == -1)
1260*61046927SAndroid Build Coastguard Worker valid.self.base_pipeline_handle = true;
1261*61046927SAndroid Build Coastguard Worker
1262*61046927SAndroid Build Coastguard Worker *out_fix_desc = (struct vn_graphics_pipeline_fix_desc) {
1263*61046927SAndroid Build Coastguard Worker .self = {
1264*61046927SAndroid Build Coastguard Worker /* clang-format off */
1265*61046927SAndroid Build Coastguard Worker .shader_stages =
1266*61046927SAndroid Build Coastguard Worker !valid.self.shader_stages &&
1267*61046927SAndroid Build Coastguard Worker info->pStages,
1268*61046927SAndroid Build Coastguard Worker .vertex_input_state =
1269*61046927SAndroid Build Coastguard Worker !valid.self.vertex_input_state &&
1270*61046927SAndroid Build Coastguard Worker info->pVertexInputState,
1271*61046927SAndroid Build Coastguard Worker .input_assembly_state =
1272*61046927SAndroid Build Coastguard Worker !valid.self.input_assembly_state &&
1273*61046927SAndroid Build Coastguard Worker info->pInputAssemblyState,
1274*61046927SAndroid Build Coastguard Worker .tessellation_state =
1275*61046927SAndroid Build Coastguard Worker !valid.self.tessellation_state &&
1276*61046927SAndroid Build Coastguard Worker info->pTessellationState,
1277*61046927SAndroid Build Coastguard Worker .viewport_state =
1278*61046927SAndroid Build Coastguard Worker !valid.self.viewport_state &&
1279*61046927SAndroid Build Coastguard Worker info->pViewportState,
1280*61046927SAndroid Build Coastguard Worker .viewport_state_viewports =
1281*61046927SAndroid Build Coastguard Worker !valid.self.viewport_state_viewports &&
1282*61046927SAndroid Build Coastguard Worker valid.self.viewport_state &&
1283*61046927SAndroid Build Coastguard Worker info->pViewportState &&
1284*61046927SAndroid Build Coastguard Worker info->pViewportState->pViewports &&
1285*61046927SAndroid Build Coastguard Worker info->pViewportState->viewportCount,
1286*61046927SAndroid Build Coastguard Worker .viewport_state_scissors =
1287*61046927SAndroid Build Coastguard Worker !valid.self.viewport_state_scissors &&
1288*61046927SAndroid Build Coastguard Worker valid.self.viewport_state &&
1289*61046927SAndroid Build Coastguard Worker info->pViewportState &&
1290*61046927SAndroid Build Coastguard Worker info->pViewportState->pScissors &&
1291*61046927SAndroid Build Coastguard Worker info->pViewportState->scissorCount,
1292*61046927SAndroid Build Coastguard Worker .rasterization_state =
1293*61046927SAndroid Build Coastguard Worker !valid.self.rasterization_state &&
1294*61046927SAndroid Build Coastguard Worker info->pRasterizationState,
1295*61046927SAndroid Build Coastguard Worker .multisample_state =
1296*61046927SAndroid Build Coastguard Worker !valid.self.multisample_state &&
1297*61046927SAndroid Build Coastguard Worker info->pMultisampleState,
1298*61046927SAndroid Build Coastguard Worker .multisample_state_sample_mask =
1299*61046927SAndroid Build Coastguard Worker !valid.self.multisample_state_sample_mask &&
1300*61046927SAndroid Build Coastguard Worker valid.self.multisample_state &&
1301*61046927SAndroid Build Coastguard Worker info->pMultisampleState &&
1302*61046927SAndroid Build Coastguard Worker info->pMultisampleState->pSampleMask,
1303*61046927SAndroid Build Coastguard Worker .depth_stencil_state =
1304*61046927SAndroid Build Coastguard Worker !valid.self.depth_stencil_state &&
1305*61046927SAndroid Build Coastguard Worker info->pDepthStencilState,
1306*61046927SAndroid Build Coastguard Worker .color_blend_state =
1307*61046927SAndroid Build Coastguard Worker !valid.self.color_blend_state &&
1308*61046927SAndroid Build Coastguard Worker info->pColorBlendState,
1309*61046927SAndroid Build Coastguard Worker .pipeline_layout =
1310*61046927SAndroid Build Coastguard Worker !valid.self.pipeline_layout &&
1311*61046927SAndroid Build Coastguard Worker info->layout,
1312*61046927SAndroid Build Coastguard Worker .render_pass =
1313*61046927SAndroid Build Coastguard Worker !valid.self.render_pass &&
1314*61046927SAndroid Build Coastguard Worker info->renderPass,
1315*61046927SAndroid Build Coastguard Worker .base_pipeline_handle =
1316*61046927SAndroid Build Coastguard Worker !valid.self.base_pipeline_handle &&
1317*61046927SAndroid Build Coastguard Worker info->basePipelineHandle,
1318*61046927SAndroid Build Coastguard Worker /* clang-format on */
1319*61046927SAndroid Build Coastguard Worker },
1320*61046927SAndroid Build Coastguard Worker .pnext = {
1321*61046927SAndroid Build Coastguard Worker /* clang-format off */
1322*61046927SAndroid Build Coastguard Worker .rendering_info_formats =
1323*61046927SAndroid Build Coastguard Worker !valid.pnext.rendering_info_formats &&
1324*61046927SAndroid Build Coastguard Worker rendering_info &&
1325*61046927SAndroid Build Coastguard Worker rendering_info->pColorAttachmentFormats &&
1326*61046927SAndroid Build Coastguard Worker rendering_info->colorAttachmentCount,
1327*61046927SAndroid Build Coastguard Worker /* clang-format on */
1328*61046927SAndroid Build Coastguard Worker },
1329*61046927SAndroid Build Coastguard Worker };
1330*61046927SAndroid Build Coastguard Worker }
1331*61046927SAndroid Build Coastguard Worker
1332*61046927SAndroid Build Coastguard Worker static void
vn_fix_graphics_pipeline_create_info_self(const struct vn_graphics_pipeline_info_self * ignore,const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_fix_tmp * fix_tmp,uint32_t index)1333*61046927SAndroid Build Coastguard Worker vn_fix_graphics_pipeline_create_info_self(
1334*61046927SAndroid Build Coastguard Worker const struct vn_graphics_pipeline_info_self *ignore,
1335*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
1336*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp *fix_tmp,
1337*61046927SAndroid Build Coastguard Worker uint32_t index)
1338*61046927SAndroid Build Coastguard Worker {
1339*61046927SAndroid Build Coastguard Worker /* VkGraphicsPipelineCreateInfo */
1340*61046927SAndroid Build Coastguard Worker if (ignore->shader_stages) {
1341*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].stageCount = 0;
1342*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pStages = NULL;
1343*61046927SAndroid Build Coastguard Worker }
1344*61046927SAndroid Build Coastguard Worker if (ignore->vertex_input_state)
1345*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pVertexInputState = NULL;
1346*61046927SAndroid Build Coastguard Worker if (ignore->input_assembly_state)
1347*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pInputAssemblyState = NULL;
1348*61046927SAndroid Build Coastguard Worker if (ignore->tessellation_state)
1349*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pTessellationState = NULL;
1350*61046927SAndroid Build Coastguard Worker if (ignore->viewport_state)
1351*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pViewportState = NULL;
1352*61046927SAndroid Build Coastguard Worker if (ignore->rasterization_state)
1353*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pRasterizationState = NULL;
1354*61046927SAndroid Build Coastguard Worker if (ignore->multisample_state)
1355*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pMultisampleState = NULL;
1356*61046927SAndroid Build Coastguard Worker if (ignore->depth_stencil_state)
1357*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pDepthStencilState = NULL;
1358*61046927SAndroid Build Coastguard Worker if (ignore->color_blend_state)
1359*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pColorBlendState = NULL;
1360*61046927SAndroid Build Coastguard Worker if (ignore->pipeline_layout)
1361*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].layout = VK_NULL_HANDLE;
1362*61046927SAndroid Build Coastguard Worker if (ignore->base_pipeline_handle)
1363*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].basePipelineHandle = VK_NULL_HANDLE;
1364*61046927SAndroid Build Coastguard Worker
1365*61046927SAndroid Build Coastguard Worker /* VkPipelineMultisampleStateCreateInfo */
1366*61046927SAndroid Build Coastguard Worker if (ignore->multisample_state_sample_mask) {
1367*61046927SAndroid Build Coastguard Worker /* Swap original pMultisampleState with temporary state. */
1368*61046927SAndroid Build Coastguard Worker fix_tmp->multisample_state_infos[index] = *info->pMultisampleState;
1369*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pMultisampleState =
1370*61046927SAndroid Build Coastguard Worker &fix_tmp->multisample_state_infos[index];
1371*61046927SAndroid Build Coastguard Worker
1372*61046927SAndroid Build Coastguard Worker fix_tmp->multisample_state_infos[index].pSampleMask = NULL;
1373*61046927SAndroid Build Coastguard Worker }
1374*61046927SAndroid Build Coastguard Worker
1375*61046927SAndroid Build Coastguard Worker /* VkPipelineViewportStateCreateInfo */
1376*61046927SAndroid Build Coastguard Worker if (ignore->viewport_state_viewports || ignore->viewport_state_scissors) {
1377*61046927SAndroid Build Coastguard Worker /* Swap original pViewportState with temporary state. */
1378*61046927SAndroid Build Coastguard Worker fix_tmp->viewport_state_infos[index] = *info->pViewportState;
1379*61046927SAndroid Build Coastguard Worker fix_tmp->infos[index].pViewportState =
1380*61046927SAndroid Build Coastguard Worker &fix_tmp->viewport_state_infos[index];
1381*61046927SAndroid Build Coastguard Worker
1382*61046927SAndroid Build Coastguard Worker if (ignore->viewport_state_viewports)
1383*61046927SAndroid Build Coastguard Worker fix_tmp->viewport_state_infos[index].pViewports = NULL;
1384*61046927SAndroid Build Coastguard Worker if (ignore->viewport_state_scissors)
1385*61046927SAndroid Build Coastguard Worker fix_tmp->viewport_state_infos[index].pScissors = NULL;
1386*61046927SAndroid Build Coastguard Worker }
1387*61046927SAndroid Build Coastguard Worker }
1388*61046927SAndroid Build Coastguard Worker
1389*61046927SAndroid Build Coastguard Worker static void
vn_graphics_pipeline_create_info_pnext_init(const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_fix_tmp * fix_tmp,uint32_t index)1390*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_create_info_pnext_init(
1391*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
1392*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp *fix_tmp,
1393*61046927SAndroid Build Coastguard Worker uint32_t index)
1394*61046927SAndroid Build Coastguard Worker {
1395*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineLibraryCreateInfoEXT *gpl = &fix_tmp->gpl_infos[index];
1396*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedbackCreateInfo *feedback =
1397*61046927SAndroid Build Coastguard Worker &fix_tmp->feedback_infos[index];
1398*61046927SAndroid Build Coastguard Worker VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr =
1399*61046927SAndroid Build Coastguard Worker &fix_tmp->fsr_infos[index];
1400*61046927SAndroid Build Coastguard Worker VkPipelineLibraryCreateInfoKHR *library = &fix_tmp->library_infos[index];
1401*61046927SAndroid Build Coastguard Worker VkPipelineRenderingCreateInfo *rendering =
1402*61046927SAndroid Build Coastguard Worker &fix_tmp->rendering_infos[index];
1403*61046927SAndroid Build Coastguard Worker
1404*61046927SAndroid Build Coastguard Worker VkBaseOutStructure *cur = (void *)&fix_tmp->infos[index];
1405*61046927SAndroid Build Coastguard Worker
1406*61046927SAndroid Build Coastguard Worker vk_foreach_struct_const(src, info->pNext) {
1407*61046927SAndroid Build Coastguard Worker void *next = NULL;
1408*61046927SAndroid Build Coastguard Worker switch (src->sType) {
1409*61046927SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT:
1410*61046927SAndroid Build Coastguard Worker memcpy(gpl, src, sizeof(*gpl));
1411*61046927SAndroid Build Coastguard Worker next = gpl;
1412*61046927SAndroid Build Coastguard Worker break;
1413*61046927SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO:
1414*61046927SAndroid Build Coastguard Worker memcpy(feedback, src, sizeof(*feedback));
1415*61046927SAndroid Build Coastguard Worker next = feedback;
1416*61046927SAndroid Build Coastguard Worker break;
1417*61046927SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR:
1418*61046927SAndroid Build Coastguard Worker memcpy(fsr, src, sizeof(*fsr));
1419*61046927SAndroid Build Coastguard Worker next = fsr;
1420*61046927SAndroid Build Coastguard Worker break;
1421*61046927SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR:
1422*61046927SAndroid Build Coastguard Worker memcpy(library, src, sizeof(*library));
1423*61046927SAndroid Build Coastguard Worker next = library;
1424*61046927SAndroid Build Coastguard Worker break;
1425*61046927SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO:
1426*61046927SAndroid Build Coastguard Worker memcpy(rendering, src, sizeof(*rendering));
1427*61046927SAndroid Build Coastguard Worker next = rendering;
1428*61046927SAndroid Build Coastguard Worker break;
1429*61046927SAndroid Build Coastguard Worker default:
1430*61046927SAndroid Build Coastguard Worker break;
1431*61046927SAndroid Build Coastguard Worker }
1432*61046927SAndroid Build Coastguard Worker
1433*61046927SAndroid Build Coastguard Worker if (next) {
1434*61046927SAndroid Build Coastguard Worker cur->pNext = next;
1435*61046927SAndroid Build Coastguard Worker cur = next;
1436*61046927SAndroid Build Coastguard Worker }
1437*61046927SAndroid Build Coastguard Worker }
1438*61046927SAndroid Build Coastguard Worker
1439*61046927SAndroid Build Coastguard Worker cur->pNext = NULL;
1440*61046927SAndroid Build Coastguard Worker }
1441*61046927SAndroid Build Coastguard Worker
1442*61046927SAndroid Build Coastguard Worker static void
vn_fix_graphics_pipeline_create_info_pnext(const struct vn_graphics_pipeline_info_pnext * ignore,const VkGraphicsPipelineCreateInfo * info,struct vn_graphics_pipeline_fix_tmp * fix_tmp,uint32_t index)1443*61046927SAndroid Build Coastguard Worker vn_fix_graphics_pipeline_create_info_pnext(
1444*61046927SAndroid Build Coastguard Worker const struct vn_graphics_pipeline_info_pnext *ignore,
1445*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
1446*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp *fix_tmp,
1447*61046927SAndroid Build Coastguard Worker uint32_t index)
1448*61046927SAndroid Build Coastguard Worker {
1449*61046927SAndroid Build Coastguard Worker /* initialize pNext chain with allocated tmp storage */
1450*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_create_info_pnext_init(info, fix_tmp, index);
1451*61046927SAndroid Build Coastguard Worker
1452*61046927SAndroid Build Coastguard Worker /* VkPipelineRenderingCreateInfo */
1453*61046927SAndroid Build Coastguard Worker if (ignore->rendering_info_formats) {
1454*61046927SAndroid Build Coastguard Worker fix_tmp->rendering_infos[index].colorAttachmentCount = 0;
1455*61046927SAndroid Build Coastguard Worker fix_tmp->rendering_infos[index].pColorAttachmentFormats = NULL;
1456*61046927SAndroid Build Coastguard Worker }
1457*61046927SAndroid Build Coastguard Worker }
1458*61046927SAndroid Build Coastguard Worker
1459*61046927SAndroid Build Coastguard Worker static const VkGraphicsPipelineCreateInfo *
vn_fix_graphics_pipeline_create_infos(struct vn_device * dev,uint32_t info_count,const VkGraphicsPipelineCreateInfo * infos,const struct vn_graphics_pipeline_fix_desc fix_descs[info_count],struct vn_graphics_pipeline_fix_tmp ** out_fix_tmp,const VkAllocationCallbacks * alloc)1460*61046927SAndroid Build Coastguard Worker vn_fix_graphics_pipeline_create_infos(
1461*61046927SAndroid Build Coastguard Worker struct vn_device *dev,
1462*61046927SAndroid Build Coastguard Worker uint32_t info_count,
1463*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *infos,
1464*61046927SAndroid Build Coastguard Worker const struct vn_graphics_pipeline_fix_desc fix_descs[info_count],
1465*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp **out_fix_tmp,
1466*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
1467*61046927SAndroid Build Coastguard Worker {
1468*61046927SAndroid Build Coastguard Worker uint32_t self_mask = 0;
1469*61046927SAndroid Build Coastguard Worker uint32_t pnext_mask = 0;
1470*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info_count; i++) {
1471*61046927SAndroid Build Coastguard Worker self_mask |= fix_descs[i].self.mask;
1472*61046927SAndroid Build Coastguard Worker pnext_mask |= fix_descs[i].pnext.mask;
1473*61046927SAndroid Build Coastguard Worker }
1474*61046927SAndroid Build Coastguard Worker
1475*61046927SAndroid Build Coastguard Worker if (!self_mask && !pnext_mask) {
1476*61046927SAndroid Build Coastguard Worker /* No fix is needed. */
1477*61046927SAndroid Build Coastguard Worker *out_fix_tmp = NULL;
1478*61046927SAndroid Build Coastguard Worker return infos;
1479*61046927SAndroid Build Coastguard Worker }
1480*61046927SAndroid Build Coastguard Worker
1481*61046927SAndroid Build Coastguard Worker /* tell whether fixes are applied in tracing */
1482*61046927SAndroid Build Coastguard Worker VN_TRACE_SCOPE("sanitize pipeline");
1483*61046927SAndroid Build Coastguard Worker
1484*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp *fix_tmp =
1485*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_fix_tmp_alloc(alloc, info_count, pnext_mask);
1486*61046927SAndroid Build Coastguard Worker if (!fix_tmp)
1487*61046927SAndroid Build Coastguard Worker return NULL;
1488*61046927SAndroid Build Coastguard Worker
1489*61046927SAndroid Build Coastguard Worker memcpy(fix_tmp->infos, infos, info_count * sizeof(infos[0]));
1490*61046927SAndroid Build Coastguard Worker
1491*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info_count; i++) {
1492*61046927SAndroid Build Coastguard Worker if (fix_descs[i].self.mask) {
1493*61046927SAndroid Build Coastguard Worker vn_fix_graphics_pipeline_create_info_self(&fix_descs[i].self,
1494*61046927SAndroid Build Coastguard Worker &infos[i], fix_tmp, i);
1495*61046927SAndroid Build Coastguard Worker }
1496*61046927SAndroid Build Coastguard Worker if (fix_descs[i].pnext.mask) {
1497*61046927SAndroid Build Coastguard Worker vn_fix_graphics_pipeline_create_info_pnext(&fix_descs[i].pnext,
1498*61046927SAndroid Build Coastguard Worker &infos[i], fix_tmp, i);
1499*61046927SAndroid Build Coastguard Worker }
1500*61046927SAndroid Build Coastguard Worker }
1501*61046927SAndroid Build Coastguard Worker
1502*61046927SAndroid Build Coastguard Worker *out_fix_tmp = fix_tmp;
1503*61046927SAndroid Build Coastguard Worker return fix_tmp->infos;
1504*61046927SAndroid Build Coastguard Worker }
1505*61046927SAndroid Build Coastguard Worker
1506*61046927SAndroid Build Coastguard Worker /**
1507*61046927SAndroid Build Coastguard Worker * We invalidate each VkPipelineCreationFeedback. This is a legal but useless
1508*61046927SAndroid Build Coastguard Worker * implementation.
1509*61046927SAndroid Build Coastguard Worker *
1510*61046927SAndroid Build Coastguard Worker * We invalidate because the venus protocol (as of 2022-08-25) does not know
1511*61046927SAndroid Build Coastguard Worker * that the VkPipelineCreationFeedback structs in the
1512*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo pNext are output parameters. Before
1513*61046927SAndroid Build Coastguard Worker * VK_EXT_pipeline_creation_feedback, the pNext chain was input-only.
1514*61046927SAndroid Build Coastguard Worker */
1515*61046927SAndroid Build Coastguard Worker static void
vn_invalidate_pipeline_creation_feedback(const VkBaseInStructure * chain)1516*61046927SAndroid Build Coastguard Worker vn_invalidate_pipeline_creation_feedback(const VkBaseInStructure *chain)
1517*61046927SAndroid Build Coastguard Worker {
1518*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedbackCreateInfo *feedback_info =
1519*61046927SAndroid Build Coastguard Worker vk_find_struct_const(chain, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
1520*61046927SAndroid Build Coastguard Worker
1521*61046927SAndroid Build Coastguard Worker if (!feedback_info)
1522*61046927SAndroid Build Coastguard Worker return;
1523*61046927SAndroid Build Coastguard Worker
1524*61046927SAndroid Build Coastguard Worker feedback_info->pPipelineCreationFeedback->flags = 0;
1525*61046927SAndroid Build Coastguard Worker
1526*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < feedback_info->pipelineStageCreationFeedbackCount;
1527*61046927SAndroid Build Coastguard Worker i++)
1528*61046927SAndroid Build Coastguard Worker feedback_info->pPipelineStageCreationFeedbacks[i].flags = 0;
1529*61046927SAndroid Build Coastguard Worker }
1530*61046927SAndroid Build Coastguard Worker
1531*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateGraphicsPipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)1532*61046927SAndroid Build Coastguard Worker vn_CreateGraphicsPipelines(VkDevice device,
1533*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
1534*61046927SAndroid Build Coastguard Worker uint32_t createInfoCount,
1535*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfos,
1536*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
1537*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
1538*61046927SAndroid Build Coastguard Worker {
1539*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
1540*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc =
1541*61046927SAndroid Build Coastguard Worker pAllocator ? pAllocator : &dev->base.base.alloc;
1542*61046927SAndroid Build Coastguard Worker bool want_sync = false;
1543*61046927SAndroid Build Coastguard Worker VkResult result;
1544*61046927SAndroid Build Coastguard Worker
1545*61046927SAndroid Build Coastguard Worker /* silence -Wmaybe-uninitialized false alarm on release build with gcc */
1546*61046927SAndroid Build Coastguard Worker if (!createInfoCount)
1547*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1548*61046927SAndroid Build Coastguard Worker
1549*61046927SAndroid Build Coastguard Worker memset(pPipelines, 0, sizeof(*pPipelines) * createInfoCount);
1550*61046927SAndroid Build Coastguard Worker
1551*61046927SAndroid Build Coastguard Worker if (!vn_create_pipeline_handles(dev, VN_PIPELINE_TYPE_GRAPHICS,
1552*61046927SAndroid Build Coastguard Worker createInfoCount, pPipelines, alloc)) {
1553*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1554*61046927SAndroid Build Coastguard Worker }
1555*61046927SAndroid Build Coastguard Worker
1556*61046927SAndroid Build Coastguard Worker STACK_ARRAY(struct vn_graphics_pipeline_fix_desc, fix_descs,
1557*61046927SAndroid Build Coastguard Worker createInfoCount);
1558*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < createInfoCount; i++) {
1559*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline *pipeline =
1560*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_from_handle(pPipelines[i]);
1561*61046927SAndroid Build Coastguard Worker vn_graphics_pipeline_state_fill(&pCreateInfos[i], &pipeline->state,
1562*61046927SAndroid Build Coastguard Worker &fix_descs[i]);
1563*61046927SAndroid Build Coastguard Worker }
1564*61046927SAndroid Build Coastguard Worker
1565*61046927SAndroid Build Coastguard Worker struct vn_graphics_pipeline_fix_tmp *fix_tmp = NULL;
1566*61046927SAndroid Build Coastguard Worker pCreateInfos = vn_fix_graphics_pipeline_create_infos(
1567*61046927SAndroid Build Coastguard Worker dev, createInfoCount, pCreateInfos, fix_descs, &fix_tmp, alloc);
1568*61046927SAndroid Build Coastguard Worker if (!pCreateInfos) {
1569*61046927SAndroid Build Coastguard Worker vn_destroy_pipeline_handles(dev, createInfoCount, pPipelines, alloc);
1570*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(fix_descs);
1571*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1572*61046927SAndroid Build Coastguard Worker }
1573*61046927SAndroid Build Coastguard Worker
1574*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < createInfoCount; i++) {
1575*61046927SAndroid Build Coastguard Worker struct vn_pipeline *pipeline = vn_pipeline_from_handle(pPipelines[i]);
1576*61046927SAndroid Build Coastguard Worker struct vn_pipeline_layout *layout =
1577*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_from_handle(pCreateInfos[i].layout);
1578*61046927SAndroid Build Coastguard Worker if (layout && (layout->push_descriptor_set_layout ||
1579*61046927SAndroid Build Coastguard Worker layout->has_push_constant_ranges)) {
1580*61046927SAndroid Build Coastguard Worker pipeline->layout = vn_pipeline_layout_ref(dev, layout);
1581*61046927SAndroid Build Coastguard Worker }
1582*61046927SAndroid Build Coastguard Worker
1583*61046927SAndroid Build Coastguard Worker if ((pCreateInfos[i].flags & VN_PIPELINE_CREATE_SYNC_MASK))
1584*61046927SAndroid Build Coastguard Worker want_sync = true;
1585*61046927SAndroid Build Coastguard Worker
1586*61046927SAndroid Build Coastguard Worker vn_invalidate_pipeline_creation_feedback(
1587*61046927SAndroid Build Coastguard Worker (const VkBaseInStructure *)pCreateInfos[i].pNext);
1588*61046927SAndroid Build Coastguard Worker }
1589*61046927SAndroid Build Coastguard Worker
1590*61046927SAndroid Build Coastguard Worker struct vn_ring *target_ring = vn_get_target_ring(dev);
1591*61046927SAndroid Build Coastguard Worker if (!target_ring) {
1592*61046927SAndroid Build Coastguard Worker vk_free(alloc, fix_tmp);
1593*61046927SAndroid Build Coastguard Worker vn_destroy_pipeline_handles(dev, createInfoCount, pPipelines, alloc);
1594*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(fix_descs);
1595*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1596*61046927SAndroid Build Coastguard Worker }
1597*61046927SAndroid Build Coastguard Worker
1598*61046927SAndroid Build Coastguard Worker if (want_sync || target_ring != dev->primary_ring) {
1599*61046927SAndroid Build Coastguard Worker if (target_ring == dev->primary_ring) {
1600*61046927SAndroid Build Coastguard Worker VN_TRACE_SCOPE("want sync");
1601*61046927SAndroid Build Coastguard Worker }
1602*61046927SAndroid Build Coastguard Worker
1603*61046927SAndroid Build Coastguard Worker result = vn_call_vkCreateGraphicsPipelines(
1604*61046927SAndroid Build Coastguard Worker target_ring, device, pipelineCache, createInfoCount, pCreateInfos,
1605*61046927SAndroid Build Coastguard Worker NULL, pPipelines);
1606*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1607*61046927SAndroid Build Coastguard Worker vn_destroy_failed_pipeline_handles(dev, createInfoCount, pPipelines,
1608*61046927SAndroid Build Coastguard Worker alloc);
1609*61046927SAndroid Build Coastguard Worker } else {
1610*61046927SAndroid Build Coastguard Worker vn_async_vkCreateGraphicsPipelines(target_ring, device, pipelineCache,
1611*61046927SAndroid Build Coastguard Worker createInfoCount, pCreateInfos, NULL,
1612*61046927SAndroid Build Coastguard Worker pPipelines);
1613*61046927SAndroid Build Coastguard Worker result = VK_SUCCESS;
1614*61046927SAndroid Build Coastguard Worker }
1615*61046927SAndroid Build Coastguard Worker
1616*61046927SAndroid Build Coastguard Worker vk_free(alloc, fix_tmp);
1617*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(fix_descs);
1618*61046927SAndroid Build Coastguard Worker return vn_result(dev->instance, result);
1619*61046927SAndroid Build Coastguard Worker }
1620*61046927SAndroid Build Coastguard Worker
1621*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateComputePipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)1622*61046927SAndroid Build Coastguard Worker vn_CreateComputePipelines(VkDevice device,
1623*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
1624*61046927SAndroid Build Coastguard Worker uint32_t createInfoCount,
1625*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfos,
1626*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
1627*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
1628*61046927SAndroid Build Coastguard Worker {
1629*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
1630*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc =
1631*61046927SAndroid Build Coastguard Worker pAllocator ? pAllocator : &dev->base.base.alloc;
1632*61046927SAndroid Build Coastguard Worker bool want_sync = false;
1633*61046927SAndroid Build Coastguard Worker VkResult result;
1634*61046927SAndroid Build Coastguard Worker
1635*61046927SAndroid Build Coastguard Worker memset(pPipelines, 0, sizeof(*pPipelines) * createInfoCount);
1636*61046927SAndroid Build Coastguard Worker
1637*61046927SAndroid Build Coastguard Worker if (!vn_create_pipeline_handles(dev, VN_PIPELINE_TYPE_COMPUTE,
1638*61046927SAndroid Build Coastguard Worker createInfoCount, pPipelines, alloc))
1639*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1640*61046927SAndroid Build Coastguard Worker
1641*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < createInfoCount; i++) {
1642*61046927SAndroid Build Coastguard Worker struct vn_pipeline *pipeline = vn_pipeline_from_handle(pPipelines[i]);
1643*61046927SAndroid Build Coastguard Worker struct vn_pipeline_layout *layout =
1644*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_from_handle(pCreateInfos[i].layout);
1645*61046927SAndroid Build Coastguard Worker if (layout->push_descriptor_set_layout ||
1646*61046927SAndroid Build Coastguard Worker layout->has_push_constant_ranges) {
1647*61046927SAndroid Build Coastguard Worker pipeline->layout = vn_pipeline_layout_ref(dev, layout);
1648*61046927SAndroid Build Coastguard Worker }
1649*61046927SAndroid Build Coastguard Worker if ((pCreateInfos[i].flags & VN_PIPELINE_CREATE_SYNC_MASK))
1650*61046927SAndroid Build Coastguard Worker want_sync = true;
1651*61046927SAndroid Build Coastguard Worker
1652*61046927SAndroid Build Coastguard Worker vn_invalidate_pipeline_creation_feedback(
1653*61046927SAndroid Build Coastguard Worker (const VkBaseInStructure *)pCreateInfos[i].pNext);
1654*61046927SAndroid Build Coastguard Worker }
1655*61046927SAndroid Build Coastguard Worker
1656*61046927SAndroid Build Coastguard Worker struct vn_ring *target_ring = vn_get_target_ring(dev);
1657*61046927SAndroid Build Coastguard Worker if (!target_ring) {
1658*61046927SAndroid Build Coastguard Worker vn_destroy_pipeline_handles(dev, createInfoCount, pPipelines, alloc);
1659*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1660*61046927SAndroid Build Coastguard Worker }
1661*61046927SAndroid Build Coastguard Worker
1662*61046927SAndroid Build Coastguard Worker if (want_sync || target_ring != dev->primary_ring) {
1663*61046927SAndroid Build Coastguard Worker result = vn_call_vkCreateComputePipelines(
1664*61046927SAndroid Build Coastguard Worker target_ring, device, pipelineCache, createInfoCount, pCreateInfos,
1665*61046927SAndroid Build Coastguard Worker NULL, pPipelines);
1666*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1667*61046927SAndroid Build Coastguard Worker vn_destroy_failed_pipeline_handles(dev, createInfoCount, pPipelines,
1668*61046927SAndroid Build Coastguard Worker alloc);
1669*61046927SAndroid Build Coastguard Worker } else {
1670*61046927SAndroid Build Coastguard Worker vn_async_vkCreateComputePipelines(target_ring, device, pipelineCache,
1671*61046927SAndroid Build Coastguard Worker createInfoCount, pCreateInfos, NULL,
1672*61046927SAndroid Build Coastguard Worker pPipelines);
1673*61046927SAndroid Build Coastguard Worker result = VK_SUCCESS;
1674*61046927SAndroid Build Coastguard Worker }
1675*61046927SAndroid Build Coastguard Worker
1676*61046927SAndroid Build Coastguard Worker return vn_result(dev->instance, result);
1677*61046927SAndroid Build Coastguard Worker }
1678*61046927SAndroid Build Coastguard Worker
1679*61046927SAndroid Build Coastguard Worker void
vn_DestroyPipeline(VkDevice device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)1680*61046927SAndroid Build Coastguard Worker vn_DestroyPipeline(VkDevice device,
1681*61046927SAndroid Build Coastguard Worker VkPipeline _pipeline,
1682*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
1683*61046927SAndroid Build Coastguard Worker {
1684*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
1685*61046927SAndroid Build Coastguard Worker struct vn_pipeline *pipeline = vn_pipeline_from_handle(_pipeline);
1686*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc =
1687*61046927SAndroid Build Coastguard Worker pAllocator ? pAllocator : &dev->base.base.alloc;
1688*61046927SAndroid Build Coastguard Worker
1689*61046927SAndroid Build Coastguard Worker if (!pipeline)
1690*61046927SAndroid Build Coastguard Worker return;
1691*61046927SAndroid Build Coastguard Worker
1692*61046927SAndroid Build Coastguard Worker if (pipeline->layout) {
1693*61046927SAndroid Build Coastguard Worker vn_pipeline_layout_unref(dev, pipeline->layout);
1694*61046927SAndroid Build Coastguard Worker }
1695*61046927SAndroid Build Coastguard Worker
1696*61046927SAndroid Build Coastguard Worker vn_async_vkDestroyPipeline(dev->primary_ring, device, _pipeline, NULL);
1697*61046927SAndroid Build Coastguard Worker
1698*61046927SAndroid Build Coastguard Worker vn_object_base_fini(&pipeline->base);
1699*61046927SAndroid Build Coastguard Worker vk_free(alloc, pipeline);
1700*61046927SAndroid Build Coastguard Worker }
1701