• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2017 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "vk_shader_module.h"
25 
26 #include "util/mesa-sha1.h"
27 #include "vk_common_entrypoints.h"
28 #include "vk_device.h"
29 #include "vk_log.h"
30 #include "vk_nir.h"
31 #include "vk_pipeline.h"
32 #include "vk_util.h"
33 
34 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateShaderModule(VkDevice _device,const VkShaderModuleCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkShaderModule * pShaderModule)35 vk_common_CreateShaderModule(VkDevice _device,
36                              const VkShaderModuleCreateInfo *pCreateInfo,
37                              const VkAllocationCallbacks *pAllocator,
38                              VkShaderModule *pShaderModule)
39 {
40     VK_FROM_HANDLE(vk_device, device, _device);
41     struct vk_shader_module *module;
42 
43     assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
44     assert(pCreateInfo->flags == 0);
45 
46     module = vk_object_alloc(device, pAllocator,
47                              sizeof(*module) + pCreateInfo->codeSize,
48                              VK_OBJECT_TYPE_SHADER_MODULE);
49     if (module == NULL)
50        return VK_ERROR_OUT_OF_HOST_MEMORY;
51 
52     module->size = pCreateInfo->codeSize;
53     module->nir = NULL;
54     memcpy(module->data, pCreateInfo->pCode, module->size);
55 
56     _mesa_sha1_compute(module->data, module->size, module->sha1);
57 
58     *pShaderModule = vk_shader_module_to_handle(module);
59 
60     return VK_SUCCESS;
61 }
62 
63 const uint8_t vk_shaderModuleIdentifierAlgorithmUUID[VK_UUID_SIZE] = "MESA-SHA1";
64 
65 VKAPI_ATTR void VKAPI_CALL
vk_common_GetShaderModuleIdentifierEXT(VkDevice _device,VkShaderModule _module,VkShaderModuleIdentifierEXT * pIdentifier)66 vk_common_GetShaderModuleIdentifierEXT(VkDevice _device,
67                                        VkShaderModule _module,
68                                        VkShaderModuleIdentifierEXT *pIdentifier)
69 {
70    VK_FROM_HANDLE(vk_shader_module, module, _module);
71    memcpy(pIdentifier->identifier, module->sha1, sizeof(module->sha1));
72    pIdentifier->identifierSize = sizeof(module->sha1);
73 }
74 
75 VKAPI_ATTR void VKAPI_CALL
vk_common_GetShaderModuleCreateInfoIdentifierEXT(VkDevice _device,const VkShaderModuleCreateInfo * pCreateInfo,VkShaderModuleIdentifierEXT * pIdentifier)76 vk_common_GetShaderModuleCreateInfoIdentifierEXT(VkDevice _device,
77                                                  const VkShaderModuleCreateInfo *pCreateInfo,
78                                                  VkShaderModuleIdentifierEXT *pIdentifier)
79 {
80    _mesa_sha1_compute(pCreateInfo->pCode, pCreateInfo->codeSize,
81                       pIdentifier->identifier);
82    pIdentifier->identifierSize = SHA1_DIGEST_LENGTH;
83 }
84 
85 VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyShaderModule(VkDevice _device,VkShaderModule _module,const VkAllocationCallbacks * pAllocator)86 vk_common_DestroyShaderModule(VkDevice _device,
87                               VkShaderModule _module,
88                               const VkAllocationCallbacks *pAllocator)
89 {
90    VK_FROM_HANDLE(vk_device, device, _device);
91    VK_FROM_HANDLE(vk_shader_module, module, _module);
92 
93    if (!module)
94       return;
95 
96    /* NIR modules (which are only created internally by the driver) are not
97     * dynamically allocated so we should never call this for them.
98     * Instead the driver is responsible for freeing the NIR code when it is
99     * no longer needed.
100     */
101    assert(module->nir == NULL);
102 
103    vk_object_free(device, pAllocator, module);
104 }
105 
106 #define SPIR_V_MAGIC_NUMBER 0x07230203
107 
108 uint32_t
vk_shader_module_spirv_version(const struct vk_shader_module * mod)109 vk_shader_module_spirv_version(const struct vk_shader_module *mod)
110 {
111    if (mod->nir != NULL)
112       return 0;
113 
114    return vk_spirv_version((uint32_t *)mod->data, mod->size);
115 }
116 
117 VkResult
vk_shader_module_to_nir(struct vk_device * device,const struct vk_shader_module * mod,gl_shader_stage stage,const char * entrypoint_name,const VkSpecializationInfo * spec_info,const struct spirv_to_nir_options * spirv_options,const nir_shader_compiler_options * nir_options,void * mem_ctx,nir_shader ** nir_out)118 vk_shader_module_to_nir(struct vk_device *device,
119                         const struct vk_shader_module *mod,
120                         gl_shader_stage stage,
121                         const char *entrypoint_name,
122                         const VkSpecializationInfo *spec_info,
123                         const struct spirv_to_nir_options *spirv_options,
124                         const nir_shader_compiler_options *nir_options,
125                         void *mem_ctx, nir_shader **nir_out)
126 {
127    const VkPipelineShaderStageCreateInfo info = {
128       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
129       .stage = mesa_to_vk_shader_stage(stage),
130       .module = vk_shader_module_to_handle((struct vk_shader_module *)mod),
131       .pName = entrypoint_name,
132       .pSpecializationInfo = spec_info,
133    };
134    return vk_pipeline_shader_stage_to_nir(device, &info,
135                                           spirv_options, nir_options,
136                                           mem_ctx, nir_out);
137 }
138 
139 struct vk_shader_module *
vk_shader_module_clone(void * mem_ctx,const struct vk_shader_module * src)140 vk_shader_module_clone(void *mem_ctx, const struct vk_shader_module *src)
141 {
142    struct vk_shader_module *dst =
143       ralloc_size(mem_ctx, sizeof(struct vk_shader_module) + src->size);
144 
145    vk_object_base_init(src->base.device, &dst->base, VK_OBJECT_TYPE_SHADER_MODULE);
146 
147    dst->nir = NULL;
148 
149    memcpy(dst->sha1, src->sha1, sizeof(src->sha1));
150 
151    dst->size = src->size;
152    memcpy(dst->data, src->data, src->size);
153 
154    return dst;
155 }
156