2 * Copyright © 2015 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 #include "anv_private.h"
34 VkResult
anv_CreateShaderModule(
36 const VkShaderModuleCreateInfo
* pCreateInfo
,
37 VkShaderModule
* pShaderModule
)
39 ANV_FROM_HANDLE(anv_device
, device
, _device
);
40 struct anv_shader_module
*module
;
42 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
);
43 assert(pCreateInfo
->flags
== 0);
45 module
= anv_device_alloc(device
, sizeof(*module
) + pCreateInfo
->codeSize
, 8,
46 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
48 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
51 module
->size
= pCreateInfo
->codeSize
;
52 memcpy(module
->data
, pCreateInfo
->pCode
, module
->size
);
54 *pShaderModule
= anv_shader_module_to_handle(module
);
59 void anv_DestroyShaderModule(
61 VkShaderModule _module
)
63 ANV_FROM_HANDLE(anv_device
, device
, _device
);
64 ANV_FROM_HANDLE(anv_shader_module
, module
, _module
);
66 anv_device_free(device
, module
);
69 VkResult
anv_CreateShader(
71 const VkShaderCreateInfo
* pCreateInfo
,
74 ANV_FROM_HANDLE(anv_device
, device
, _device
);
75 ANV_FROM_HANDLE(anv_shader_module
, module
, pCreateInfo
->module
);
76 struct anv_shader
*shader
;
78 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SHADER_CREATE_INFO
);
79 assert(pCreateInfo
->flags
== 0);
81 const char *name
= pCreateInfo
->pName
? pCreateInfo
->pName
: "main";
82 size_t name_len
= strlen(name
);
84 if (strcmp(name
, "main") != 0) {
85 anv_finishme("Multiple shaders per module not really supported");
88 shader
= anv_device_alloc(device
, sizeof(*shader
) + name_len
+ 1, 8,
89 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
91 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
93 shader
->module
= module
;
94 memcpy(shader
->entrypoint
, name
, name_len
+ 1);
96 *pShader
= anv_shader_to_handle(shader
);
101 void anv_DestroyShader(
105 ANV_FROM_HANDLE(anv_device
, device
, _device
);
106 ANV_FROM_HANDLE(anv_shader
, shader
, _shader
);
108 anv_device_free(device
, shader
);
112 VkResult
anv_CreatePipelineCache(
114 const VkPipelineCacheCreateInfo
* pCreateInfo
,
115 VkPipelineCache
* pPipelineCache
)
117 pPipelineCache
->handle
= 1;
119 stub_return(VK_SUCCESS
);
122 void anv_DestroyPipelineCache(
124 VkPipelineCache _cache
)
128 size_t anv_GetPipelineCacheSize(
130 VkPipelineCache pipelineCache
)
135 VkResult
anv_GetPipelineCacheData(
137 VkPipelineCache pipelineCache
,
140 stub_return(VK_UNSUPPORTED
);
143 VkResult
anv_MergePipelineCaches(
145 VkPipelineCache destCache
,
146 uint32_t srcCacheCount
,
147 const VkPipelineCache
* pSrcCaches
)
149 stub_return(VK_UNSUPPORTED
);
152 void anv_DestroyPipeline(
154 VkPipeline _pipeline
)
156 ANV_FROM_HANDLE(anv_device
, device
, _device
);
157 ANV_FROM_HANDLE(anv_pipeline
, pipeline
, _pipeline
);
159 anv_compiler_free(pipeline
);
160 anv_reloc_list_finish(&pipeline
->batch_relocs
, pipeline
->device
);
161 anv_state_stream_finish(&pipeline
->program_stream
);
162 anv_state_pool_free(&device
->dynamic_state_pool
, pipeline
->blend_state
);
163 anv_device_free(pipeline
->device
, pipeline
);
166 static const uint32_t vk_to_gen_primitive_type
[] = {
167 [VK_PRIMITIVE_TOPOLOGY_POINT_LIST
] = _3DPRIM_POINTLIST
,
168 [VK_PRIMITIVE_TOPOLOGY_LINE_LIST
] = _3DPRIM_LINELIST
,
169 [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP
] = _3DPRIM_LINESTRIP
,
170 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
] = _3DPRIM_TRILIST
,
171 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
] = _3DPRIM_TRISTRIP
,
172 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN
] = _3DPRIM_TRIFAN
,
173 [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ
] = _3DPRIM_LINELIST_ADJ
,
174 [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ
] = _3DPRIM_LINESTRIP_ADJ
,
175 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ
] = _3DPRIM_TRILIST_ADJ
,
176 [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ
] = _3DPRIM_TRISTRIP_ADJ
,
177 [VK_PRIMITIVE_TOPOLOGY_PATCH
] = _3DPRIM_PATCHLIST_1
181 anv_pipeline_init_dynamic_state(struct anv_pipeline
*pipeline
,
182 const VkGraphicsPipelineCreateInfo
*pCreateInfo
)
184 uint32_t states
= ANV_DYNAMIC_STATE_DIRTY_MASK
;
186 if (pCreateInfo
->pDynamicState
) {
187 /* Remove all of the states that are marked as dynamic */
188 uint32_t count
= pCreateInfo
->pDynamicState
->dynamicStateCount
;
189 for (uint32_t s
= 0; s
< count
; s
++)
190 states
&= ~(1 << pCreateInfo
->pDynamicState
->pDynamicStates
[s
]);
193 struct anv_dynamic_state
*dynamic
= &pipeline
->dynamic_state
;
195 dynamic
->viewport
.count
= pCreateInfo
->pViewportState
->viewportCount
;
196 if (states
& (1 << VK_DYNAMIC_STATE_VIEWPORT
)) {
197 typed_memcpy(dynamic
->viewport
.viewports
,
198 pCreateInfo
->pViewportState
->pViewports
,
199 pCreateInfo
->pViewportState
->viewportCount
);
202 dynamic
->scissor
.count
= pCreateInfo
->pViewportState
->scissorCount
;
203 if (states
& (1 << VK_DYNAMIC_STATE_SCISSOR
)) {
204 typed_memcpy(dynamic
->scissor
.scissors
,
205 pCreateInfo
->pViewportState
->pScissors
,
206 pCreateInfo
->pViewportState
->scissorCount
);
209 if (states
& (1 << VK_DYNAMIC_STATE_LINE_WIDTH
)) {
210 assert(pCreateInfo
->pRasterState
);
211 dynamic
->line_width
= pCreateInfo
->pRasterState
->lineWidth
;
214 if (states
& (1 << VK_DYNAMIC_STATE_DEPTH_BIAS
)) {
215 assert(pCreateInfo
->pRasterState
);
216 dynamic
->depth_bias
.bias
= pCreateInfo
->pRasterState
->depthBias
;
217 dynamic
->depth_bias
.clamp
= pCreateInfo
->pRasterState
->depthBiasClamp
;
218 dynamic
->depth_bias
.slope_scaled
=
219 pCreateInfo
->pRasterState
->slopeScaledDepthBias
;
222 if (states
& (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS
)) {
223 assert(pCreateInfo
->pColorBlendState
);
224 typed_memcpy(dynamic
->blend_constants
,
225 pCreateInfo
->pColorBlendState
->blendConst
, 4);
228 if (states
& (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS
)) {
229 assert(pCreateInfo
->pDepthStencilState
);
230 dynamic
->depth_bounds
.min
=
231 pCreateInfo
->pDepthStencilState
->minDepthBounds
;
232 dynamic
->depth_bounds
.max
=
233 pCreateInfo
->pDepthStencilState
->maxDepthBounds
;
236 if (states
& (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
)) {
237 assert(pCreateInfo
->pDepthStencilState
);
238 dynamic
->stencil_compare_mask
.front
=
239 pCreateInfo
->pDepthStencilState
->front
.stencilCompareMask
;
240 dynamic
->stencil_compare_mask
.back
=
241 pCreateInfo
->pDepthStencilState
->back
.stencilCompareMask
;
244 if (states
& (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
)) {
245 assert(pCreateInfo
->pDepthStencilState
);
246 dynamic
->stencil_write_mask
.front
=
247 pCreateInfo
->pDepthStencilState
->front
.stencilWriteMask
;
248 dynamic
->stencil_write_mask
.back
=
249 pCreateInfo
->pDepthStencilState
->back
.stencilWriteMask
;
252 if (states
& (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE
)) {
253 assert(pCreateInfo
->pDepthStencilState
);
254 dynamic
->stencil_reference
.front
=
255 pCreateInfo
->pDepthStencilState
->front
.stencilReference
;
256 dynamic
->stencil_reference
.back
=
257 pCreateInfo
->pDepthStencilState
->back
.stencilReference
;
260 pipeline
->dynamic_state_mask
= states
;
264 anv_pipeline_validate_create_info(const VkGraphicsPipelineCreateInfo
*info
)
266 struct anv_render_pass
*renderpass
= NULL
;
267 struct anv_subpass
*subpass
= NULL
;
269 /* Assert that all required members of VkGraphicsPipelineCreateInfo are
270 * present, as explained by the Vulkan (20 Oct 2015, git-aa308cb), Section
271 * 4.2 Graphics Pipeline.
273 assert(info
->sType
== VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
);
275 renderpass
= anv_render_pass_from_handle(info
->renderPass
);
278 if (renderpass
!= &anv_meta_dummy_renderpass
) {
279 assert(info
->subpass
< renderpass
->subpass_count
);
280 subpass
= &renderpass
->subpasses
[info
->subpass
];
283 assert(info
->stageCount
>= 1);
284 assert(info
->pVertexInputState
);
285 assert(info
->pInputAssemblyState
);
286 assert(info
->pViewportState
);
287 assert(info
->pRasterState
);
288 assert(info
->pMultisampleState
);
290 if (subpass
&& subpass
->depth_stencil_attachment
!= VK_ATTACHMENT_UNUSED
)
291 assert(info
->pDepthStencilState
);
293 if (subpass
&& subpass
->color_count
> 0)
294 assert(info
->pColorBlendState
);
296 for (uint32_t i
= 0; i
< info
->stageCount
; ++i
) {
297 switch (info
->pStages
[i
].stage
) {
298 case VK_SHADER_STAGE_TESS_CONTROL
:
299 case VK_SHADER_STAGE_TESS_EVALUATION
:
300 assert(info
->pTessellationState
);
309 anv_pipeline_init(struct anv_pipeline
*pipeline
, struct anv_device
*device
,
310 const VkGraphicsPipelineCreateInfo
*pCreateInfo
,
311 const struct anv_graphics_pipeline_create_info
*extra
)
316 anv_pipeline_validate_create_info(pCreateInfo
);
319 pipeline
->device
= device
;
320 pipeline
->layout
= anv_pipeline_layout_from_handle(pCreateInfo
->layout
);
321 memset(pipeline
->shaders
, 0, sizeof(pipeline
->shaders
));
323 result
= anv_reloc_list_init(&pipeline
->batch_relocs
, device
);
324 if (result
!= VK_SUCCESS
) {
325 anv_device_free(device
, pipeline
);
328 pipeline
->batch
.next
= pipeline
->batch
.start
= pipeline
->batch_data
;
329 pipeline
->batch
.end
= pipeline
->batch
.start
+ sizeof(pipeline
->batch_data
);
330 pipeline
->batch
.relocs
= &pipeline
->batch_relocs
;
332 anv_state_stream_init(&pipeline
->program_stream
,
333 &device
->instruction_block_pool
);
335 for (uint32_t i
= 0; i
< pCreateInfo
->stageCount
; i
++) {
336 pipeline
->shaders
[pCreateInfo
->pStages
[i
].stage
] =
337 anv_shader_from_handle(pCreateInfo
->pStages
[i
].shader
);
340 anv_pipeline_init_dynamic_state(pipeline
, pCreateInfo
);
342 if (pCreateInfo
->pTessellationState
)
343 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
344 if (pCreateInfo
->pMultisampleState
&&
345 pCreateInfo
->pMultisampleState
->rasterSamples
> 1)
346 anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
348 pipeline
->use_repclear
= extra
&& extra
->use_repclear
;
350 anv_compiler_run(device
->compiler
, pipeline
);
352 const struct brw_wm_prog_data
*wm_prog_data
= &pipeline
->wm_prog_data
;
354 pipeline
->ps_ksp2
= 0;
355 pipeline
->ps_grf_start2
= 0;
356 if (pipeline
->ps_simd8
!= NO_KERNEL
) {
357 pipeline
->ps_ksp0
= pipeline
->ps_simd8
;
358 pipeline
->ps_grf_start0
= wm_prog_data
->base
.dispatch_grf_start_reg
;
359 if (pipeline
->ps_simd16
!= NO_KERNEL
) {
360 pipeline
->ps_ksp2
= pipeline
->ps_simd16
;
361 pipeline
->ps_grf_start2
= wm_prog_data
->dispatch_grf_start_reg_16
;
363 } else if (pipeline
->ps_simd16
!= NO_KERNEL
) {
364 pipeline
->ps_ksp0
= pipeline
->ps_simd16
;
365 pipeline
->ps_grf_start0
= wm_prog_data
->dispatch_grf_start_reg_16
;
367 unreachable("no ps shader");
370 const VkPipelineVertexInputStateCreateInfo
*vi_info
=
371 pCreateInfo
->pVertexInputState
;
372 pipeline
->vb_used
= 0;
373 for (uint32_t i
= 0; i
< vi_info
->bindingCount
; i
++) {
374 const VkVertexInputBindingDescription
*desc
=
375 &vi_info
->pVertexBindingDescriptions
[i
];
377 pipeline
->vb_used
|= 1 << desc
->binding
;
378 pipeline
->binding_stride
[desc
->binding
] = desc
->strideInBytes
;
380 /* Step rate is programmed per vertex element (attribute), not
381 * binding. Set up a map of which bindings step per instance, for
382 * reference by vertex element setup. */
383 switch (desc
->stepRate
) {
385 case VK_VERTEX_INPUT_STEP_RATE_VERTEX
:
386 pipeline
->instancing_enable
[desc
->binding
] = false;
388 case VK_VERTEX_INPUT_STEP_RATE_INSTANCE
:
389 pipeline
->instancing_enable
[desc
->binding
] = true;
394 const VkPipelineInputAssemblyStateCreateInfo
*ia_info
=
395 pCreateInfo
->pInputAssemblyState
;
396 pipeline
->primitive_restart
= ia_info
->primitiveRestartEnable
;
397 pipeline
->topology
= vk_to_gen_primitive_type
[ia_info
->topology
];
399 if (extra
&& extra
->use_rectlist
)
400 pipeline
->topology
= _3DPRIM_RECTLIST
;
406 anv_graphics_pipeline_create(
408 const VkGraphicsPipelineCreateInfo
*pCreateInfo
,
409 const struct anv_graphics_pipeline_create_info
*extra
,
410 VkPipeline
*pPipeline
)
412 ANV_FROM_HANDLE(anv_device
, device
, _device
);
414 switch (device
->info
.gen
) {
416 return gen7_graphics_pipeline_create(_device
, pCreateInfo
, extra
, pPipeline
);
418 return gen8_graphics_pipeline_create(_device
, pCreateInfo
, extra
, pPipeline
);
420 unreachable("unsupported gen\n");
424 VkResult
anv_CreateGraphicsPipelines(
426 VkPipelineCache pipelineCache
,
428 const VkGraphicsPipelineCreateInfo
* pCreateInfos
,
429 VkPipeline
* pPipelines
)
431 VkResult result
= VK_SUCCESS
;
434 for (; i
< count
; i
++) {
435 result
= anv_graphics_pipeline_create(_device
, &pCreateInfos
[i
],
436 NULL
, &pPipelines
[i
]);
437 if (result
!= VK_SUCCESS
) {
438 for (unsigned j
= 0; j
< i
; j
++) {
439 anv_DestroyPipeline(_device
, pPipelines
[j
]);
449 static VkResult
anv_compute_pipeline_create(
451 const VkComputePipelineCreateInfo
* pCreateInfo
,
452 VkPipeline
* pPipeline
)
454 ANV_FROM_HANDLE(anv_device
, device
, _device
);
456 switch (device
->info
.gen
) {
458 return gen7_compute_pipeline_create(_device
, pCreateInfo
, pPipeline
);
460 return gen8_compute_pipeline_create(_device
, pCreateInfo
, pPipeline
);
462 unreachable("unsupported gen\n");
466 VkResult
anv_CreateComputePipelines(
468 VkPipelineCache pipelineCache
,
470 const VkComputePipelineCreateInfo
* pCreateInfos
,
471 VkPipeline
* pPipelines
)
473 VkResult result
= VK_SUCCESS
;
476 for (; i
< count
; i
++) {
477 result
= anv_compute_pipeline_create(_device
, &pCreateInfos
[i
],
479 if (result
!= VK_SUCCESS
) {
480 for (unsigned j
= 0; j
< i
; j
++) {
481 anv_DestroyPipeline(_device
, pPipelines
[j
]);
491 // Pipeline layout functions
493 VkResult
anv_CreatePipelineLayout(
495 const VkPipelineLayoutCreateInfo
* pCreateInfo
,
496 VkPipelineLayout
* pPipelineLayout
)
498 ANV_FROM_HANDLE(anv_device
, device
, _device
);
499 struct anv_pipeline_layout l
, *layout
;
501 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
);
503 l
.num_sets
= pCreateInfo
->descriptorSetCount
;
505 unsigned dynamic_offset_count
= 0;
507 memset(l
.stage
, 0, sizeof(l
.stage
));
508 for (uint32_t set
= 0; set
< pCreateInfo
->descriptorSetCount
; set
++) {
509 ANV_FROM_HANDLE(anv_descriptor_set_layout
, set_layout
,
510 pCreateInfo
->pSetLayouts
[set
]);
511 l
.set
[set
].layout
= set_layout
;
513 l
.set
[set
].dynamic_offset_start
= dynamic_offset_count
;
514 for (uint32_t b
= 0; b
< set_layout
->binding_count
; b
++) {
515 if (set_layout
->binding
[b
].dynamic_offset_index
>= 0)
516 dynamic_offset_count
+= set_layout
->binding
[b
].array_size
;
519 for (VkShaderStage s
= 0; s
< VK_SHADER_STAGE_NUM
; s
++) {
520 l
.set
[set
].stage
[s
].surface_start
= l
.stage
[s
].surface_count
;
521 l
.set
[set
].stage
[s
].sampler_start
= l
.stage
[s
].sampler_count
;
523 for (uint32_t b
= 0; b
< set_layout
->binding_count
; b
++) {
524 unsigned array_size
= set_layout
->binding
[b
].array_size
;
526 if (set_layout
->binding
[b
].stage
[s
].surface_index
>= 0) {
527 l
.stage
[s
].surface_count
+= array_size
;
529 if (set_layout
->binding
[b
].dynamic_offset_index
>= 0)
530 l
.stage
[s
].has_dynamic_offsets
= true;
533 if (set_layout
->binding
[b
].stage
[s
].sampler_index
>= 0)
534 l
.stage
[s
].sampler_count
+= array_size
;
539 unsigned num_bindings
= 0;
540 for (VkShaderStage s
= 0; s
< VK_SHADER_STAGE_NUM
; s
++)
541 num_bindings
+= l
.stage
[s
].surface_count
+ l
.stage
[s
].sampler_count
;
543 size_t size
= sizeof(*layout
) + num_bindings
* sizeof(layout
->entries
[0]);
545 layout
= anv_device_alloc(device
, size
, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
547 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
549 /* Now we can actually build our surface and sampler maps */
550 struct anv_pipeline_binding
*entry
= layout
->entries
;
551 for (VkShaderStage s
= 0; s
< VK_SHADER_STAGE_NUM
; s
++) {
552 l
.stage
[s
].surface_to_descriptor
= entry
;
553 entry
+= l
.stage
[s
].surface_count
;
554 l
.stage
[s
].sampler_to_descriptor
= entry
;
555 entry
+= l
.stage
[s
].sampler_count
;
559 for (uint32_t set
= 0; set
< pCreateInfo
->descriptorSetCount
; set
++) {
560 struct anv_descriptor_set_layout
*set_layout
= l
.set
[set
].layout
;
562 unsigned set_offset
= 0;
563 for (uint32_t b
= 0; b
< set_layout
->binding_count
; b
++) {
564 unsigned array_size
= set_layout
->binding
[b
].array_size
;
566 if (set_layout
->binding
[b
].stage
[s
].surface_index
>= 0) {
567 assert(surface
== l
.set
[set
].stage
[s
].surface_start
+
568 set_layout
->binding
[b
].stage
[s
].surface_index
);
569 for (unsigned i
= 0; i
< array_size
; i
++) {
570 l
.stage
[s
].surface_to_descriptor
[surface
+ i
].set
= set
;
571 l
.stage
[s
].surface_to_descriptor
[surface
+ i
].offset
= set_offset
+ i
;
573 surface
+= array_size
;
576 if (set_layout
->binding
[b
].stage
[s
].sampler_index
>= 0) {
577 assert(sampler
== l
.set
[set
].stage
[s
].sampler_start
+
578 set_layout
->binding
[b
].stage
[s
].sampler_index
);
579 for (unsigned i
= 0; i
< array_size
; i
++) {
580 l
.stage
[s
].sampler_to_descriptor
[sampler
+ i
].set
= set
;
581 l
.stage
[s
].sampler_to_descriptor
[sampler
+ i
].offset
= set_offset
+ i
;
583 sampler
+= array_size
;
586 set_offset
+= array_size
;
591 /* Finally, we're done setting it up, copy into the allocated version */
594 *pPipelineLayout
= anv_pipeline_layout_to_handle(layout
);
599 void anv_DestroyPipelineLayout(
601 VkPipelineLayout _pipelineLayout
)
603 ANV_FROM_HANDLE(anv_device
, device
, _device
);
604 ANV_FROM_HANDLE(anv_pipeline_layout
, pipeline_layout
, _pipelineLayout
);
606 anv_device_free(device
, pipeline_layout
);