1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2008, 2009 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21b8e80941Smrg * DEALINGS IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg#include <getopt.h> 24b8e80941Smrg 25b8e80941Smrg/** @file standalone.cpp 26b8e80941Smrg * 27b8e80941Smrg * Standalone compiler helper lib. Used by standalone glsl_compiler and 28b8e80941Smrg * also available to drivers to implement their own standalone compiler 29b8e80941Smrg * with driver backend. 30b8e80941Smrg */ 31b8e80941Smrg 32b8e80941Smrg#include "ast.h" 33b8e80941Smrg#include "glsl_parser_extras.h" 34b8e80941Smrg#include "ir_optimization.h" 35b8e80941Smrg#include "program.h" 36b8e80941Smrg#include "loop_analysis.h" 37b8e80941Smrg#include "standalone_scaffolding.h" 38b8e80941Smrg#include "standalone.h" 39b8e80941Smrg#include "string_to_uint_map.h" 40b8e80941Smrg#include "util/set.h" 41b8e80941Smrg#include "linker.h" 42b8e80941Smrg#include "glsl_parser_extras.h" 43b8e80941Smrg#include "ir_builder_print_visitor.h" 44b8e80941Smrg#include "builtin_functions.h" 45b8e80941Smrg#include "opt_add_neg_to_sub.h" 46b8e80941Smrg#include "main/mtypes.h" 47b8e80941Smrg 48b8e80941Smrgclass dead_variable_visitor : public ir_hierarchical_visitor { 49b8e80941Smrgpublic: 50b8e80941Smrg dead_variable_visitor() 51b8e80941Smrg { 52b8e80941Smrg variables = _mesa_pointer_set_create(NULL); 53b8e80941Smrg } 54b8e80941Smrg 55b8e80941Smrg virtual ~dead_variable_visitor() 56b8e80941Smrg { 57b8e80941Smrg _mesa_set_destroy(variables, NULL); 58b8e80941Smrg } 59b8e80941Smrg 60b8e80941Smrg virtual ir_visitor_status visit(ir_variable *ir) 61b8e80941Smrg { 62b8e80941Smrg /* If the variable is auto or temp, add it to the set of variables that 63b8e80941Smrg * are candidates for removal. 64b8e80941Smrg */ 65b8e80941Smrg if (ir->data.mode != ir_var_auto && ir->data.mode != ir_var_temporary) 66b8e80941Smrg return visit_continue; 67b8e80941Smrg 68b8e80941Smrg _mesa_set_add(variables, ir); 69b8e80941Smrg 70b8e80941Smrg return visit_continue; 71b8e80941Smrg } 72b8e80941Smrg 73b8e80941Smrg virtual ir_visitor_status visit(ir_dereference_variable *ir) 74b8e80941Smrg { 75b8e80941Smrg struct set_entry *entry = _mesa_set_search(variables, ir->var); 76b8e80941Smrg 77b8e80941Smrg /* If a variable is dereferenced at all, remove it from the set of 78b8e80941Smrg * variables that are candidates for removal. 79b8e80941Smrg */ 80b8e80941Smrg if (entry != NULL) 81b8e80941Smrg _mesa_set_remove(variables, entry); 82b8e80941Smrg 83b8e80941Smrg return visit_continue; 84b8e80941Smrg } 85b8e80941Smrg 86b8e80941Smrg void remove_dead_variables() 87b8e80941Smrg { 88b8e80941Smrg set_foreach(variables, entry) { 89b8e80941Smrg ir_variable *ir = (ir_variable *) entry->key; 90b8e80941Smrg 91b8e80941Smrg assert(ir->ir_type == ir_type_variable); 92b8e80941Smrg ir->remove(); 93b8e80941Smrg } 94b8e80941Smrg } 95b8e80941Smrg 96b8e80941Smrgprivate: 97b8e80941Smrg set *variables; 98b8e80941Smrg}; 99b8e80941Smrg 100b8e80941Smrgstatic void 101b8e80941Smrginit_gl_program(struct gl_program *prog, bool is_arb_asm) 102b8e80941Smrg{ 103b8e80941Smrg prog->RefCount = 1; 104b8e80941Smrg prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB; 105b8e80941Smrg prog->is_arb_asm = is_arb_asm; 106b8e80941Smrg} 107b8e80941Smrg 108b8e80941Smrgstatic struct gl_program * 109b8e80941Smrgnew_program(UNUSED struct gl_context *ctx, GLenum target, 110b8e80941Smrg UNUSED GLuint id, bool is_arb_asm) 111b8e80941Smrg{ 112b8e80941Smrg switch (target) { 113b8e80941Smrg case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ 114b8e80941Smrg case GL_GEOMETRY_PROGRAM_NV: 115b8e80941Smrg case GL_TESS_CONTROL_PROGRAM_NV: 116b8e80941Smrg case GL_TESS_EVALUATION_PROGRAM_NV: 117b8e80941Smrg case GL_FRAGMENT_PROGRAM_ARB: 118b8e80941Smrg case GL_COMPUTE_PROGRAM_NV: { 119b8e80941Smrg struct gl_program *prog = rzalloc(NULL, struct gl_program); 120b8e80941Smrg init_gl_program(prog, is_arb_asm); 121b8e80941Smrg return prog; 122b8e80941Smrg } 123b8e80941Smrg default: 124b8e80941Smrg printf("bad target in new_program\n"); 125b8e80941Smrg return NULL; 126b8e80941Smrg } 127b8e80941Smrg} 128b8e80941Smrg 129b8e80941Smrgstatic const struct standalone_options *options; 130b8e80941Smrg 131b8e80941Smrgstatic void 132b8e80941Smrginitialize_context(struct gl_context *ctx, gl_api api) 133b8e80941Smrg{ 134b8e80941Smrg initialize_context_to_defaults(ctx, api); 135b8e80941Smrg glsl_type_singleton_init_or_ref(); 136b8e80941Smrg 137b8e80941Smrg /* The standalone compiler needs to claim support for almost 138b8e80941Smrg * everything in order to compile the built-in functions. 139b8e80941Smrg */ 140b8e80941Smrg ctx->Const.GLSLVersion = options->glsl_version; 141b8e80941Smrg ctx->Extensions.ARB_ES3_compatibility = true; 142b8e80941Smrg ctx->Extensions.ARB_ES3_1_compatibility = true; 143b8e80941Smrg ctx->Extensions.ARB_ES3_2_compatibility = true; 144b8e80941Smrg ctx->Const.MaxComputeWorkGroupCount[0] = 65535; 145b8e80941Smrg ctx->Const.MaxComputeWorkGroupCount[1] = 65535; 146b8e80941Smrg ctx->Const.MaxComputeWorkGroupCount[2] = 65535; 147b8e80941Smrg ctx->Const.MaxComputeWorkGroupSize[0] = 1024; 148b8e80941Smrg ctx->Const.MaxComputeWorkGroupSize[1] = 1024; 149b8e80941Smrg ctx->Const.MaxComputeWorkGroupSize[2] = 64; 150b8e80941Smrg ctx->Const.MaxComputeWorkGroupInvocations = 1024; 151b8e80941Smrg ctx->Const.MaxComputeSharedMemorySize = 32768; 152b8e80941Smrg ctx->Const.MaxComputeVariableGroupSize[0] = 512; 153b8e80941Smrg ctx->Const.MaxComputeVariableGroupSize[1] = 512; 154b8e80941Smrg ctx->Const.MaxComputeVariableGroupSize[2] = 64; 155b8e80941Smrg ctx->Const.MaxComputeVariableGroupInvocations = 512; 156b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16; 157b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024; 158b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxCombinedUniformComponents = 1024; 159b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */ 160b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */ 161b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = 8; 162b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = 8; 163b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms = 8; 164b8e80941Smrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformBlocks = 12; 165b8e80941Smrg 166b8e80941Smrg switch (ctx->Const.GLSLVersion) { 167b8e80941Smrg case 100: 168b8e80941Smrg ctx->Const.MaxClipPlanes = 0; 169b8e80941Smrg ctx->Const.MaxCombinedTextureImageUnits = 8; 170b8e80941Smrg ctx->Const.MaxDrawBuffers = 2; 171b8e80941Smrg ctx->Const.MinProgramTexelOffset = 0; 172b8e80941Smrg ctx->Const.MaxProgramTexelOffset = 0; 173b8e80941Smrg ctx->Const.MaxLights = 0; 174b8e80941Smrg ctx->Const.MaxTextureCoordUnits = 0; 175b8e80941Smrg ctx->Const.MaxTextureUnits = 8; 176b8e80941Smrg 177b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8; 178b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0; 179b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4; 180b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 128 * 4; 181b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 182b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32; 183b8e80941Smrg 184b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 185b8e80941Smrg ctx->Const.MaxCombinedTextureImageUnits; 186b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4; 187b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 16 * 4; 188b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 189b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 190b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 191b8e80941Smrg 192b8e80941Smrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; 193b8e80941Smrg break; 194b8e80941Smrg case 110: 195b8e80941Smrg case 120: 196b8e80941Smrg ctx->Const.MaxClipPlanes = 6; 197b8e80941Smrg ctx->Const.MaxCombinedTextureImageUnits = 2; 198b8e80941Smrg ctx->Const.MaxDrawBuffers = 1; 199b8e80941Smrg ctx->Const.MinProgramTexelOffset = 0; 200b8e80941Smrg ctx->Const.MaxProgramTexelOffset = 0; 201b8e80941Smrg ctx->Const.MaxLights = 8; 202b8e80941Smrg ctx->Const.MaxTextureCoordUnits = 2; 203b8e80941Smrg ctx->Const.MaxTextureUnits = 2; 204b8e80941Smrg 205b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 206b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0; 207b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512; 208b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 512; 209b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 210b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32; 211b8e80941Smrg 212b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 213b8e80941Smrg ctx->Const.MaxCombinedTextureImageUnits; 214b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64; 215b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 64; 216b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 217b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 218b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 219b8e80941Smrg 220b8e80941Smrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; 221b8e80941Smrg break; 222b8e80941Smrg case 130: 223b8e80941Smrg case 140: 224b8e80941Smrg ctx->Const.MaxClipPlanes = 8; 225b8e80941Smrg ctx->Const.MaxCombinedTextureImageUnits = 16; 226b8e80941Smrg ctx->Const.MaxDrawBuffers = 8; 227b8e80941Smrg ctx->Const.MinProgramTexelOffset = -8; 228b8e80941Smrg ctx->Const.MaxProgramTexelOffset = 7; 229b8e80941Smrg ctx->Const.MaxLights = 8; 230b8e80941Smrg ctx->Const.MaxTextureCoordUnits = 8; 231b8e80941Smrg ctx->Const.MaxTextureUnits = 2; 232b8e80941Smrg ctx->Const.MaxUniformBufferBindings = 84; 233b8e80941Smrg ctx->Const.MaxVertexStreams = 4; 234b8e80941Smrg ctx->Const.MaxTransformFeedbackBuffers = 4; 235b8e80941Smrg 236b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 237b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; 238b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; 239b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024; 240b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 241b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64; 242b8e80941Smrg 243b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; 244b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024; 245b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024; 246b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 247b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 248b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 249b8e80941Smrg 250b8e80941Smrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; 251b8e80941Smrg break; 252b8e80941Smrg case 150: 253b8e80941Smrg case 330: 254b8e80941Smrg case 400: 255b8e80941Smrg case 410: 256b8e80941Smrg case 420: 257b8e80941Smrg case 430: 258b8e80941Smrg case 440: 259b8e80941Smrg case 450: 260b8e80941Smrg case 460: 261b8e80941Smrg ctx->Const.MaxClipPlanes = 8; 262b8e80941Smrg ctx->Const.MaxDrawBuffers = 8; 263b8e80941Smrg ctx->Const.MinProgramTexelOffset = -8; 264b8e80941Smrg ctx->Const.MaxProgramTexelOffset = 7; 265b8e80941Smrg ctx->Const.MaxLights = 8; 266b8e80941Smrg ctx->Const.MaxTextureCoordUnits = 8; 267b8e80941Smrg ctx->Const.MaxTextureUnits = 2; 268b8e80941Smrg ctx->Const.MaxUniformBufferBindings = 84; 269b8e80941Smrg ctx->Const.MaxVertexStreams = 4; 270b8e80941Smrg ctx->Const.MaxTransformFeedbackBuffers = 4; 271b8e80941Smrg ctx->Const.MaxShaderStorageBufferBindings = 4; 272b8e80941Smrg ctx->Const.MaxShaderStorageBlockSize = 4096; 273b8e80941Smrg ctx->Const.MaxAtomicBufferBindings = 4; 274b8e80941Smrg 275b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 276b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; 277b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; 278b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024; 279b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 280b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64; 281b8e80941Smrg 282b8e80941Smrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16; 283b8e80941Smrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024; 284b8e80941Smrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents = 1024; 285b8e80941Smrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents = 286b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 287b8e80941Smrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128; 288b8e80941Smrg 289b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; 290b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024; 291b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024; 292b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 293b8e80941Smrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents; 294b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 295b8e80941Smrg 296b8e80941Smrg ctx->Const.MaxCombinedTextureImageUnits = 297b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits 298b8e80941Smrg + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits 299b8e80941Smrg + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; 300b8e80941Smrg 301b8e80941Smrg ctx->Const.MaxGeometryOutputVertices = 256; 302b8e80941Smrg ctx->Const.MaxGeometryTotalOutputComponents = 1024; 303b8e80941Smrg 304b8e80941Smrg ctx->Const.MaxVarying = 60 / 4; 305b8e80941Smrg break; 306b8e80941Smrg case 300: 307b8e80941Smrg ctx->Const.MaxClipPlanes = 8; 308b8e80941Smrg ctx->Const.MaxCombinedTextureImageUnits = 32; 309b8e80941Smrg ctx->Const.MaxDrawBuffers = 4; 310b8e80941Smrg ctx->Const.MinProgramTexelOffset = -8; 311b8e80941Smrg ctx->Const.MaxProgramTexelOffset = 7; 312b8e80941Smrg ctx->Const.MaxLights = 0; 313b8e80941Smrg ctx->Const.MaxTextureCoordUnits = 0; 314b8e80941Smrg ctx->Const.MaxTextureUnits = 0; 315b8e80941Smrg ctx->Const.MaxUniformBufferBindings = 84; 316b8e80941Smrg ctx->Const.MaxVertexStreams = 4; 317b8e80941Smrg ctx->Const.MaxTransformFeedbackBuffers = 4; 318b8e80941Smrg 319b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 320b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; 321b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; 322b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024; 323b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 324b8e80941Smrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4; 325b8e80941Smrg 326b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; 327b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224; 328b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 224; 329b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4; 330b8e80941Smrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 331b8e80941Smrg 332b8e80941Smrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4; 333b8e80941Smrg break; 334b8e80941Smrg } 335b8e80941Smrg 336b8e80941Smrg ctx->Const.GenerateTemporaryNames = true; 337b8e80941Smrg ctx->Const.MaxPatchVertices = 32; 338b8e80941Smrg 339b8e80941Smrg /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */ 340b8e80941Smrg ctx->Const.MaxUserAssignableUniformLocations = 341b8e80941Smrg 4 * MESA_SHADER_STAGES * MAX_UNIFORMS; 342b8e80941Smrg 343b8e80941Smrg ctx->Driver.NewProgram = new_program; 344b8e80941Smrg} 345b8e80941Smrg 346b8e80941Smrg/* Returned string will have 'ctx' as its ralloc owner. */ 347b8e80941Smrgstatic char * 348b8e80941Smrgload_text_file(void *ctx, const char *file_name) 349b8e80941Smrg{ 350b8e80941Smrg char *text = NULL; 351b8e80941Smrg size_t size; 352b8e80941Smrg size_t total_read = 0; 353b8e80941Smrg FILE *fp = fopen(file_name, "rb"); 354b8e80941Smrg 355b8e80941Smrg if (!fp) { 356b8e80941Smrg return NULL; 357b8e80941Smrg } 358b8e80941Smrg 359b8e80941Smrg fseek(fp, 0L, SEEK_END); 360b8e80941Smrg size = ftell(fp); 361b8e80941Smrg fseek(fp, 0L, SEEK_SET); 362b8e80941Smrg 363b8e80941Smrg text = (char *) ralloc_size(ctx, size + 1); 364b8e80941Smrg if (text != NULL) { 365b8e80941Smrg do { 366b8e80941Smrg size_t bytes = fread(text + total_read, 367b8e80941Smrg 1, size - total_read, fp); 368b8e80941Smrg if (bytes < size - total_read) { 369b8e80941Smrg free(text); 370b8e80941Smrg text = NULL; 371b8e80941Smrg goto error; 372b8e80941Smrg } 373b8e80941Smrg 374b8e80941Smrg if (bytes == 0) { 375b8e80941Smrg break; 376b8e80941Smrg } 377b8e80941Smrg 378b8e80941Smrg total_read += bytes; 379b8e80941Smrg } while (total_read < size); 380b8e80941Smrg 381b8e80941Smrg text[total_read] = '\0'; 382b8e80941Smrg error:; 383b8e80941Smrg } 384b8e80941Smrg 385b8e80941Smrg fclose(fp); 386b8e80941Smrg 387b8e80941Smrg return text; 388b8e80941Smrg} 389b8e80941Smrg 390b8e80941Smrgstatic void 391b8e80941Smrgcompile_shader(struct gl_context *ctx, struct gl_shader *shader) 392b8e80941Smrg{ 393b8e80941Smrg struct _mesa_glsl_parse_state *state = 394b8e80941Smrg new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader); 395b8e80941Smrg 396b8e80941Smrg _mesa_glsl_compile_shader(ctx, shader, options->dump_ast, 397b8e80941Smrg options->dump_hir, true); 398b8e80941Smrg 399b8e80941Smrg /* Print out the resulting IR */ 400b8e80941Smrg if (!state->error && options->dump_lir) { 401b8e80941Smrg _mesa_print_ir(stdout, shader->ir, state); 402b8e80941Smrg } 403b8e80941Smrg 404b8e80941Smrg return; 405b8e80941Smrg} 406b8e80941Smrg 407b8e80941Smrgextern "C" struct gl_shader_program * 408b8e80941Smrgstandalone_compile_shader(const struct standalone_options *_options, 409b8e80941Smrg unsigned num_files, char* const* files, struct gl_context *ctx) 410b8e80941Smrg{ 411b8e80941Smrg int status = EXIT_SUCCESS; 412b8e80941Smrg bool glsl_es = false; 413b8e80941Smrg 414b8e80941Smrg options = _options; 415b8e80941Smrg 416b8e80941Smrg switch (options->glsl_version) { 417b8e80941Smrg case 100: 418b8e80941Smrg case 300: 419b8e80941Smrg glsl_es = true; 420b8e80941Smrg break; 421b8e80941Smrg case 110: 422b8e80941Smrg case 120: 423b8e80941Smrg case 130: 424b8e80941Smrg case 140: 425b8e80941Smrg case 150: 426b8e80941Smrg case 330: 427b8e80941Smrg case 400: 428b8e80941Smrg case 410: 429b8e80941Smrg case 420: 430b8e80941Smrg case 430: 431b8e80941Smrg case 440: 432b8e80941Smrg case 450: 433b8e80941Smrg case 460: 434b8e80941Smrg glsl_es = false; 435b8e80941Smrg break; 436b8e80941Smrg default: 437b8e80941Smrg fprintf(stderr, "Unrecognized GLSL version `%d'\n", options->glsl_version); 438b8e80941Smrg return NULL; 439b8e80941Smrg } 440b8e80941Smrg 441b8e80941Smrg if (glsl_es) { 442b8e80941Smrg initialize_context(ctx, API_OPENGLES2); 443b8e80941Smrg } else { 444b8e80941Smrg initialize_context(ctx, options->glsl_version > 130 ? API_OPENGL_CORE : API_OPENGL_COMPAT); 445b8e80941Smrg } 446b8e80941Smrg 447b8e80941Smrg struct gl_shader_program *whole_program; 448b8e80941Smrg 449b8e80941Smrg whole_program = rzalloc (NULL, struct gl_shader_program); 450b8e80941Smrg assert(whole_program != NULL); 451b8e80941Smrg whole_program->data = rzalloc(whole_program, struct gl_shader_program_data); 452b8e80941Smrg assert(whole_program->data != NULL); 453b8e80941Smrg whole_program->data->InfoLog = ralloc_strdup(whole_program->data, ""); 454b8e80941Smrg 455b8e80941Smrg /* Created just to avoid segmentation faults */ 456b8e80941Smrg whole_program->AttributeBindings = new string_to_uint_map; 457b8e80941Smrg whole_program->FragDataBindings = new string_to_uint_map; 458b8e80941Smrg whole_program->FragDataIndexBindings = new string_to_uint_map; 459b8e80941Smrg 460b8e80941Smrg for (unsigned i = 0; i < num_files; i++) { 461b8e80941Smrg whole_program->Shaders = 462b8e80941Smrg reralloc(whole_program, whole_program->Shaders, 463b8e80941Smrg struct gl_shader *, whole_program->NumShaders + 1); 464b8e80941Smrg assert(whole_program->Shaders != NULL); 465b8e80941Smrg 466b8e80941Smrg struct gl_shader *shader = rzalloc(whole_program, gl_shader); 467b8e80941Smrg 468b8e80941Smrg whole_program->Shaders[whole_program->NumShaders] = shader; 469b8e80941Smrg whole_program->NumShaders++; 470b8e80941Smrg 471b8e80941Smrg const unsigned len = strlen(files[i]); 472b8e80941Smrg if (len < 6) 473b8e80941Smrg goto fail; 474b8e80941Smrg 475b8e80941Smrg const char *const ext = & files[i][len - 5]; 476b8e80941Smrg /* TODO add support to read a .shader_test */ 477b8e80941Smrg if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0) 478b8e80941Smrg shader->Type = GL_VERTEX_SHADER; 479b8e80941Smrg else if (strncmp(".tesc", ext, 5) == 0) 480b8e80941Smrg shader->Type = GL_TESS_CONTROL_SHADER; 481b8e80941Smrg else if (strncmp(".tese", ext, 5) == 0) 482b8e80941Smrg shader->Type = GL_TESS_EVALUATION_SHADER; 483b8e80941Smrg else if (strncmp(".geom", ext, 5) == 0) 484b8e80941Smrg shader->Type = GL_GEOMETRY_SHADER; 485b8e80941Smrg else if (strncmp(".frag", ext, 5) == 0) 486b8e80941Smrg shader->Type = GL_FRAGMENT_SHADER; 487b8e80941Smrg else if (strncmp(".comp", ext, 5) == 0) 488b8e80941Smrg shader->Type = GL_COMPUTE_SHADER; 489b8e80941Smrg else 490b8e80941Smrg goto fail; 491b8e80941Smrg shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type); 492b8e80941Smrg 493b8e80941Smrg shader->Source = load_text_file(whole_program, files[i]); 494b8e80941Smrg if (shader->Source == NULL) { 495b8e80941Smrg printf("File \"%s\" does not exist.\n", files[i]); 496b8e80941Smrg exit(EXIT_FAILURE); 497b8e80941Smrg } 498b8e80941Smrg 499b8e80941Smrg compile_shader(ctx, shader); 500b8e80941Smrg 501b8e80941Smrg if (strlen(shader->InfoLog) > 0) { 502b8e80941Smrg if (!options->just_log) 503b8e80941Smrg printf("Info log for %s:\n", files[i]); 504b8e80941Smrg 505b8e80941Smrg printf("%s", shader->InfoLog); 506b8e80941Smrg if (!options->just_log) 507b8e80941Smrg printf("\n"); 508b8e80941Smrg } 509b8e80941Smrg 510b8e80941Smrg if (!shader->CompileStatus) { 511b8e80941Smrg status = EXIT_FAILURE; 512b8e80941Smrg break; 513b8e80941Smrg } 514b8e80941Smrg } 515b8e80941Smrg 516b8e80941Smrg if (status == EXIT_SUCCESS) { 517b8e80941Smrg _mesa_clear_shader_program_data(ctx, whole_program); 518b8e80941Smrg 519b8e80941Smrg if (options->do_link) { 520b8e80941Smrg link_shaders(ctx, whole_program); 521b8e80941Smrg } else { 522b8e80941Smrg const gl_shader_stage stage = whole_program->Shaders[0]->Stage; 523b8e80941Smrg 524b8e80941Smrg whole_program->data->LinkStatus = LINKING_SUCCESS; 525b8e80941Smrg whole_program->_LinkedShaders[stage] = 526b8e80941Smrg link_intrastage_shaders(whole_program /* mem_ctx */, 527b8e80941Smrg ctx, 528b8e80941Smrg whole_program, 529b8e80941Smrg whole_program->Shaders, 530b8e80941Smrg 1, 531b8e80941Smrg true); 532b8e80941Smrg 533b8e80941Smrg /* Par-linking can fail, for example, if there are undefined external 534b8e80941Smrg * references. 535b8e80941Smrg */ 536b8e80941Smrg if (whole_program->_LinkedShaders[stage] != NULL) { 537b8e80941Smrg assert(whole_program->data->LinkStatus); 538b8e80941Smrg 539b8e80941Smrg struct gl_shader_compiler_options *const compiler_options = 540b8e80941Smrg &ctx->Const.ShaderCompilerOptions[stage]; 541b8e80941Smrg 542b8e80941Smrg exec_list *const ir = 543b8e80941Smrg whole_program->_LinkedShaders[stage]->ir; 544b8e80941Smrg 545b8e80941Smrg bool progress; 546b8e80941Smrg do { 547b8e80941Smrg progress = do_function_inlining(ir); 548b8e80941Smrg 549b8e80941Smrg progress = do_common_optimization(ir, 550b8e80941Smrg false, 551b8e80941Smrg false, 552b8e80941Smrg compiler_options, 553b8e80941Smrg true) 554b8e80941Smrg && progress; 555b8e80941Smrg } while(progress); 556b8e80941Smrg } 557b8e80941Smrg } 558b8e80941Smrg 559b8e80941Smrg status = (whole_program->data->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; 560b8e80941Smrg 561b8e80941Smrg if (strlen(whole_program->data->InfoLog) > 0) { 562b8e80941Smrg printf("\n"); 563b8e80941Smrg if (!options->just_log) 564b8e80941Smrg printf("Info log for linking:\n"); 565b8e80941Smrg printf("%s", whole_program->data->InfoLog); 566b8e80941Smrg if (!options->just_log) 567b8e80941Smrg printf("\n"); 568b8e80941Smrg } 569b8e80941Smrg 570b8e80941Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 571b8e80941Smrg struct gl_linked_shader *shader = whole_program->_LinkedShaders[i]; 572b8e80941Smrg 573b8e80941Smrg if (!shader) 574b8e80941Smrg continue; 575b8e80941Smrg 576b8e80941Smrg add_neg_to_sub_visitor v; 577b8e80941Smrg visit_list_elements(&v, shader->ir); 578b8e80941Smrg 579b8e80941Smrg dead_variable_visitor dv; 580b8e80941Smrg visit_list_elements(&dv, shader->ir); 581b8e80941Smrg dv.remove_dead_variables(); 582b8e80941Smrg } 583b8e80941Smrg 584b8e80941Smrg if (options->dump_builder) { 585b8e80941Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 586b8e80941Smrg struct gl_linked_shader *shader = whole_program->_LinkedShaders[i]; 587b8e80941Smrg 588b8e80941Smrg if (!shader) 589b8e80941Smrg continue; 590b8e80941Smrg 591b8e80941Smrg _mesa_print_builder_for_ir(stdout, shader->ir); 592b8e80941Smrg } 593b8e80941Smrg } 594b8e80941Smrg } 595b8e80941Smrg 596b8e80941Smrg return whole_program; 597b8e80941Smrg 598b8e80941Smrgfail: 599b8e80941Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 600b8e80941Smrg if (whole_program->_LinkedShaders[i]) 601b8e80941Smrg ralloc_free(whole_program->_LinkedShaders[i]->Program); 602b8e80941Smrg } 603b8e80941Smrg 604b8e80941Smrg ralloc_free(whole_program); 605b8e80941Smrg return NULL; 606b8e80941Smrg} 607b8e80941Smrg 608b8e80941Smrgextern "C" void 609b8e80941Smrgstandalone_compiler_cleanup(struct gl_shader_program *whole_program) 610b8e80941Smrg{ 611b8e80941Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 612b8e80941Smrg if (whole_program->_LinkedShaders[i]) 613b8e80941Smrg ralloc_free(whole_program->_LinkedShaders[i]->Program); 614b8e80941Smrg } 615b8e80941Smrg 616b8e80941Smrg delete whole_program->AttributeBindings; 617b8e80941Smrg delete whole_program->FragDataBindings; 618b8e80941Smrg delete whole_program->FragDataIndexBindings; 619b8e80941Smrg 620b8e80941Smrg ralloc_free(whole_program); 621b8e80941Smrg glsl_type_singleton_decref(); 622b8e80941Smrg _mesa_glsl_release_builtin_functions(); 623b8e80941Smrg} 624