vulkan: Add a vk_pipeline_shader_stage_to_nir helper

This is similar to vk_shader_module_to_nir only it takes a
VkPipelineShaderStageCreateInfo and handles
VK_KHR_graphics_pipeline_library semantics for when a
VkShaderModuleCreateInfo is provided instead of an actual module.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17196>
This commit is contained in:
Jason Ekstrand 2022-06-22 16:40:34 -05:00 committed by Marge Bot
parent 288c1c29fb
commit 8ce7faab47
4 changed files with 151 additions and 30 deletions

View file

@ -56,6 +56,8 @@ vulkan_runtime_files = files(
'vk_nir.h',
'vk_object.c',
'vk_object.h',
'vk_pipeline.c',
'vk_pipeline.h',
'vk_pipeline_cache.c',
'vk_pipeline_cache.h',
'vk_physical_device.c',

View file

@ -0,0 +1,88 @@
/*
* Copyright © 2022 Collabora, LTD
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "vk_pipeline.h"
#include "vk_log.h"
#include "vk_nir.h"
#include "vk_shader_module.h"
#include "vk_util.h"
VkResult
vk_pipeline_shader_stage_to_nir(struct vk_device *device,
const VkPipelineShaderStageCreateInfo *info,
const struct spirv_to_nir_options *spirv_options,
const struct nir_shader_compiler_options *nir_options,
void *mem_ctx, nir_shader **nir_out)
{
VK_FROM_HANDLE(vk_shader_module, module, info->module);
const gl_shader_stage stage = vk_to_mesa_shader_stage(info->stage);
assert(info->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
if (module != NULL && module->nir != NULL) {
assert(module->nir->info.stage == stage);
assert(exec_list_length(&module->nir->functions) == 1);
ASSERTED const char *nir_name =
nir_shader_get_entrypoint(module->nir)->function->name;
assert(strcmp(nir_name, info->pName) == 0);
nir_validate_shader(module->nir, "internal shader");
nir_shader *clone = nir_shader_clone(mem_ctx, module->nir);
if (clone == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
assert(clone->options == NULL || clone->options == nir_options);
clone->options = nir_options;
*nir_out = clone;
return VK_SUCCESS;
}
const uint32_t *spirv_data;
uint32_t spirv_size;
if (module != NULL) {
spirv_data = (uint32_t *)module->data;
spirv_size = module->size;
} else {
const VkShaderModuleCreateInfo *minfo =
vk_find_struct_const(info->pNext, SHADER_MODULE_CREATE_INFO);
if (unlikely(minfo == NULL)) {
return vk_errorf(device, VK_ERROR_UNKNOWN,
"No shader module provided");
}
spirv_data = minfo->pCode;
spirv_size = minfo->codeSize;
}
nir_shader *nir = vk_spirv_to_nir(device, spirv_data, spirv_size, stage,
info->pName, info->pSpecializationInfo,
spirv_options, nir_options, mem_ctx);
if (nir == NULL)
return vk_errorf(device, VK_ERROR_UNKNOWN, "spirv_to_nir failed");
*nir_out = nir;
return VK_SUCCESS;
}

View file

@ -0,0 +1,49 @@
/*
* Copyright © 2022 Collabora, LTD
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef VK_PIPELINE_H
#define VK_PIPELINE_H
#include "vulkan/vulkan_core.h"
struct nir_shader;
struct nir_shader_compiler_options;
struct spirv_to_nir_options;
struct vk_device;
#ifdef __cplusplus
extern "C" {
#endif
VkResult
vk_pipeline_shader_stage_to_nir(struct vk_device *device,
const VkPipelineShaderStageCreateInfo *info,
const struct spirv_to_nir_options *spirv_options,
const struct nir_shader_compiler_options *nir_options,
void *mem_ctx, struct nir_shader **nir_out);
#ifdef __cplusplus
}
#endif
#endif /* VK_PIPELINE_H */

View file

@ -28,6 +28,8 @@
#include "vk_device.h"
#include "vk_log.h"
#include "vk_nir.h"
#include "vk_pipeline.h"
#include "vk_util.h"
VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateShaderModule(VkDevice _device,
@ -100,36 +102,16 @@ vk_shader_module_to_nir(struct vk_device *device,
const nir_shader_compiler_options *nir_options,
void *mem_ctx, nir_shader **nir_out)
{
if (mod->nir != NULL) {
assert(mod->nir->info.stage == stage);
assert(exec_list_length(&mod->nir->functions) == 1);
ASSERTED const char *nir_name =
nir_shader_get_entrypoint(mod->nir)->function->name;
assert(strcmp(nir_name, entrypoint_name) == 0);
nir_validate_shader(mod->nir, "internal shader");
nir_shader *clone = nir_shader_clone(mem_ctx, mod->nir);
if (clone == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
assert(clone->options == NULL || clone->options == nir_options);
clone->options = nir_options;
*nir_out = clone;
return VK_SUCCESS;
} else {
nir_shader *nir = vk_spirv_to_nir(device,
(uint32_t *)mod->data, mod->size,
stage, entrypoint_name, spec_info,
spirv_options, nir_options,
mem_ctx);
if (nir == NULL)
return vk_errorf(device, VK_ERROR_UNKNOWN, "spirv_to_nir failed");
*nir_out = nir;
return VK_SUCCESS;
}
const VkPipelineShaderStageCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = mesa_to_vk_shader_stage(stage),
.module = vk_shader_module_to_handle((struct vk_shader_module *)mod),
.pName = entrypoint_name,
.pSpecializationInfo = spec_info,
};
return vk_pipeline_shader_stage_to_nir(device, &info,
spirv_options, nir_options,
mem_ctx, nir_out);
}
struct vk_shader_module *