• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
3  * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
4  * Copyright © 2010 Intel Corporation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 
26 #include "main/shaderapi.h"
27 #include "main/shaderobj.h"
28 #include "main/glspirv.h"
29 #include "compiler/glsl/glsl_parser_extras.h"
30 #include "compiler/glsl_types.h"
31 #include "compiler/glsl/linker.h"
32 #include "compiler/glsl/program.h"
33 #include "compiler/glsl/shader_cache.h"
34 
35 #include "state_tracker/st_glsl_to_ir.h"
36 
37 extern "C" {
38 
39 /**
40  * Link a GLSL shader program.  Called via glLinkProgram().
41  */
42 void
_mesa_glsl_link_shader(struct gl_context * ctx,struct gl_shader_program * prog)43 _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
44 {
45    unsigned int i;
46    bool spirv = false;
47 
48    _mesa_clear_shader_program_data(ctx, prog);
49 
50    prog->data = _mesa_create_shader_program_data();
51 
52    prog->data->LinkStatus = LINKING_SUCCESS;
53 
54    for (i = 0; i < prog->NumShaders; i++) {
55       if (!prog->Shaders[i]->CompileStatus) {
56 	 linker_error(prog, "linking with uncompiled/unspecialized shader");
57       }
58 
59       if (!i) {
60          spirv = (prog->Shaders[i]->spirv_data != NULL);
61       } else if (spirv && !prog->Shaders[i]->spirv_data) {
62          /* The GL_ARB_gl_spirv spec adds a new bullet point to the list of
63           * reasons LinkProgram can fail:
64           *
65           *    "All the shader objects attached to <program> do not have the
66           *     same value for the SPIR_V_BINARY_ARB state."
67           */
68          linker_error(prog,
69                       "not all attached shaders have the same "
70                       "SPIR_V_BINARY_ARB state");
71       }
72    }
73    prog->data->spirv = spirv;
74 
75    if (prog->data->LinkStatus) {
76       if (!spirv)
77          link_shaders(ctx, prog);
78       else
79          _mesa_spirv_link_shaders(ctx, prog);
80    }
81 
82    /* If LinkStatus is LINKING_SUCCESS, then reset sampler validated to true.
83     * Validation happens via the LinkShader call below. If LinkStatus is
84     * LINKING_SKIPPED, then SamplersValidated will have been restored from the
85     * shader cache.
86     */
87    if (prog->data->LinkStatus == LINKING_SUCCESS) {
88       prog->SamplersValidated = GL_TRUE;
89    }
90 
91    if (prog->data->LinkStatus && !st_link_shader(ctx, prog)) {
92       prog->data->LinkStatus = LINKING_FAILURE;
93    }
94 
95    if (prog->data->LinkStatus != LINKING_FAILURE)
96       _mesa_create_program_resource_hash(prog);
97 
98    /* Return early if we are loading the shader from on-disk cache */
99    if (prog->data->LinkStatus == LINKING_SKIPPED)
100       return;
101 
102    if (ctx->_Shader->Flags & GLSL_DUMP) {
103       if (!prog->data->LinkStatus) {
104 	 fprintf(stderr, "GLSL shader program %d failed to link\n", prog->Name);
105       }
106 
107       if (prog->data->InfoLog && prog->data->InfoLog[0] != 0) {
108 	 fprintf(stderr, "GLSL shader program %d info log:\n", prog->Name);
109          fprintf(stderr, "%s\n", prog->data->InfoLog);
110       }
111    }
112 
113 #ifdef ENABLE_SHADER_CACHE
114    if (prog->data->LinkStatus)
115       shader_cache_write_program_metadata(ctx, prog);
116 #endif
117 }
118 
119 } /* extern "C" */
120