1 /* 2 * Copyright 2017 Advanced Micro Devices, Inc. 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 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include "glspirv.h" 25 #include "errors.h" 26 #include "util/u_atomic.h" 27 28 void 29 _mesa_spirv_module_reference(struct gl_spirv_module **dest, 30 struct gl_spirv_module *src) 31 { 32 struct gl_spirv_module *old = *dest; 33 34 if (old && p_atomic_dec_zero(&old->RefCount)) 35 free(old); 36 37 *dest = src; 38 39 if (src) 40 p_atomic_inc(&src->RefCount); 41 } 42 43 void 44 _mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest, 45 struct gl_shader_spirv_data *src) 46 { 47 struct gl_shader_spirv_data *old = *dest; 48 49 if (old && p_atomic_dec_zero(&old->RefCount)) { 50 _mesa_spirv_module_reference(&(*dest)->SpirVModule, NULL); 51 ralloc_free(old); 52 } 53 54 *dest = src; 55 56 if (src) 57 p_atomic_inc(&src->RefCount); 58 } 59 60 void 61 _mesa_spirv_shader_binary(struct gl_context *ctx, 62 unsigned n, struct gl_shader **shaders, 63 const void* binary, size_t length) 64 { 65 struct gl_spirv_module *module; 66 struct gl_shader_spirv_data *spirv_data; 67 68 assert(length >= 0); 69 70 module = malloc(sizeof(*module) + length); 71 if (!module) { 72 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary"); 73 return; 74 } 75 76 p_atomic_set(&module->RefCount, 0); 77 module->Length = length; 78 memcpy(&module->Binary[0], binary, length); 79 80 for (int i = 0; i < n; ++i) { 81 struct gl_shader *sh = shaders[i]; 82 83 spirv_data = rzalloc(NULL, struct gl_shader_spirv_data); 84 _mesa_shader_spirv_data_reference(&sh->spirv_data, spirv_data); 85 _mesa_spirv_module_reference(&spirv_data->SpirVModule, module); 86 87 sh->CompileStatus = compile_failure; 88 89 free((void *)sh->Source); 90 sh->Source = NULL; 91 free((void *)sh->FallbackSource); 92 sh->FallbackSource = NULL; 93 94 ralloc_free(sh->ir); 95 sh->ir = NULL; 96 ralloc_free(sh->symbols); 97 sh->symbols = NULL; 98 } 99 } 100 101 void GLAPIENTRY 102 _mesa_SpecializeShaderARB(GLuint shader, 103 const GLchar *pEntryPoint, 104 GLuint numSpecializationConstants, 105 const GLuint *pConstantIndex, 106 const GLuint *pConstantValue) 107 { 108 GET_CURRENT_CONTEXT(ctx); 109 110 /* Just return GL_INVALID_OPERATION error while this is boilerplate */ 111 _mesa_error(ctx, GL_INVALID_OPERATION, "SpecializeShaderARB"); 112 } 113