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