standalone.cpp revision 7ec681f3
101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2008, 2009 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg#include <getopt.h> 2401e04c3fSmrg 2501e04c3fSmrg/** @file standalone.cpp 2601e04c3fSmrg * 2701e04c3fSmrg * Standalone compiler helper lib. Used by standalone glsl_compiler and 2801e04c3fSmrg * also available to drivers to implement their own standalone compiler 2901e04c3fSmrg * with driver backend. 3001e04c3fSmrg */ 3101e04c3fSmrg 3201e04c3fSmrg#include "ast.h" 3301e04c3fSmrg#include "glsl_parser_extras.h" 3401e04c3fSmrg#include "ir_optimization.h" 3501e04c3fSmrg#include "program.h" 3601e04c3fSmrg#include "loop_analysis.h" 3701e04c3fSmrg#include "standalone_scaffolding.h" 3801e04c3fSmrg#include "standalone.h" 3901e04c3fSmrg#include "string_to_uint_map.h" 4001e04c3fSmrg#include "util/set.h" 4101e04c3fSmrg#include "linker.h" 4201e04c3fSmrg#include "glsl_parser_extras.h" 4301e04c3fSmrg#include "ir_builder_print_visitor.h" 4401e04c3fSmrg#include "builtin_functions.h" 4501e04c3fSmrg#include "opt_add_neg_to_sub.h" 4601e04c3fSmrg#include "main/mtypes.h" 477ec681f3Smrg#include "program/program.h" 4801e04c3fSmrg 4901e04c3fSmrgclass dead_variable_visitor : public ir_hierarchical_visitor { 5001e04c3fSmrgpublic: 5101e04c3fSmrg dead_variable_visitor() 5201e04c3fSmrg { 537e102996Smaya variables = _mesa_pointer_set_create(NULL); 5401e04c3fSmrg } 5501e04c3fSmrg 5601e04c3fSmrg virtual ~dead_variable_visitor() 5701e04c3fSmrg { 5801e04c3fSmrg _mesa_set_destroy(variables, NULL); 5901e04c3fSmrg } 6001e04c3fSmrg 6101e04c3fSmrg virtual ir_visitor_status visit(ir_variable *ir) 6201e04c3fSmrg { 6301e04c3fSmrg /* If the variable is auto or temp, add it to the set of variables that 6401e04c3fSmrg * are candidates for removal. 6501e04c3fSmrg */ 6601e04c3fSmrg if (ir->data.mode != ir_var_auto && ir->data.mode != ir_var_temporary) 6701e04c3fSmrg return visit_continue; 6801e04c3fSmrg 6901e04c3fSmrg _mesa_set_add(variables, ir); 7001e04c3fSmrg 7101e04c3fSmrg return visit_continue; 7201e04c3fSmrg } 7301e04c3fSmrg 7401e04c3fSmrg virtual ir_visitor_status visit(ir_dereference_variable *ir) 7501e04c3fSmrg { 7601e04c3fSmrg struct set_entry *entry = _mesa_set_search(variables, ir->var); 7701e04c3fSmrg 7801e04c3fSmrg /* If a variable is dereferenced at all, remove it from the set of 7901e04c3fSmrg * variables that are candidates for removal. 8001e04c3fSmrg */ 8101e04c3fSmrg if (entry != NULL) 8201e04c3fSmrg _mesa_set_remove(variables, entry); 8301e04c3fSmrg 8401e04c3fSmrg return visit_continue; 8501e04c3fSmrg } 8601e04c3fSmrg 8701e04c3fSmrg void remove_dead_variables() 8801e04c3fSmrg { 8901e04c3fSmrg set_foreach(variables, entry) { 9001e04c3fSmrg ir_variable *ir = (ir_variable *) entry->key; 9101e04c3fSmrg 9201e04c3fSmrg assert(ir->ir_type == ir_type_variable); 9301e04c3fSmrg ir->remove(); 9401e04c3fSmrg } 9501e04c3fSmrg } 9601e04c3fSmrg 9701e04c3fSmrgprivate: 9801e04c3fSmrg set *variables; 9901e04c3fSmrg}; 10001e04c3fSmrg 10101e04c3fSmrgstatic void 1027ec681f3Smrginit_gl_program(struct gl_program *prog, bool is_arb_asm, gl_shader_stage stage) 10301e04c3fSmrg{ 10401e04c3fSmrg prog->RefCount = 1; 10501e04c3fSmrg prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB; 1067ec681f3Smrg prog->info.is_arb_asm = is_arb_asm; 1077ec681f3Smrg prog->info.stage = stage; 10801e04c3fSmrg} 10901e04c3fSmrg 11001e04c3fSmrgstatic struct gl_program * 1117ec681f3Smrgnew_program(UNUSED struct gl_context *ctx, gl_shader_stage stage, 11201e04c3fSmrg UNUSED GLuint id, bool is_arb_asm) 11301e04c3fSmrg{ 1147ec681f3Smrg struct gl_program *prog = rzalloc(NULL, struct gl_program); 1157ec681f3Smrg init_gl_program(prog, is_arb_asm, stage); 1167ec681f3Smrg return prog; 11701e04c3fSmrg} 11801e04c3fSmrg 11901e04c3fSmrgstatic const struct standalone_options *options; 12001e04c3fSmrg 12101e04c3fSmrgstatic void 12201e04c3fSmrginitialize_context(struct gl_context *ctx, gl_api api) 12301e04c3fSmrg{ 12401e04c3fSmrg initialize_context_to_defaults(ctx, api); 1257ec681f3Smrg _mesa_glsl_builtin_functions_init_or_ref(); 12601e04c3fSmrg 12701e04c3fSmrg /* The standalone compiler needs to claim support for almost 12801e04c3fSmrg * everything in order to compile the built-in functions. 12901e04c3fSmrg */ 13001e04c3fSmrg ctx->Const.GLSLVersion = options->glsl_version; 13101e04c3fSmrg ctx->Extensions.ARB_ES3_compatibility = true; 1327e102996Smaya ctx->Extensions.ARB_ES3_1_compatibility = true; 1337e102996Smaya ctx->Extensions.ARB_ES3_2_compatibility = true; 13401e04c3fSmrg ctx->Const.MaxComputeWorkGroupCount[0] = 65535; 13501e04c3fSmrg ctx->Const.MaxComputeWorkGroupCount[1] = 65535; 13601e04c3fSmrg ctx->Const.MaxComputeWorkGroupCount[2] = 65535; 13701e04c3fSmrg ctx->Const.MaxComputeWorkGroupSize[0] = 1024; 13801e04c3fSmrg ctx->Const.MaxComputeWorkGroupSize[1] = 1024; 13901e04c3fSmrg ctx->Const.MaxComputeWorkGroupSize[2] = 64; 14001e04c3fSmrg ctx->Const.MaxComputeWorkGroupInvocations = 1024; 14101e04c3fSmrg ctx->Const.MaxComputeSharedMemorySize = 32768; 14201e04c3fSmrg ctx->Const.MaxComputeVariableGroupSize[0] = 512; 14301e04c3fSmrg ctx->Const.MaxComputeVariableGroupSize[1] = 512; 14401e04c3fSmrg ctx->Const.MaxComputeVariableGroupSize[2] = 64; 14501e04c3fSmrg ctx->Const.MaxComputeVariableGroupInvocations = 512; 14601e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16; 14701e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024; 14801e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxCombinedUniformComponents = 1024; 14901e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */ 15001e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */ 15101e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = 8; 15201e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = 8; 15301e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms = 8; 15401e04c3fSmrg ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformBlocks = 12; 15501e04c3fSmrg 15601e04c3fSmrg switch (ctx->Const.GLSLVersion) { 15701e04c3fSmrg case 100: 15801e04c3fSmrg ctx->Const.MaxClipPlanes = 0; 15901e04c3fSmrg ctx->Const.MaxCombinedTextureImageUnits = 8; 16001e04c3fSmrg ctx->Const.MaxDrawBuffers = 2; 16101e04c3fSmrg ctx->Const.MinProgramTexelOffset = 0; 16201e04c3fSmrg ctx->Const.MaxProgramTexelOffset = 0; 16301e04c3fSmrg ctx->Const.MaxLights = 0; 16401e04c3fSmrg ctx->Const.MaxTextureCoordUnits = 0; 16501e04c3fSmrg ctx->Const.MaxTextureUnits = 8; 16601e04c3fSmrg 16701e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8; 16801e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0; 16901e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4; 17001e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 128 * 4; 17101e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 17201e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32; 17301e04c3fSmrg 17401e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 17501e04c3fSmrg ctx->Const.MaxCombinedTextureImageUnits; 17601e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4; 17701e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 16 * 4; 17801e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 17901e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 18001e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 18101e04c3fSmrg 18201e04c3fSmrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; 18301e04c3fSmrg break; 18401e04c3fSmrg case 110: 18501e04c3fSmrg case 120: 18601e04c3fSmrg ctx->Const.MaxClipPlanes = 6; 18701e04c3fSmrg ctx->Const.MaxCombinedTextureImageUnits = 2; 18801e04c3fSmrg ctx->Const.MaxDrawBuffers = 1; 18901e04c3fSmrg ctx->Const.MinProgramTexelOffset = 0; 19001e04c3fSmrg ctx->Const.MaxProgramTexelOffset = 0; 19101e04c3fSmrg ctx->Const.MaxLights = 8; 19201e04c3fSmrg ctx->Const.MaxTextureCoordUnits = 2; 19301e04c3fSmrg ctx->Const.MaxTextureUnits = 2; 19401e04c3fSmrg 19501e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 19601e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0; 19701e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512; 19801e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 512; 19901e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 20001e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32; 20101e04c3fSmrg 20201e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 20301e04c3fSmrg ctx->Const.MaxCombinedTextureImageUnits; 20401e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64; 20501e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 64; 20601e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 20701e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 20801e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 20901e04c3fSmrg 21001e04c3fSmrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; 21101e04c3fSmrg break; 21201e04c3fSmrg case 130: 21301e04c3fSmrg case 140: 21401e04c3fSmrg ctx->Const.MaxClipPlanes = 8; 21501e04c3fSmrg ctx->Const.MaxCombinedTextureImageUnits = 16; 21601e04c3fSmrg ctx->Const.MaxDrawBuffers = 8; 21701e04c3fSmrg ctx->Const.MinProgramTexelOffset = -8; 21801e04c3fSmrg ctx->Const.MaxProgramTexelOffset = 7; 21901e04c3fSmrg ctx->Const.MaxLights = 8; 22001e04c3fSmrg ctx->Const.MaxTextureCoordUnits = 8; 22101e04c3fSmrg ctx->Const.MaxTextureUnits = 2; 22201e04c3fSmrg ctx->Const.MaxUniformBufferBindings = 84; 22301e04c3fSmrg ctx->Const.MaxVertexStreams = 4; 22401e04c3fSmrg ctx->Const.MaxTransformFeedbackBuffers = 4; 22501e04c3fSmrg 22601e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 22701e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; 22801e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; 22901e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024; 23001e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 23101e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64; 23201e04c3fSmrg 23301e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; 23401e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024; 23501e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024; 23601e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 23701e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 23801e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 23901e04c3fSmrg 24001e04c3fSmrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; 24101e04c3fSmrg break; 24201e04c3fSmrg case 150: 24301e04c3fSmrg case 330: 24401e04c3fSmrg case 400: 24501e04c3fSmrg case 410: 24601e04c3fSmrg case 420: 24701e04c3fSmrg case 430: 24801e04c3fSmrg case 440: 24901e04c3fSmrg case 450: 25001e04c3fSmrg case 460: 25101e04c3fSmrg ctx->Const.MaxClipPlanes = 8; 25201e04c3fSmrg ctx->Const.MaxDrawBuffers = 8; 25301e04c3fSmrg ctx->Const.MinProgramTexelOffset = -8; 25401e04c3fSmrg ctx->Const.MaxProgramTexelOffset = 7; 25501e04c3fSmrg ctx->Const.MaxLights = 8; 25601e04c3fSmrg ctx->Const.MaxTextureCoordUnits = 8; 25701e04c3fSmrg ctx->Const.MaxTextureUnits = 2; 25801e04c3fSmrg ctx->Const.MaxUniformBufferBindings = 84; 25901e04c3fSmrg ctx->Const.MaxVertexStreams = 4; 26001e04c3fSmrg ctx->Const.MaxTransformFeedbackBuffers = 4; 2617e102996Smaya ctx->Const.MaxShaderStorageBufferBindings = 4; 2627e102996Smaya ctx->Const.MaxShaderStorageBlockSize = 4096; 2637e102996Smaya ctx->Const.MaxAtomicBufferBindings = 4; 26401e04c3fSmrg 26501e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 26601e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; 26701e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; 26801e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024; 26901e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 27001e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64; 27101e04c3fSmrg 27201e04c3fSmrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16; 27301e04c3fSmrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024; 27401e04c3fSmrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents = 1024; 27501e04c3fSmrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents = 27601e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; 27701e04c3fSmrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128; 27801e04c3fSmrg 27901e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; 28001e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024; 28101e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024; 28201e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 28301e04c3fSmrg ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents; 28401e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 28501e04c3fSmrg 28601e04c3fSmrg ctx->Const.MaxCombinedTextureImageUnits = 28701e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits 28801e04c3fSmrg + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits 28901e04c3fSmrg + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; 29001e04c3fSmrg 29101e04c3fSmrg ctx->Const.MaxGeometryOutputVertices = 256; 29201e04c3fSmrg ctx->Const.MaxGeometryTotalOutputComponents = 1024; 29301e04c3fSmrg 29401e04c3fSmrg ctx->Const.MaxVarying = 60 / 4; 29501e04c3fSmrg break; 29601e04c3fSmrg case 300: 29701e04c3fSmrg ctx->Const.MaxClipPlanes = 8; 29801e04c3fSmrg ctx->Const.MaxCombinedTextureImageUnits = 32; 29901e04c3fSmrg ctx->Const.MaxDrawBuffers = 4; 30001e04c3fSmrg ctx->Const.MinProgramTexelOffset = -8; 30101e04c3fSmrg ctx->Const.MaxProgramTexelOffset = 7; 30201e04c3fSmrg ctx->Const.MaxLights = 0; 30301e04c3fSmrg ctx->Const.MaxTextureCoordUnits = 0; 30401e04c3fSmrg ctx->Const.MaxTextureUnits = 0; 30501e04c3fSmrg ctx->Const.MaxUniformBufferBindings = 84; 30601e04c3fSmrg ctx->Const.MaxVertexStreams = 4; 30701e04c3fSmrg ctx->Const.MaxTransformFeedbackBuffers = 4; 30801e04c3fSmrg 30901e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; 31001e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; 31101e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; 31201e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024; 31301e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ 31401e04c3fSmrg ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4; 31501e04c3fSmrg 31601e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; 31701e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224; 31801e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 224; 31901e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4; 32001e04c3fSmrg ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ 32101e04c3fSmrg 32201e04c3fSmrg ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4; 32301e04c3fSmrg break; 32401e04c3fSmrg } 32501e04c3fSmrg 32601e04c3fSmrg ctx->Const.GenerateTemporaryNames = true; 32701e04c3fSmrg ctx->Const.MaxPatchVertices = 32; 32801e04c3fSmrg 32901e04c3fSmrg /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */ 33001e04c3fSmrg ctx->Const.MaxUserAssignableUniformLocations = 33101e04c3fSmrg 4 * MESA_SHADER_STAGES * MAX_UNIFORMS; 33201e04c3fSmrg 33301e04c3fSmrg ctx->Driver.NewProgram = new_program; 33401e04c3fSmrg} 33501e04c3fSmrg 33601e04c3fSmrg/* Returned string will have 'ctx' as its ralloc owner. */ 33701e04c3fSmrgstatic char * 33801e04c3fSmrgload_text_file(void *ctx, const char *file_name) 33901e04c3fSmrg{ 34001e04c3fSmrg char *text = NULL; 34101e04c3fSmrg size_t size; 34201e04c3fSmrg size_t total_read = 0; 34301e04c3fSmrg FILE *fp = fopen(file_name, "rb"); 34401e04c3fSmrg 34501e04c3fSmrg if (!fp) { 34601e04c3fSmrg return NULL; 34701e04c3fSmrg } 34801e04c3fSmrg 34901e04c3fSmrg fseek(fp, 0L, SEEK_END); 35001e04c3fSmrg size = ftell(fp); 35101e04c3fSmrg fseek(fp, 0L, SEEK_SET); 35201e04c3fSmrg 35301e04c3fSmrg text = (char *) ralloc_size(ctx, size + 1); 35401e04c3fSmrg if (text != NULL) { 35501e04c3fSmrg do { 35601e04c3fSmrg size_t bytes = fread(text + total_read, 35701e04c3fSmrg 1, size - total_read, fp); 35801e04c3fSmrg if (bytes < size - total_read) { 35901e04c3fSmrg free(text); 36001e04c3fSmrg text = NULL; 36101e04c3fSmrg goto error; 36201e04c3fSmrg } 36301e04c3fSmrg 36401e04c3fSmrg if (bytes == 0) { 36501e04c3fSmrg break; 36601e04c3fSmrg } 36701e04c3fSmrg 36801e04c3fSmrg total_read += bytes; 36901e04c3fSmrg } while (total_read < size); 37001e04c3fSmrg 37101e04c3fSmrg text[total_read] = '\0'; 37201e04c3fSmrg error:; 37301e04c3fSmrg } 37401e04c3fSmrg 37501e04c3fSmrg fclose(fp); 37601e04c3fSmrg 37701e04c3fSmrg return text; 37801e04c3fSmrg} 37901e04c3fSmrg 38001e04c3fSmrgstatic void 38101e04c3fSmrgcompile_shader(struct gl_context *ctx, struct gl_shader *shader) 38201e04c3fSmrg{ 38301e04c3fSmrg _mesa_glsl_compile_shader(ctx, shader, options->dump_ast, 38401e04c3fSmrg options->dump_hir, true); 38501e04c3fSmrg 38601e04c3fSmrg /* Print out the resulting IR */ 3877ec681f3Smrg if (shader->CompileStatus == COMPILE_SUCCESS && options->dump_lir) { 3887ec681f3Smrg _mesa_print_ir(stdout, shader->ir, NULL); 38901e04c3fSmrg } 39001e04c3fSmrg 39101e04c3fSmrg return; 39201e04c3fSmrg} 39301e04c3fSmrg 39401e04c3fSmrgextern "C" struct gl_shader_program * 39501e04c3fSmrgstandalone_compile_shader(const struct standalone_options *_options, 3967e102996Smaya unsigned num_files, char* const* files, struct gl_context *ctx) 39701e04c3fSmrg{ 39801e04c3fSmrg int status = EXIT_SUCCESS; 39901e04c3fSmrg bool glsl_es = false; 40001e04c3fSmrg 40101e04c3fSmrg options = _options; 40201e04c3fSmrg 40301e04c3fSmrg switch (options->glsl_version) { 40401e04c3fSmrg case 100: 40501e04c3fSmrg case 300: 40601e04c3fSmrg glsl_es = true; 40701e04c3fSmrg break; 40801e04c3fSmrg case 110: 40901e04c3fSmrg case 120: 41001e04c3fSmrg case 130: 41101e04c3fSmrg case 140: 41201e04c3fSmrg case 150: 41301e04c3fSmrg case 330: 41401e04c3fSmrg case 400: 41501e04c3fSmrg case 410: 41601e04c3fSmrg case 420: 41701e04c3fSmrg case 430: 41801e04c3fSmrg case 440: 41901e04c3fSmrg case 450: 42001e04c3fSmrg case 460: 42101e04c3fSmrg glsl_es = false; 42201e04c3fSmrg break; 42301e04c3fSmrg default: 42401e04c3fSmrg fprintf(stderr, "Unrecognized GLSL version `%d'\n", options->glsl_version); 42501e04c3fSmrg return NULL; 42601e04c3fSmrg } 42701e04c3fSmrg 42801e04c3fSmrg if (glsl_es) { 42901e04c3fSmrg initialize_context(ctx, API_OPENGLES2); 43001e04c3fSmrg } else { 43101e04c3fSmrg initialize_context(ctx, options->glsl_version > 130 ? API_OPENGL_CORE : API_OPENGL_COMPAT); 43201e04c3fSmrg } 43301e04c3fSmrg 4347ec681f3Smrg if (options->lower_precision) { 4357ec681f3Smrg for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_COMPUTE; i++) { 4367ec681f3Smrg struct gl_shader_compiler_options *options = 4377ec681f3Smrg &ctx->Const.ShaderCompilerOptions[i]; 4387ec681f3Smrg options->LowerPrecisionFloat16 = true; 4397ec681f3Smrg options->LowerPrecisionInt16 = true; 4407ec681f3Smrg options->LowerPrecisionDerivatives = true; 4417ec681f3Smrg options->LowerPrecisionConstants = true; 4427ec681f3Smrg options->LowerPrecisionFloat16Uniforms = true; 4437ec681f3Smrg } 4447ec681f3Smrg } 4457ec681f3Smrg 44601e04c3fSmrg struct gl_shader_program *whole_program; 44701e04c3fSmrg 44801e04c3fSmrg whole_program = rzalloc (NULL, struct gl_shader_program); 44901e04c3fSmrg assert(whole_program != NULL); 45001e04c3fSmrg whole_program->data = rzalloc(whole_program, struct gl_shader_program_data); 45101e04c3fSmrg assert(whole_program->data != NULL); 45201e04c3fSmrg whole_program->data->InfoLog = ralloc_strdup(whole_program->data, ""); 45301e04c3fSmrg 45401e04c3fSmrg /* Created just to avoid segmentation faults */ 45501e04c3fSmrg whole_program->AttributeBindings = new string_to_uint_map; 45601e04c3fSmrg whole_program->FragDataBindings = new string_to_uint_map; 45701e04c3fSmrg whole_program->FragDataIndexBindings = new string_to_uint_map; 45801e04c3fSmrg 45901e04c3fSmrg for (unsigned i = 0; i < num_files; i++) { 46001e04c3fSmrg whole_program->Shaders = 46101e04c3fSmrg reralloc(whole_program, whole_program->Shaders, 46201e04c3fSmrg struct gl_shader *, whole_program->NumShaders + 1); 46301e04c3fSmrg assert(whole_program->Shaders != NULL); 46401e04c3fSmrg 46501e04c3fSmrg struct gl_shader *shader = rzalloc(whole_program, gl_shader); 46601e04c3fSmrg 46701e04c3fSmrg whole_program->Shaders[whole_program->NumShaders] = shader; 46801e04c3fSmrg whole_program->NumShaders++; 46901e04c3fSmrg 47001e04c3fSmrg const unsigned len = strlen(files[i]); 47101e04c3fSmrg if (len < 6) 47201e04c3fSmrg goto fail; 47301e04c3fSmrg 47401e04c3fSmrg const char *const ext = & files[i][len - 5]; 47501e04c3fSmrg /* TODO add support to read a .shader_test */ 47601e04c3fSmrg if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0) 47701e04c3fSmrg shader->Type = GL_VERTEX_SHADER; 47801e04c3fSmrg else if (strncmp(".tesc", ext, 5) == 0) 47901e04c3fSmrg shader->Type = GL_TESS_CONTROL_SHADER; 48001e04c3fSmrg else if (strncmp(".tese", ext, 5) == 0) 48101e04c3fSmrg shader->Type = GL_TESS_EVALUATION_SHADER; 48201e04c3fSmrg else if (strncmp(".geom", ext, 5) == 0) 48301e04c3fSmrg shader->Type = GL_GEOMETRY_SHADER; 48401e04c3fSmrg else if (strncmp(".frag", ext, 5) == 0) 48501e04c3fSmrg shader->Type = GL_FRAGMENT_SHADER; 48601e04c3fSmrg else if (strncmp(".comp", ext, 5) == 0) 48701e04c3fSmrg shader->Type = GL_COMPUTE_SHADER; 48801e04c3fSmrg else 48901e04c3fSmrg goto fail; 49001e04c3fSmrg shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type); 49101e04c3fSmrg 49201e04c3fSmrg shader->Source = load_text_file(whole_program, files[i]); 49301e04c3fSmrg if (shader->Source == NULL) { 49401e04c3fSmrg printf("File \"%s\" does not exist.\n", files[i]); 49501e04c3fSmrg exit(EXIT_FAILURE); 49601e04c3fSmrg } 49701e04c3fSmrg 49801e04c3fSmrg compile_shader(ctx, shader); 49901e04c3fSmrg 50001e04c3fSmrg if (strlen(shader->InfoLog) > 0) { 50101e04c3fSmrg if (!options->just_log) 50201e04c3fSmrg printf("Info log for %s:\n", files[i]); 50301e04c3fSmrg 50401e04c3fSmrg printf("%s", shader->InfoLog); 50501e04c3fSmrg if (!options->just_log) 50601e04c3fSmrg printf("\n"); 50701e04c3fSmrg } 50801e04c3fSmrg 50901e04c3fSmrg if (!shader->CompileStatus) { 51001e04c3fSmrg status = EXIT_FAILURE; 51101e04c3fSmrg break; 51201e04c3fSmrg } 51301e04c3fSmrg } 51401e04c3fSmrg 51501e04c3fSmrg if (status == EXIT_SUCCESS) { 51601e04c3fSmrg _mesa_clear_shader_program_data(ctx, whole_program); 51701e04c3fSmrg 51801e04c3fSmrg if (options->do_link) { 51901e04c3fSmrg link_shaders(ctx, whole_program); 52001e04c3fSmrg } else { 52101e04c3fSmrg const gl_shader_stage stage = whole_program->Shaders[0]->Stage; 52201e04c3fSmrg 52301e04c3fSmrg whole_program->data->LinkStatus = LINKING_SUCCESS; 52401e04c3fSmrg whole_program->_LinkedShaders[stage] = 52501e04c3fSmrg link_intrastage_shaders(whole_program /* mem_ctx */, 52601e04c3fSmrg ctx, 52701e04c3fSmrg whole_program, 52801e04c3fSmrg whole_program->Shaders, 52901e04c3fSmrg 1, 53001e04c3fSmrg true); 53101e04c3fSmrg 53201e04c3fSmrg /* Par-linking can fail, for example, if there are undefined external 53301e04c3fSmrg * references. 53401e04c3fSmrg */ 53501e04c3fSmrg if (whole_program->_LinkedShaders[stage] != NULL) { 53601e04c3fSmrg assert(whole_program->data->LinkStatus); 53701e04c3fSmrg 53801e04c3fSmrg struct gl_shader_compiler_options *const compiler_options = 53901e04c3fSmrg &ctx->Const.ShaderCompilerOptions[stage]; 54001e04c3fSmrg 54101e04c3fSmrg exec_list *const ir = 54201e04c3fSmrg whole_program->_LinkedShaders[stage]->ir; 54301e04c3fSmrg 54401e04c3fSmrg bool progress; 54501e04c3fSmrg do { 54601e04c3fSmrg progress = do_function_inlining(ir); 54701e04c3fSmrg 54801e04c3fSmrg progress = do_common_optimization(ir, 54901e04c3fSmrg false, 55001e04c3fSmrg false, 55101e04c3fSmrg compiler_options, 55201e04c3fSmrg true) 55301e04c3fSmrg && progress; 55401e04c3fSmrg } while(progress); 55501e04c3fSmrg } 55601e04c3fSmrg } 55701e04c3fSmrg 55801e04c3fSmrg status = (whole_program->data->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; 55901e04c3fSmrg 56001e04c3fSmrg if (strlen(whole_program->data->InfoLog) > 0) { 56101e04c3fSmrg printf("\n"); 56201e04c3fSmrg if (!options->just_log) 56301e04c3fSmrg printf("Info log for linking:\n"); 56401e04c3fSmrg printf("%s", whole_program->data->InfoLog); 56501e04c3fSmrg if (!options->just_log) 56601e04c3fSmrg printf("\n"); 56701e04c3fSmrg } 56801e04c3fSmrg 56901e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 57001e04c3fSmrg struct gl_linked_shader *shader = whole_program->_LinkedShaders[i]; 57101e04c3fSmrg 57201e04c3fSmrg if (!shader) 57301e04c3fSmrg continue; 57401e04c3fSmrg 57501e04c3fSmrg add_neg_to_sub_visitor v; 57601e04c3fSmrg visit_list_elements(&v, shader->ir); 57701e04c3fSmrg 57801e04c3fSmrg dead_variable_visitor dv; 57901e04c3fSmrg visit_list_elements(&dv, shader->ir); 58001e04c3fSmrg dv.remove_dead_variables(); 58101e04c3fSmrg } 58201e04c3fSmrg 58301e04c3fSmrg if (options->dump_builder) { 58401e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 58501e04c3fSmrg struct gl_linked_shader *shader = whole_program->_LinkedShaders[i]; 58601e04c3fSmrg 58701e04c3fSmrg if (!shader) 58801e04c3fSmrg continue; 58901e04c3fSmrg 59001e04c3fSmrg _mesa_print_builder_for_ir(stdout, shader->ir); 59101e04c3fSmrg } 59201e04c3fSmrg } 59301e04c3fSmrg } 59401e04c3fSmrg 59501e04c3fSmrg return whole_program; 59601e04c3fSmrg 59701e04c3fSmrgfail: 59801e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 59901e04c3fSmrg if (whole_program->_LinkedShaders[i]) 6007ec681f3Smrg _mesa_delete_linked_shader(ctx, whole_program->_LinkedShaders[i]); 60101e04c3fSmrg } 60201e04c3fSmrg 60301e04c3fSmrg ralloc_free(whole_program); 60401e04c3fSmrg return NULL; 60501e04c3fSmrg} 60601e04c3fSmrg 60701e04c3fSmrgextern "C" void 60801e04c3fSmrgstandalone_compiler_cleanup(struct gl_shader_program *whole_program) 60901e04c3fSmrg{ 61001e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 61101e04c3fSmrg if (whole_program->_LinkedShaders[i]) 6127ec681f3Smrg _mesa_delete_linked_shader(NULL, whole_program->_LinkedShaders[i]); 61301e04c3fSmrg } 61401e04c3fSmrg 61501e04c3fSmrg delete whole_program->AttributeBindings; 61601e04c3fSmrg delete whole_program->FragDataBindings; 61701e04c3fSmrg delete whole_program->FragDataIndexBindings; 6187ec681f3Smrg delete whole_program->UniformHash; 61901e04c3fSmrg 62001e04c3fSmrg ralloc_free(whole_program); 6217ec681f3Smrg _mesa_glsl_builtin_functions_decref(); 62201e04c3fSmrg} 623