duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

effect_codegen_glsl.cpp (65805B)


      1 /*
      2  * Copyright (C) 2014 Patrick Mours
      3  * SPDX-License-Identifier: BSD-3-Clause
      4  */
      5 
      6 #include "effect_parser.hpp"
      7 #include "effect_codegen.hpp"
      8 #include <cmath> // signbit, isinf, isnan
      9 #include <cstdio> // snprintf
     10 #include <cassert>
     11 #include <algorithm> // std::find_if, std::max
     12 #include <locale>
     13 #include <sstream>
     14 #include <unordered_set>
     15 
     16 using namespace reshadefx;
     17 
     18 namespace {
     19 class codegen_glsl final : public codegen
     20 {
     21 public:
     22 	codegen_glsl(bool gles, bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types, bool flip_vert_y)
     23 		: _gles(gles), _debug_info(debug_info), _vulkan_semantics(vulkan_semantics), _uniforms_to_spec_constants(uniforms_to_spec_constants), _enable_16bit_types(enable_16bit_types), _flip_vert_y(flip_vert_y)
     24 	{
     25 		// Create default block and reserve a memory block to avoid frequent reallocations
     26 		std::string &block = _blocks.emplace(0, std::string()).first->second;
     27 		block.reserve(8192);
     28 	}
     29 
     30 private:
     31 	enum class naming
     32 	{
     33 		// After escaping, name should already be unique, so no additional steps are taken
     34 		unique,
     35 		// After escaping, will be numbered when clashing with another name
     36 		general,
     37 		// This is a special name that is not modified and should be unique
     38 		reserved,
     39 		// Replace name with a code snippet
     40 		expression,
     41 	};
     42 
     43 	std::string _ubo_block;
     44 	std::string _compute_block;
     45 	std::unordered_map<id, std::string> _names;
     46 	std::unordered_map<id, std::string> _blocks;
     47 	bool _gles = false;
     48 	bool _debug_info = false;
     49 	bool _vulkan_semantics = false;
     50 	bool _uniforms_to_spec_constants = false;
     51 	bool _enable_16bit_types = false;
     52 	bool _flip_vert_y = false;
     53 	bool _enable_control_flow_attributes = false;
     54 	std::unordered_map<id, id> _remapped_sampler_variables;
     55 	std::unordered_map<std::string, uint32_t> _semantic_to_location;
     56 
     57 	// Only write compatibility intrinsics to result if they are actually in use
     58 	bool _uses_fmod = false;
     59 	bool _uses_componentwise_or = false;
     60 	bool _uses_componentwise_and = false;
     61 	bool _uses_componentwise_cond = false;
     62 
     63 	void write_result(module &module) override
     64 	{
     65 		module = std::move(_module);
     66 
     67 		std::string preamble;
     68 
     69 		if (_enable_16bit_types)
     70 			// GL_NV_gpu_shader5, GL_AMD_gpu_shader_half_float or GL_EXT_shader_16bit_storage
     71 			preamble += "#extension GL_NV_gpu_shader5 : require\n";
     72 		if (_enable_control_flow_attributes)
     73 			preamble += "#extension GL_EXT_control_flow_attributes : enable\n";
     74 
     75 		if (_uses_fmod)
     76 			preamble += "float fmodHLSL(float x, float y) { return x - y * trunc(x / y); }\n"
     77 				"vec2 fmodHLSL(vec2 x, vec2 y) { return x - y * trunc(x / y); }\n"
     78 				"vec3 fmodHLSL(vec3 x, vec3 y) { return x - y * trunc(x / y); }\n"
     79 				"vec4 fmodHLSL(vec4 x, vec4 y) { return x - y * trunc(x / y); }\n"
     80 				"mat2 fmodHLSL(mat2 x, mat2 y) { return x - matrixCompMult(y, mat2(trunc(x[0] / y[0]), trunc(x[1] / y[1]))); }\n"
     81 				"mat3 fmodHLSL(mat3 x, mat3 y) { return x - matrixCompMult(y, mat3(trunc(x[0] / y[0]), trunc(x[1] / y[1]), trunc(x[2] / y[2]))); }\n"
     82 				"mat4 fmodHLSL(mat4 x, mat4 y) { return x - matrixCompMult(y, mat4(trunc(x[0] / y[0]), trunc(x[1] / y[1]), trunc(x[2] / y[2]), trunc(x[3] / y[3]))); }\n";
     83 		if (_uses_componentwise_or)
     84 			preamble +=
     85 				"bvec2 compOr(bvec2 a, bvec2 b) { return bvec2(a.x || b.x, a.y || b.y); }\n"
     86 				"bvec3 compOr(bvec3 a, bvec3 b) { return bvec3(a.x || b.x, a.y || b.y, a.z || b.z); }\n"
     87 				"bvec4 compOr(bvec4 a, bvec4 b) { return bvec4(a.x || b.x, a.y || b.y, a.z || b.z, a.w || b.w); }\n";
     88 		if (_uses_componentwise_and)
     89 			preamble +=
     90 				"bvec2 compAnd(bvec2 a, bvec2 b) { return bvec2(a.x && b.x, a.y && b.y); }\n"
     91 				"bvec3 compAnd(bvec3 a, bvec3 b) { return bvec3(a.x && b.x, a.y && b.y, a.z && b.z); }\n"
     92 				"bvec4 compAnd(bvec4 a, bvec4 b) { return bvec4(a.x && b.x, a.y && b.y, a.z && b.z, a.w && b.w); }\n";
     93 		if (_uses_componentwise_cond)
     94 			preamble +=
     95 				"vec2 compCond(bvec2 cond, vec2 a, vec2 b) { return vec2(cond.x ? a.x : b.x, cond.y ? a.y : b.y); }\n"
     96 				"vec3 compCond(bvec3 cond, vec3 a, vec3 b) { return vec3(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z); }\n"
     97 				"vec4 compCond(bvec4 cond, vec4 a, vec4 b) { return vec4(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z, cond.w ? a.w : b.w); }\n"
     98 				"ivec2 compCond(bvec2 cond, ivec2 a, ivec2 b) { return ivec2(cond.x ? a.x : b.x, cond.y ? a.y : b.y); }\n"
     99 				"ivec3 compCond(bvec3 cond, ivec3 a, ivec3 b) { return ivec3(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z); }\n"
    100 				"ivec4 compCond(bvec4 cond, ivec4 a, ivec4 b) { return ivec4(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z, cond.w ? a.w : b.w); }\n"
    101 				"uvec2 compCond(bvec2 cond, uvec2 a, uvec2 b) { return uvec2(cond.x ? a.x : b.x, cond.y ? a.y : b.y); }\n"
    102 				"uvec3 compCond(bvec3 cond, uvec3 a, uvec3 b) { return uvec3(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z); }\n"
    103 				"uvec4 compCond(bvec4 cond, uvec4 a, uvec4 b) { return uvec4(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z, cond.w ? a.w : b.w); }\n";
    104 
    105 		if (!_ubo_block.empty())
    106 		{
    107 			if (_vulkan_semantics)
    108 			{
    109 				preamble += "layout(std140, set = 0, binding = 0) uniform _Globals {\n" + _ubo_block + "};\n";
    110 			}
    111 			else
    112 			{
    113 				preamble += "layout(std140, binding = 0) uniform _Globals {\n" + _ubo_block + "};\n";
    114 			}
    115 		}
    116 
    117 		module.code.assign(preamble.begin(), preamble.end());
    118 
    119 		const std::string &main_block = _blocks.at(0);
    120 		module.code.insert(module.code.end(), main_block.begin(), main_block.end());
    121 	}
    122 
    123 	template <bool is_param = false, bool is_decl = true, bool is_interface = false>
    124 	void write_type(std::string &s, const type &type) const
    125 	{
    126 		if constexpr (is_decl)
    127 		{
    128 			// Global variables are implicitly 'static' in GLSL, so the keyword does not exist
    129 			if (type.has(type::q_precise))
    130 				s += "precise ";
    131 			if (type.has(type::q_groupshared))
    132 				s += "shared ";
    133 		}
    134 
    135 		if constexpr (is_interface)
    136 		{
    137 			if (type.has(type::q_linear))
    138 				s += "smooth ";
    139 			if (type.has(type::q_noperspective))
    140 				s += "noperspective ";
    141 			if (type.has(type::q_centroid))
    142 				s += "centroid ";
    143 			if (type.has(type::q_nointerpolation))
    144 				s += "flat ";
    145 		}
    146 
    147 		if constexpr (is_interface || is_param)
    148 		{
    149 			if (type.has(type::q_inout))
    150 				s += "inout ";
    151 			else if (type.has(type::q_in))
    152 				s += "in ";
    153 			else if (type.has(type::q_out))
    154 				s += "out ";
    155 		}
    156 
    157 		switch (type.base)
    158 		{
    159 		case type::t_void:
    160 			s += "void";
    161 			break;
    162 		case type::t_bool:
    163 			if (type.cols > 1)
    164 				s += "mat" + std::to_string(type.rows) + 'x' + std::to_string(type.cols);
    165 			else if (type.rows > 1)
    166 				s += "bvec" + std::to_string(type.rows);
    167 			else
    168 				s += "bool";
    169 			break;
    170 		case type::t_min16int:
    171 			if (_enable_16bit_types)
    172 			{
    173 				assert(type.cols == 1);
    174 				if (type.rows > 1)
    175 					s += "i16vec" + std::to_string(type.rows);
    176 				else
    177 					s += "int16_t";
    178 				break;
    179 			}
    180 			else if constexpr (is_decl)
    181 				s += "mediump ";
    182 			[[fallthrough]];
    183 		case type::t_int:
    184 			if (type.cols > 1)
    185 				s += "mat" + std::to_string(type.rows) + 'x' + std::to_string(type.cols);
    186 			else if (type.rows > 1)
    187 				s += "ivec" + std::to_string(type.rows);
    188 			else
    189 				s += "int";
    190 			break;
    191 		case type::t_min16uint:
    192 			if (_enable_16bit_types)
    193 			{
    194 				assert(type.cols == 1);
    195 				if (type.rows > 1)
    196 					s += "u16vec" + std::to_string(type.rows);
    197 				else
    198 					s += "uint16_t";
    199 				break;
    200 			}
    201 			else if constexpr (is_decl)
    202 				s += "mediump ";
    203 			[[fallthrough]];
    204 		case type::t_uint:
    205 			if (type.cols > 1)
    206 				s += "mat" + std::to_string(type.rows) + 'x' + std::to_string(type.cols);
    207 			else if (type.rows > 1)
    208 				s += "uvec" + std::to_string(type.rows);
    209 			else
    210 				s += "uint";
    211 			break;
    212 		case type::t_min16float:
    213 			if (_enable_16bit_types)
    214 			{
    215 				assert(type.cols == 1);
    216 				if (type.rows > 1)
    217 					s += "f16vec" + std::to_string(type.rows);
    218 				else
    219 					s += "float16_t";
    220 				break;
    221 			}
    222 			else if constexpr (is_decl)
    223 				s += "mediump ";
    224 			[[fallthrough]];
    225 		case type::t_float:
    226 			if (type.cols > 1)
    227 				s += "mat" + std::to_string(type.rows) + 'x' + std::to_string(type.cols);
    228 			else if (type.rows > 1)
    229 				s += "vec" + std::to_string(type.rows);
    230 			else
    231 				s += "float";
    232 			break;
    233 		case type::t_struct:
    234 			s += id_to_name(type.definition);
    235 			break;
    236 		case type::t_sampler1d_int:
    237 			s += "isampler1D";
    238 			break;
    239 		case type::t_sampler2d_int:
    240 			s += "isampler2D";
    241 			break;
    242 		case type::t_sampler3d_int:
    243 			s += "isampler3D";
    244 			break;
    245 		case type::t_sampler1d_uint:
    246 			s += "usampler1D";
    247 			break;
    248 		case type::t_sampler3d_uint:
    249 			s += "usampler3D";
    250 			break;
    251 		case type::t_sampler2d_uint:
    252 			s += "usampler2D";
    253 			break;
    254 		case type::t_sampler1d_float:
    255 			s += "sampler1D";
    256 			break;
    257 		case type::t_sampler2d_float:
    258 			s += "sampler2D";
    259 			break;
    260 		case type::t_sampler3d_float:
    261 			s += "sampler3D";
    262 			break;
    263 		case type::t_storage1d_int:
    264 			if constexpr (is_param)
    265 				s += "writeonly ";
    266 			s += "iimage1D";
    267 			break;
    268 		case type::t_storage2d_int:
    269 			if constexpr (is_param)
    270 				s += "writeonly ";
    271 			s += "iimage2D";
    272 			break;
    273 		case type::t_storage3d_int:
    274 			if constexpr (is_param)
    275 				s += "writeonly ";
    276 			s += "iimage3D";
    277 			break;
    278 		case type::t_storage1d_uint:
    279 			if constexpr (is_param)
    280 				s += "writeonly ";
    281 			s += "uimage1D";
    282 			break;
    283 		case type::t_storage2d_uint:
    284 			if constexpr (is_param)
    285 				s += "writeonly ";
    286 			s += "uimage2D";
    287 			break;
    288 		case type::t_storage3d_uint:
    289 			if constexpr (is_param)
    290 				s += "writeonly ";
    291 			s += "uimage3D";
    292 			break;
    293 		case type::t_storage1d_float:
    294 			if constexpr (is_param)
    295 				s += "writeonly ";
    296 			s += "image1D";
    297 			break;
    298 		case type::t_storage2d_float:
    299 			if constexpr (is_param) // Images need a format to be readable, but declaring that on function parameters is not well supported, so can only support write-only images there
    300 				s += "writeonly ";
    301 			s += "image2D";
    302 			break;
    303 		case type::t_storage3d_float:
    304 			if constexpr (is_param)
    305 				s += "writeonly ";
    306 			s += "image3D";
    307 			break;
    308 		default:
    309 			assert(false);
    310 		}
    311 	}
    312 	void write_constant(std::string &s, const type &type, const constant &data) const
    313 	{
    314 		if (type.is_array())
    315 		{
    316 			auto elem_type = type;
    317 			elem_type.array_length = 0;
    318 
    319 			write_type<false, false>(s, elem_type);
    320 			s += '[' + std::to_string(type.array_length) + "](";
    321 
    322 			for (int i = 0; i < type.array_length; ++i)
    323 			{
    324 				write_constant(s, elem_type, i < static_cast<int>(data.array_data.size()) ? data.array_data[i] : constant());
    325 
    326 				if (i < type.array_length - 1)
    327 					s += ", ";
    328 			}
    329 
    330 			s += ')';
    331 			return;
    332 		}
    333 
    334 		// There can only be numeric constants
    335 		assert(type.is_numeric());
    336 
    337 		if (!type.is_scalar())
    338 			write_type<false, false>(s, type), s += '(';
    339 
    340 		for (unsigned int i = 0, components = type.components(); i < components; ++i)
    341 		{
    342 			switch (type.base)
    343 			{
    344 			case type::t_bool:
    345 				s += data.as_uint[i] ? "true" : "false";
    346 				break;
    347 			case type::t_min16int:
    348 			case type::t_int:
    349 				s += std::to_string(data.as_int[i]);
    350 				break;
    351 			case type::t_min16uint:
    352 			case type::t_uint:
    353 				s += std::to_string(data.as_uint[i]) + 'u';
    354 				break;
    355 			case type::t_min16float:
    356 			case type::t_float:
    357 				if (std::isnan(data.as_float[i])) {
    358 					s += "0.0/0.0/*nan*/";
    359 					break;
    360 				}
    361 				if (std::isinf(data.as_float[i])) {
    362 					s += std::signbit(data.as_float[i]) ? "1.0/0.0/*inf*/" : "-1.0/0.0/*-inf*/";
    363 					break;
    364 				}
    365 				{
    366 					std::ostringstream ss;
    367 					ss.imbue(std::locale::classic());
    368 					ss << data.as_float[i];
    369 					s += ss.str();
    370 				}
    371 				break;
    372 			default:
    373 				assert(false);
    374 			}
    375 
    376 			if (i < components - 1)
    377 				s += ", ";
    378 		}
    379 
    380 		if (!type.is_scalar())
    381 			s += ')';
    382 	}
    383 	void write_location(std::string &s, const location &loc) const
    384 	{
    385 		if (loc.source.empty() || !_debug_info)
    386 			return;
    387 
    388 		s += "#line " + std::to_string(loc.line) + '\n';
    389 	}
    390 	void write_texture_format(std::string &s, texture_format format)
    391 	{
    392 		switch (format)
    393 		{
    394 		case texture_format::r8:
    395 			s += "r8";
    396 			break;
    397 		case texture_format::r16:
    398 			s += "r16";
    399 			break;
    400 		case texture_format::r16f:
    401 			s += "r16f";
    402 			break;
    403 		case texture_format::r32i:
    404 			s += "r32i";
    405 			break;
    406 		case texture_format::r32u:
    407 			s += "r32u";
    408 			break;
    409 		case texture_format::r32f:
    410 			s += "r32f";
    411 			break;
    412 		case texture_format::rg8:
    413 			s += "rg8";
    414 			break;
    415 		case texture_format::rg16:
    416 			s += "rg16";
    417 			break;
    418 		case texture_format::rg16f:
    419 			s += "rg16f";
    420 			break;
    421 		case texture_format::rg32f:
    422 			s += "rg32f";
    423 			break;
    424 		case texture_format::rgba8:
    425 			s += "rgba8";
    426 			break;
    427 		case texture_format::rgba16:
    428 			s += "rgba16";
    429 			break;
    430 		case texture_format::rgba16f:
    431 			s += "rgba16f";
    432 			break;
    433 		case texture_format::rgba32f:
    434 			s += "rgba32f";
    435 			break;
    436 		case texture_format::rgb10a2:
    437 			s += "rgb10_a2";
    438 			break;
    439 		default:
    440 			assert(false);
    441 		}
    442 	}
    443 
    444 	std::string id_to_name(id id) const
    445 	{
    446 		if (const auto it = _remapped_sampler_variables.find(id);
    447 			it != _remapped_sampler_variables.end())
    448 			id = it->second;
    449 
    450 		assert(id != 0);
    451 		if (const auto names_it = _names.find(id);
    452 			names_it != _names.end())
    453 			return names_it->second;
    454 		return '_' + std::to_string(id);
    455 	}
    456 
    457 	template <naming naming_type = naming::general>
    458 	void define_name(const id id, std::string name)
    459 	{
    460 		assert(!name.empty());
    461 		if constexpr (naming_type != naming::expression)
    462 			if (name[0] == '_')
    463 				return; // Filter out names that may clash with automatic ones
    464 		if constexpr (naming_type != naming::reserved)
    465 			name = escape_name(std::move(name));
    466 		if constexpr (naming_type == naming::general)
    467 			if (std::find_if(_names.begin(), _names.end(), [&name](const auto &it) { return it.second == name; }) != _names.end())
    468 				name += '_' + std::to_string(id); // Append a numbered suffix if the name already exists
    469 		_names[id] = std::move(name);
    470 	}
    471 
    472 	uint32_t semantic_to_location(const std::string &semantic, uint32_t max_array_length = 1)
    473 	{
    474 		if (semantic.compare(0, 5, "COLOR") == 0)
    475 			return std::strtoul(semantic.c_str() + 5, nullptr, 10);
    476 		if (semantic.compare(0, 9, "SV_TARGET") == 0)
    477 			return std::strtoul(semantic.c_str() + 9, nullptr, 10);
    478 
    479 		if (const auto it = _semantic_to_location.find(semantic);
    480 			it != _semantic_to_location.end())
    481 			return it->second;
    482 
    483 		// Extract the semantic index from the semantic name (e.g. 2 for "TEXCOORD2")
    484 		size_t digit_index = semantic.size() - 1;
    485 		while (digit_index != 0 && semantic[digit_index] >= '0' && semantic[digit_index] <= '9')
    486 			digit_index--;
    487 		digit_index++;
    488 
    489 		const uint32_t semantic_digit = std::strtoul(semantic.c_str() + digit_index, nullptr, 10);
    490 		const std::string semantic_base = semantic.substr(0, digit_index);
    491 
    492 		uint32_t location = static_cast<uint32_t>(_semantic_to_location.size());
    493 
    494 		// Now create adjoining location indices for all possible semantic indices belonging to this semantic name
    495 		for (uint32_t a = 0; a < semantic_digit + max_array_length; ++a)
    496 		{
    497 			const auto insert = _semantic_to_location.emplace(semantic_base + std::to_string(a), location + a);
    498 			if (!insert.second)
    499 			{
    500 				assert(a == 0 || (insert.first->second - a) == location);
    501 
    502 				// Semantic was already created with a different location index, so need to remap to that
    503 				location = insert.first->second - a;
    504 			}
    505 		}
    506 
    507 		return location + semantic_digit;
    508 	}
    509 
    510 	std::string escape_name(std::string name) const
    511 	{
    512 		static const std::unordered_set<std::string> s_reserverd_names = {
    513 			"common", "partition", "input", "output", "active", "filter", "superp", "invariant",
    514 			"attribute", "varying", "buffer", "resource", "coherent", "readonly", "writeonly",
    515 			"layout", "flat", "smooth", "lowp", "mediump", "highp", "precision", "patch", "subroutine",
    516 			"atomic_uint", "fixed",
    517 			"vec2", "vec3", "vec4", "ivec2", "dvec2", "dvec3", "dvec4", "ivec3", "ivec4", "uvec2", "uvec3", "uvec4", "bvec2", "bvec3", "bvec4", "fvec2", "fvec3", "fvec4", "hvec2", "hvec3", "hvec4",
    518 			"mat2", "mat3", "mat4", "dmat2", "dmat3", "dmat4", "mat2x2", "mat2x3", "mat2x4", "dmat2x2", "dmat2x3", "dmat2x4", "mat3x2", "mat3x3", "mat3x4", "dmat3x2", "dmat3x3", "dmat3x4", "mat4x2", "mat4x3", "mat4x4", "dmat4x2", "dmat4x3", "dmat4x4",
    519 			"sampler1DShadow", "sampler1DArrayShadow", "isampler1D", "isampler1DArray", "usampler1D", "usampler1DArray",
    520 			"sampler2DShadow", "sampler2DArrayShadow", "isampler2D", "isampler2DArray", "usampler2D", "usampler2DArray", "sampler2DRect", "sampler2DRectShadow", "isampler2DRect", "usampler2DRect", "isampler2DMS", "usampler2DMS", "isampler2DMSArray", "usampler2DMSArray",
    521 			"isampler3D", "usampler3D", "sampler3DRect",
    522 			"samplerCubeShadow", "samplerCubeArrayShadow", "isamplerCube", "isamplerCubeArray", "usamplerCube", "usamplerCubeArray",
    523 			"samplerBuffer", "isamplerBuffer", "usamplerBuffer",
    524 			"image1D", "iimage1D", "uimage1D", "image1DArray", "iimage1DArray", "uimage1DArray",
    525 			"image2D", "iimage2D", "uimage2D", "image2DArray", "iimage2DArray", "uimage2DArray", "image2DRect", "iimage2DRect", "uimage2DRect", "image2DMS", "iimage2DMS", "uimage2DMS", "image2DMSArray", "iimage2DMSArray", "uimage2DMSArray",
    526 			"image3D", "iimage3D", "uimage3D",
    527 			"imageCube", "iimageCube", "uimageCube", "imageCubeArray", "iimageCubeArray", "uimageCubeArray",
    528 			"imageBuffer", "iimageBuffer", "uimageBuffer",
    529 			"abs", "sign", "all", "any", "sin", "sinh", "cos", "cosh", "tan", "tanh", "asin", "acos", "atan",
    530 			"exp", "exp2", "log", "log2", "sqrt", "inversesqrt", "ceil", "floor", "fract", "trunc", "round",
    531 			"radians", "degrees", "length", "normalize", "transpose", "determinant", "intBitsToFloat", "uintBitsToFloat",
    532 			"floatBitsToInt", "floatBitsToUint", "matrixCompMult", "not", "lessThan", "greaterThan", "lessThanEqual",
    533 			"greaterThanEqual", "equal", "notEqual", "dot", "cross", "distance", "pow", "modf", "frexp", "ldexp",
    534 			"min", "max", "step", "reflect", "texture", "textureOffset", "fma", "mix", "clamp", "smoothstep", "refract",
    535 			"faceforward", "textureLod", "textureLodOffset", "texelFetch", "main"
    536 		};
    537 
    538 		// Escape reserved names so that they do not fail to compile
    539 		if (name.compare(0, 3, "gl_") == 0 || s_reserverd_names.count(name))
    540 			// Append an underscore at start instead of the end, since another one may get added in 'define_name' when there is a suffix
    541 			// This is guaranteed to not clash with user defined names, since those starting with an underscore are filtered out in 'define_name'
    542 			name = '_' + name;
    543 
    544 		// Remove duplicated underscore symbols from name which can occur due to namespaces but are not allowed in GLSL
    545 		for (size_t pos = 0; (pos = name.find("__", pos)) != std::string::npos;)
    546 			name.replace(pos, 2, "_");
    547 
    548 		return name;
    549 	}
    550 	std::string semantic_to_builtin(std::string name, const std::string &semantic, shader_type stype) const
    551 	{
    552 		if (semantic == "SV_POSITION")
    553 			return stype == shader_type::ps ? "gl_FragCoord" : "gl_Position";
    554 		if (semantic == "SV_POINTSIZE")
    555 			return "gl_PointSize";
    556 		if (semantic == "SV_DEPTH")
    557 			return "gl_FragDepth";
    558 		if (semantic == "SV_VERTEXID")
    559 			return _vulkan_semantics ? "gl_VertexIndex" : "gl_VertexID";
    560 		if (semantic == "SV_ISFRONTFACE")
    561 			return "gl_FrontFacing";
    562 		if (semantic == "SV_GROUPID")
    563 			return "gl_WorkGroupID";
    564 		if (semantic == "SV_GROUPINDEX")
    565 			return "gl_LocalInvocationIndex";
    566 		if (semantic == "SV_GROUPTHREADID")
    567 			return "gl_LocalInvocationID";
    568 		if (semantic == "SV_DISPATCHTHREADID")
    569 			return "gl_GlobalInvocationID";
    570 
    571 		return escape_name(std::move(name));
    572 	}
    573 
    574 	static void increase_indentation_level(std::string &block)
    575 	{
    576 		if (block.empty())
    577 			return;
    578 
    579 		for (size_t pos = 0; (pos = block.find("\n\t", pos)) != std::string::npos; pos += 3)
    580 			block.replace(pos, 2, "\n\t\t");
    581 
    582 		block.insert(block.begin(), '\t');
    583 	}
    584 
    585 	id   define_struct(const location &loc, struct_info &info) override
    586 	{
    587 		info.definition = make_id();
    588 		define_name<naming::unique>(info.definition, info.unique_name);
    589 
    590 		_structs.push_back(info);
    591 
    592 		std::string &code = _blocks.at(_current_block);
    593 
    594 		write_location(code, loc);
    595 
    596 		code += "struct " + id_to_name(info.definition) + "\n{\n";
    597 
    598 		for (const struct_member_info &member : info.member_list)
    599 		{
    600 			code += '\t';
    601 			write_type(code, member.type); // GLSL does not allow interpolation attributes on struct members
    602 			code += ' ';
    603 			code += escape_name(member.name);
    604 			if (member.type.is_array())
    605 				code += '[' + std::to_string(member.type.array_length) + ']';
    606 			code += ";\n";
    607 		}
    608 
    609 		if (info.member_list.empty())
    610 			code += "float _dummy;\n";
    611 
    612 		code += "};\n";
    613 
    614 		return info.definition;
    615 	}
    616 	id   define_texture(const location &, texture_info &info) override
    617 	{
    618 		info.id = make_id();
    619 		info.binding = ~0u;
    620 
    621 		_module.textures.push_back(info);
    622 
    623 		return info.id;
    624 	}
    625 	id   define_sampler(const location &loc, const texture_info &, sampler_info &info) override
    626 	{
    627 		info.id = make_id();
    628 		info.binding = _module.num_sampler_bindings++;
    629 		info.texture_binding = ~0u; // Unset texture bindings
    630 
    631 		define_name<naming::unique>(info.id, info.unique_name);
    632 
    633 		std::string &code = _blocks.at(_current_block);
    634 
    635 		write_location(code, loc);
    636 
    637 		code += "layout(";
    638 		if (_vulkan_semantics)
    639 			code += "set = 1, ";
    640 #if 0
    641 		code += "binding = " + std::to_string(info.binding);
    642 #else
    643 		code += "binding = /*SAMPLER:" + info.unique_name + "*/0";
    644 #endif
    645 		code += ") uniform ";
    646 		write_type(code, info.type);
    647 		code += ' ' + id_to_name(info.id) + ";\n";
    648 
    649 		_module.samplers.push_back(info);
    650 
    651 		return info.id;
    652 	}
    653 	id   define_storage(const location &loc, const texture_info &tex_info, storage_info &info) override
    654 	{
    655 		info.id = make_id();
    656 		info.binding = _module.num_storage_bindings++;
    657 
    658 		define_name<naming::unique>(info.id, info.unique_name);
    659 
    660 		std::string &code = _blocks.at(_current_block);
    661 
    662 		write_location(code, loc);
    663 
    664 		code += "layout(binding = " + std::to_string(info.binding) + ", ";
    665 		write_texture_format(code, tex_info.format);
    666 		code += ") uniform ";
    667 		write_type(code, info.type);
    668 		code += ' ' + id_to_name(info.id) + ";\n";
    669 
    670 		_module.storages.push_back(info);
    671 
    672 		return info.id;
    673 	}
    674 	id   define_uniform(const location &loc, uniform_info &info) override
    675 	{
    676 		const id res = make_id();
    677 
    678 		define_name<naming::unique>(res, info.name);
    679 
    680 		if (_uniforms_to_spec_constants && info.has_initializer_value)
    681 		{
    682 			info.size = info.type.components() * 4;
    683 			if (info.type.is_array())
    684 				info.size *= info.type.array_length;
    685 
    686 			std::string &code = _blocks.at(_current_block);
    687 
    688 			write_location(code, loc);
    689 
    690 			assert(!info.type.has(type::q_static) && !info.type.has(type::q_const));
    691 
    692 			code += "const ";
    693 			write_type(code, info.type);
    694 			code += ' ' + id_to_name(res) + " = ";
    695 			if (!info.type.is_scalar())
    696 				write_type<false, false>(code, info.type);
    697 			code += "(SPEC_CONSTANT_" + info.name + ");\n";
    698 
    699 			_module.spec_constants.push_back(info);
    700 		}
    701 		else
    702 		{
    703 			// GLSL specification on std140 layout:
    704 			// 1. If the member is a scalar consuming N basic machine units, the base alignment is N.
    705 			// 2. If the member is a two- or four-component vector with components consuming N basic machine units, the base alignment is 2N or 4N, respectively.
    706 			// 3. If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N.
    707 			// 4. If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element,
    708 			//    according to rules (1), (2), and (3), and rounded up to the base alignment of a four-component vector.
    709 			// 7. If the member is a row-major matrix with C columns and R rows, the matrix is stored identically to an array of R row vectors with C components each, according to rule (4).
    710 			// 8. If the member is an array of S row-major matrices with C columns and R rows, the matrix is stored identically to a row of S*R row vectors with C components each, according to rule (4).
    711 			uint32_t alignment = (info.type.rows == 3 ? 4 /* (3) */ : info.type.rows /* (2)*/) * 4 /* (1)*/;
    712 			info.size = info.type.rows * 4;
    713 
    714 			if (info.type.is_matrix())
    715 			{
    716 				alignment = 16 /* (4) */;
    717 				info.size = info.type.rows * alignment /* (7), (8) */;
    718 			}
    719 			if (info.type.is_array())
    720 			{
    721 				alignment = 16 /* (4) */;
    722 				info.size = align_up(info.size, alignment) * info.type.array_length;
    723 			}
    724 
    725 			// Adjust offset according to alignment rules from above
    726 			info.offset = _module.total_uniform_size;
    727 			info.offset = align_up(info.offset, alignment);
    728 			_module.total_uniform_size = info.offset + info.size;
    729 
    730 			write_location(_ubo_block, loc);
    731 
    732 			_ubo_block += '\t';
    733 			// Note: All matrices are floating-point, even if the uniform type says different!!
    734 			write_type(_ubo_block, info.type);
    735 			_ubo_block += ' ' + id_to_name(res);
    736 
    737 			if (info.type.is_array())
    738 				_ubo_block += '[' + std::to_string(info.type.array_length) + ']';
    739 
    740 			_ubo_block += ";\n";
    741 
    742 			_module.uniforms.push_back(info);
    743 		}
    744 
    745 		return res;
    746 	}
    747 	id   define_variable(const location &loc, const type &type, std::string name, bool global, id initializer_value) override
    748 	{
    749 		const id res = make_id();
    750 
    751 		// GLSL does not allow local sampler variables, so try to remap those
    752 		if (!global && type.is_sampler())
    753 			return (_remapped_sampler_variables[res] = 0), res;
    754 
    755 		if (!name.empty())
    756 			define_name<naming::general>(res, name);
    757 
    758 		std::string &code = _blocks.at(_current_block);
    759 
    760 		write_location(code, loc);
    761 
    762 		if (!global)
    763 			code += '\t';
    764 
    765 		if (initializer_value != 0 && (type.has(type::q_const) && !_gles))
    766 			code += "const ";
    767 
    768 		write_type(code, type);
    769 		code += ' ' + id_to_name(res);
    770 
    771 		if (type.is_array())
    772 			code += '[' + std::to_string(type.array_length) + ']';
    773 
    774 		if (initializer_value != 0)
    775 			code += " = " + id_to_name(initializer_value);
    776 
    777 		code += ";\n";
    778 
    779 		return res;
    780 	}
    781 	id   define_function(const location &loc, function_info &info) override
    782 	{
    783 		return define_function(loc, info, false);
    784 	}
    785 
    786 	id   define_function(const location &loc, function_info &info, bool is_entry_point)
    787 	{
    788 		info.definition = make_id();
    789 
    790 		// Name is used in other places like the "ENTRY_POINT" defines, so escape it here
    791 		info.unique_name = escape_name(info.unique_name);
    792 
    793 		if (!is_entry_point)
    794 			define_name<naming::unique>(info.definition, info.unique_name);
    795 		else
    796 			define_name<naming::reserved>(info.definition, "main");
    797 
    798 		std::string &code = _blocks.at(_current_block);
    799 
    800 		write_location(code, loc);
    801 
    802 		write_type(code, info.return_type);
    803 		code += ' ' + id_to_name(info.definition) + '(';
    804 
    805 		assert(info.parameter_list.empty() || !is_entry_point);
    806 
    807 		for (size_t i = 0, num_params = info.parameter_list.size(); i < num_params; ++i)
    808 		{
    809 			auto &param = info.parameter_list[i];
    810 
    811 			param.definition = make_id();
    812 			define_name<naming::unique>(param.definition, param.name);
    813 
    814 			code += '\n';
    815 			write_location(code, param.location);
    816 			code += '\t';
    817 			write_type<true>(code, param.type); // GLSL does not allow interpolation attributes on function parameters
    818 			code += ' ' + id_to_name(param.definition);
    819 
    820 			if (param.type.is_array())
    821 				code += '[' + std::to_string(param.type.array_length) + ']';
    822 
    823 			if (i < num_params - 1)
    824 				code += ',';
    825 		}
    826 
    827 		code += ")\n";
    828 
    829 		_functions.push_back(std::make_unique<function_info>(info));
    830 
    831 		return info.definition;
    832 	}
    833 
    834 	void define_entry_point(function_info &func, shader_type stype, int num_threads[3]) override
    835 	{
    836 		// Modify entry point name so each thread configuration is made separate
    837 		if (stype == shader_type::cs)
    838 			func.unique_name = 'E' + func.unique_name +
    839 				'_' + std::to_string(num_threads[0]) +
    840 				'_' + std::to_string(num_threads[1]) +
    841 				'_' + std::to_string(num_threads[2]);
    842 
    843 		if (const auto it = std::find_if(_module.entry_points.begin(), _module.entry_points.end(),
    844 				[&func](const auto &ep) { return ep.name == func.unique_name; });
    845 			it != _module.entry_points.end())
    846 			return;
    847 
    848 		_module.entry_points.push_back({ func.unique_name, stype });
    849 
    850 		_blocks.at(0) += "#ifdef ENTRY_POINT_" + func.unique_name + '\n';
    851 		if (stype == shader_type::cs)
    852 			_blocks.at(0) += "layout(local_size_x = " + std::to_string(num_threads[0]) +
    853 														", local_size_y = " + std::to_string(num_threads[1]) +
    854 														", local_size_z = " + std::to_string(num_threads[2]) + ") in;\n";
    855 
    856 		function_info entry_point;
    857 		entry_point.return_type = { type::t_void };
    858 
    859 		std::unordered_map<std::string, std::string> semantic_to_varying_variable;
    860 
    861 		const auto create_varying_variable = [this, stype, &semantic_to_varying_variable](type type, unsigned int extra_qualifiers, const std::string &name, const std::string &semantic) {
    862 			// Skip built in variables
    863 			if (!semantic_to_builtin(std::string(), semantic, stype).empty())
    864 				return;
    865 
    866 			// Do not create multiple input/output variables for duplicate semantic usage (since every input/output location may only be defined once in GLSL)
    867 			if ((extra_qualifiers & type::q_in) != 0 &&
    868 				!semantic_to_varying_variable.emplace(semantic, name).second)
    869 				return;
    870 
    871 			type.qualifiers |= extra_qualifiers;
    872 			assert((type.has(type::q_in) || type.has(type::q_out)) && !type.has(type::q_inout));
    873 
    874 			// OpenGL does not allow varying of type boolean
    875 			if (type.is_boolean())
    876 				type.base = type::t_float;
    877 
    878 			std::string &code = _blocks.at(_current_block);
    879 
    880 			const int array_length = std::max(1, type.array_length);
    881 			const uint32_t location = semantic_to_location(semantic, array_length);
    882 
    883 			for (int a = 0; a < array_length; ++a)
    884 			{
    885 				code += "layout(location = " + std::to_string(location + a) + ") ";
    886 				write_type<false, false, true>(code, type);
    887 				code += ' ';
    888 				code += escape_name(type.is_array() ?
    889 					name + '_' + std::to_string(a) :
    890 					name);
    891 				code += ";\n";
    892 			}
    893 		};
    894 
    895 		// Translate function parameters to input/output variables
    896 		if (func.return_type.is_struct())
    897 		{
    898 			const struct_info &definition = get_struct(func.return_type.definition);
    899 
    900 			for (const struct_member_info &member : definition.member_list)
    901 				create_varying_variable(member.type, type::q_out, "_return_" + member.name, member.semantic);
    902 		}
    903 		else if (!func.return_type.is_void())
    904 		{
    905 			create_varying_variable(func.return_type, type::q_out, "_return", func.return_semantic);
    906 		}
    907 
    908 		const auto num_params = func.parameter_list.size();
    909 		for (size_t i = 0; i < num_params; ++i)
    910 		{
    911 			type param_type = func.parameter_list[i].type;
    912 			param_type.qualifiers &= ~type::q_inout;
    913 
    914 			// Create separate input/output variables for "inout" parameters (since "inout" is not valid on those in GLSL)
    915 			if (func.parameter_list[i].type.has(type::q_in))
    916 			{
    917 				// Flatten structure parameters
    918 				if (param_type.is_struct())
    919 				{
    920 					const struct_info &definition = get_struct(param_type.definition);
    921 
    922 					for (int a = 0, array_length = std::max(1, param_type.array_length); a < array_length; a++)
    923 						for (const struct_member_info &member : definition.member_list)
    924 							create_varying_variable(member.type, param_type.qualifiers | type::q_in, "_in_param" + std::to_string(i) + '_' + std::to_string(a) + '_' + member.name, member.semantic);
    925 				}
    926 				else
    927 				{
    928 					create_varying_variable(param_type, type::q_in, "_in_param" + std::to_string(i), func.parameter_list[i].semantic);
    929 				}
    930 			}
    931 
    932 			if (func.parameter_list[i].type.has(type::q_out))
    933 			{
    934 				if (param_type.is_struct())
    935 				{
    936 					const struct_info &definition = get_struct(param_type.definition);
    937 
    938 					for (int a = 0, array_length = std::max(1, param_type.array_length); a < array_length; a++)
    939 						for (const struct_member_info &member : definition.member_list)
    940 							create_varying_variable(member.type, param_type.qualifiers | type::q_out, "_out_param" + std::to_string(i) + '_' + std::to_string(a) + '_' + member.name, member.semantic);
    941 				}
    942 				else
    943 				{
    944 					create_varying_variable(param_type, type::q_out, "_out_param" + std::to_string(i), func.parameter_list[i].semantic);
    945 				}
    946 			}
    947 		}
    948 
    949 		// Translate return value to output variable
    950 		define_function({}, entry_point, true);
    951 		enter_block(create_block());
    952 
    953 		std::string &code = _blocks.at(_current_block);
    954 
    955 		// Handle input parameters
    956 		for (size_t i = 0; i < num_params; ++i)
    957 		{
    958 			const type &param_type = func.parameter_list[i].type;
    959 
    960 			if (param_type.has(type::q_in))
    961 			{
    962 				// Create local array element variables
    963 				for (int a = 0, array_length = std::max(1, param_type.array_length); a < array_length; a++)
    964 				{
    965 					if (param_type.is_struct())
    966 					{
    967 						// Build struct from separate member input variables
    968 						code += '\t';
    969 						write_type<false, true>(code, param_type);
    970 						code += ' ';
    971 						code += escape_name(param_type.is_array() ?
    972 							"_in_param" + std::to_string(i) + '_' + std::to_string(a) :
    973 							"_in_param" + std::to_string(i));
    974 						code += " = ";
    975 						write_type<false, false>(code, param_type);
    976 						code += '(';
    977 
    978 						const struct_info &definition = get_struct(param_type.definition);
    979 
    980 						for (const struct_member_info &member : definition.member_list)
    981 						{
    982 							std::string in_param_name = "_in_param" + std::to_string(i) + '_' + std::to_string(a) + '_' + member.name;
    983 							if (const auto it = semantic_to_varying_variable.find(member.semantic);
    984 								it != semantic_to_varying_variable.end() && it->second != in_param_name)
    985 								in_param_name = it->second;
    986 
    987 							if (member.type.is_array())
    988 							{
    989 								write_type<false, false>(code, member.type);
    990 								code += "[](";
    991 
    992 								for (int b = 0; b < member.type.array_length; b++)
    993 								{
    994 									// OpenGL does not allow varying of type boolean, so need to cast here
    995 									if (member.type.is_boolean())
    996 									{
    997 										write_type<false, false>(code, member.type);
    998 										code += '(';
    999 									}
   1000 
   1001 									code += escape_name(in_param_name + '_' + std::to_string(b));
   1002 
   1003 									if (member.type.is_boolean())
   1004 										code += ')';
   1005 
   1006 									if (b < member.type.array_length - 1)
   1007 										code += ", ";
   1008 								}
   1009 
   1010 								code += ')';
   1011 							}
   1012 							else
   1013 							{
   1014 								if (member.type.is_boolean() || (_gles && member.type.is_integral()))
   1015 								{
   1016 									write_type<false, false>(code, member.type);
   1017 									code += '(';
   1018 								}
   1019 
   1020 								code += semantic_to_builtin(std::move(in_param_name), member.semantic, stype);
   1021 
   1022 								if (member.type.is_boolean() || (_gles && member.type.is_integral()))
   1023 									code += ')';
   1024 							}
   1025 
   1026 							code += ", ";
   1027 						}
   1028 
   1029 						// There can be no empty structs, so can assume that the last two characters are always ", "
   1030 						code.pop_back();
   1031 						code.pop_back();
   1032 
   1033 						code += ");\n";
   1034 					}
   1035 					else if (const auto it = semantic_to_varying_variable.find(func.parameter_list[i].semantic);
   1036 						it != semantic_to_varying_variable.end() && it->second != "_in_param" + std::to_string(i))
   1037 					{
   1038 						// Create local variables for duplicated semantics (since no input/output variable is created for those, see 'create_varying_variable')
   1039 						code += '\t';
   1040 						write_type<false, true>(code, param_type);
   1041 						code += ' ';
   1042 						code += escape_name(param_type.is_array() ?
   1043 							"_in_param" + std::to_string(i) + '_' + std::to_string(a) :
   1044 							"_in_param" + std::to_string(i));
   1045 						code += " = ";
   1046 
   1047 						if (param_type.is_boolean())
   1048 						{
   1049 							write_type<false, false>(code, param_type);
   1050 							code += '(';
   1051 						}
   1052 
   1053 						code += escape_name(param_type.is_array() ?
   1054 							it->second + '_' + std::to_string(a) :
   1055 							it->second);
   1056 
   1057 						if (param_type.is_boolean())
   1058 							code += ')';
   1059 
   1060 						code += ";\n";
   1061 					}
   1062 				}
   1063 			}
   1064 
   1065 			// Create local parameter variables which are used as arguments in the entry point function call below
   1066 			code += '\t';
   1067 			write_type<false, true>(code, param_type);
   1068 			code += ' ';
   1069 			code += escape_name("_param" + std::to_string(i));
   1070 			if (param_type.is_array())
   1071 				code += '[' + std::to_string(param_type.array_length) + ']';
   1072 
   1073 			// Initialize those local variables with the input value if existing
   1074 			// Parameters with only an "out" qualifier are written to by the entry point function, so do not need to be initialized
   1075 			if (param_type.has(type::q_in))
   1076 			{
   1077 				code += " = ";
   1078 
   1079 				// Build array from separate array element variables
   1080 				if (param_type.is_array())
   1081 				{
   1082 					write_type<false, false>(code, param_type);
   1083 					code += "[](";
   1084 
   1085 					for (int a = 0; a < param_type.array_length; ++a)
   1086 					{
   1087 						// OpenGL does not allow varying of type boolean, so need to cast here
   1088 						if (param_type.is_boolean())
   1089 						{
   1090 							write_type<false, false>(code, param_type);
   1091 							code += '(';
   1092 						}
   1093 
   1094 						code += escape_name("_in_param" + std::to_string(i) + '_' + std::to_string(a));
   1095 
   1096 						if (param_type.is_boolean())
   1097 							code += ')';
   1098 
   1099 						if (a < param_type.array_length - 1)
   1100 							code += ", ";
   1101 					}
   1102 
   1103 					code += ')';
   1104 				}
   1105 				else
   1106 				{
   1107 					if (param_type.is_boolean() || (_gles && param_type.is_integral()))
   1108 					{
   1109 						write_type<false, false>(code, param_type);
   1110 						code += '(';
   1111 					}
   1112 
   1113 					code += semantic_to_builtin("_in_param" + std::to_string(i), func.parameter_list[i].semantic, stype);
   1114 
   1115 					if (param_type.is_boolean() || (_gles && param_type.is_integral()))
   1116 						code += ')';
   1117 				}
   1118 			}
   1119 
   1120 			code += ";\n";
   1121 		}
   1122 
   1123 		code += '\t';
   1124 		// Structs cannot be output variables, so have to write to a temporary first and then output each member separately
   1125 		if (func.return_type.is_struct())
   1126 		{
   1127 			write_type(code, func.return_type);
   1128 			code += " _return = ";
   1129 		}
   1130 		// All other output types can write to the output variable directly
   1131 		else if (!func.return_type.is_void())
   1132 		{
   1133 			code += semantic_to_builtin("_return", func.return_semantic, stype);
   1134 			code += " = ";
   1135 		}
   1136 
   1137 		// Call the function this entry point refers to
   1138 		code += id_to_name(func.definition) + '(';
   1139 
   1140 		for (size_t i = 0; i < num_params; ++i)
   1141 		{
   1142 			code += "_param" + std::to_string(i);
   1143 
   1144 			if (i < num_params - 1)
   1145 				code += ", ";
   1146 		}
   1147 
   1148 		code += ");\n";
   1149 
   1150 		// Handle output parameters
   1151 		for (size_t i = 0; i < num_params; ++i)
   1152 		{
   1153 			const type &param_type = func.parameter_list[i].type;
   1154 			if (!param_type.has(type::q_out))
   1155 				continue;
   1156 
   1157 			if (param_type.is_struct())
   1158 			{
   1159 				const struct_info &definition = get_struct(param_type.definition);
   1160 
   1161 				// Split out struct fields into separate output variables again
   1162 				for (int a = 0, array_length = std::max(1, param_type.array_length); a < array_length; a++)
   1163 				{
   1164 					for (const struct_member_info &member : definition.member_list)
   1165 					{
   1166 						if (member.type.is_array())
   1167 						{
   1168 							for (int b = 0; b < member.type.array_length; b++)
   1169 							{
   1170 								code += '\t';
   1171 								code += escape_name("_out_param" + std::to_string(i) + '_' + std::to_string(a) + '_' + member.name + '_' + std::to_string(b));
   1172 								code += " = ";
   1173 
   1174 								// OpenGL does not allow varying of type boolean, so need to cast here
   1175 								if (member.type.is_boolean())
   1176 								{
   1177 									type varying_type = member.type;
   1178 									varying_type.base = type::t_float;
   1179 									write_type<false, false>(code, varying_type);
   1180 									code += '(';
   1181 								}
   1182 
   1183 								code += escape_name("_param" + std::to_string(i));
   1184 								if (param_type.is_array())
   1185 									code += '[' + std::to_string(a) + ']';
   1186 								code += '.';
   1187 								code += member.name;
   1188 								code += '[' + std::to_string(b) + ']';
   1189 
   1190 								if (member.type.is_boolean())
   1191 									code += ')';
   1192 
   1193 								code += ";\n";
   1194 							}
   1195 						}
   1196 						else
   1197 						{
   1198 							code += '\t';
   1199 							code += semantic_to_builtin("_out_param" + std::to_string(i) + '_' + std::to_string(a) + '_' + member.name, member.semantic, stype);
   1200 							code += " = ";
   1201 
   1202 							if (member.type.is_boolean())
   1203 							{
   1204 								type varying_type = member.type;
   1205 								varying_type.base = type::t_float;
   1206 								write_type<false, false>(code, varying_type);
   1207 								code += '(';
   1208 							}
   1209 
   1210 							code += escape_name("_param" + std::to_string(i));
   1211 							if (param_type.is_array())
   1212 								code += '[' + std::to_string(a) + ']';
   1213 							code += '.';
   1214 							code += member.name;
   1215 
   1216 							if (member.type.is_boolean())
   1217 								code += ')';
   1218 
   1219 							code += ";\n";
   1220 						}
   1221 					}
   1222 				}
   1223 			}
   1224 			else
   1225 			{
   1226 				if (param_type.is_array())
   1227 				{
   1228 					// Split up array output into individual array elements again
   1229 					for (int a = 0; a < param_type.array_length; a++)
   1230 					{
   1231 						code += '\t';
   1232 						code += escape_name("_out_param" + std::to_string(i) + '_' + std::to_string(a));
   1233 						code += " = ";
   1234 
   1235 						// OpenGL does not allow varying of type boolean, so need to cast here
   1236 						if (param_type.is_boolean())
   1237 						{
   1238 							type varying_type = param_type;
   1239 							varying_type.base = type::t_float;
   1240 							write_type<false, false>(code, varying_type);
   1241 							code += '(';
   1242 						}
   1243 
   1244 						code += escape_name("_param" + std::to_string(i));
   1245 						code += '[' + std::to_string(a) + ']';
   1246 
   1247 						if (param_type.is_boolean())
   1248 							code += ')';
   1249 
   1250 						code += ";\n";
   1251 					}
   1252 				}
   1253 				else
   1254 				{
   1255 					code += '\t';
   1256 					code += semantic_to_builtin("_out_param" + std::to_string(i), func.parameter_list[i].semantic, stype);
   1257 					code += " = ";
   1258 
   1259 					if (param_type.is_boolean())
   1260 					{
   1261 						type varying_type = param_type;
   1262 						varying_type.base = type::t_float;
   1263 						write_type<false, false>(code, varying_type);
   1264 						code += '(';
   1265 					}
   1266 
   1267 					code += escape_name("_param" + std::to_string(i));
   1268 
   1269 					if (param_type.is_boolean())
   1270 						code += ')';
   1271 
   1272 					code += ";\n";
   1273 				}
   1274 			}
   1275 		}
   1276 
   1277 		// Handle return struct output variables
   1278 		if (func.return_type.is_struct())
   1279 		{
   1280 			const struct_info &definition = get_struct(func.return_type.definition);
   1281 
   1282 			for (const struct_member_info &member : definition.member_list)
   1283 			{
   1284 				code += '\t';
   1285 				code += semantic_to_builtin("_return_" + member.name, member.semantic, stype);
   1286 				code += " = _return." + escape_name(member.name) + ";\n";
   1287 			}
   1288 		}
   1289 
   1290 		// Add code to flip the output vertically
   1291 		if (_flip_vert_y && stype == shader_type::vs)
   1292 			code += "\tgl_Position.y = -gl_Position.y;\n";
   1293 
   1294 		leave_block_and_return(0);
   1295 		leave_function();
   1296 
   1297 		_blocks.at(0) += "#endif\n";
   1298 	}
   1299 
   1300 	id   emit_load(const expression &exp, bool force_new_id) override
   1301 	{
   1302 		if (exp.is_constant)
   1303 			return emit_constant(exp.type, exp.constant);
   1304 		else if (exp.chain.empty() && !force_new_id) // Can refer to values without access chain directly
   1305 			return exp.base;
   1306 
   1307 		const id res = make_id();
   1308 
   1309 		std::string type, expr_code = id_to_name(exp.base);
   1310 
   1311 		for (const auto &op : exp.chain)
   1312 		{
   1313 			switch (op.op)
   1314 			{
   1315 			case expression::operation::op_cast:
   1316 				type.clear();
   1317 				write_type<false, false>(type, op.to);
   1318 				expr_code = type + '(' + expr_code + ')';
   1319 				break;
   1320 			case expression::operation::op_member:
   1321 				expr_code += '.';
   1322 				expr_code += escape_name(get_struct(op.from.definition).member_list[op.index].name);
   1323 				break;
   1324 			case expression::operation::op_dynamic_index:
   1325 				// For matrices this will extract a column, but that is fine, since they are initialized column-wise too
   1326 				// Also cast to an integer, since it could be a boolean too, but GLSL does not allow those in index expressions
   1327 				expr_code += "[int(" + id_to_name(op.index) + ")]";
   1328 				break;
   1329 			case expression::operation::op_constant_index:
   1330 				if (op.from.is_vector() && !op.from.is_array())
   1331 					expr_code += '.',
   1332 					expr_code += "xyzw"[op.index];
   1333 				else
   1334 					expr_code += '[' + std::to_string(op.index) + ']';
   1335 				break;
   1336 			case expression::operation::op_swizzle:
   1337 				if (op.from.is_matrix())
   1338 				{
   1339 					if (op.swizzle[1] < 0)
   1340 					{
   1341 						const int row = (op.swizzle[0] % 4);
   1342 						const int col = (op.swizzle[0] - row) / 4;
   1343 
   1344 						expr_code += '[' + std::to_string(row) + "][" + std::to_string(col) + ']';
   1345 					}
   1346 					else
   1347 					{
   1348 						// TODO: Implement matrix to vector swizzles
   1349 						assert(false);
   1350 						expr_code += "_NOT_IMPLEMENTED_"; // Make sure compilation fails
   1351 					}
   1352 				}
   1353 				else
   1354 				{
   1355 					// can't swizzle scalars
   1356 					if (_gles && op.from.is_scalar())
   1357 					{
   1358 						// => e.g. vec3(expr, expr, expr).xyz
   1359 						type.clear();
   1360 						write_type<false, false>(type, op.to);
   1361 						std::string new_code = type;
   1362 						new_code += '(';
   1363 
   1364 						const unsigned int components = op.to.components();
   1365 						for (unsigned int i = 0; i < components; ++i)
   1366 						{
   1367 								if (i > 0)
   1368 									new_code += ',';
   1369 								new_code += '(' + expr_code + ')';
   1370 						}
   1371 						new_code += ')';
   1372 						expr_code = std::move(new_code);
   1373 					}
   1374 					else
   1375 					{
   1376 						expr_code += '.';
   1377 						for (unsigned int i = 0; i < 4 && op.swizzle[i] >= 0; ++i)
   1378 							expr_code += "xyzw"[op.swizzle[i]];
   1379 					}
   1380 				}
   1381 				break;
   1382 			}
   1383 		}
   1384 
   1385 		// GLSL matrices are always floating point, so need to cast result to the target type
   1386 		if (!exp.chain.empty() && exp.chain[0].from.is_matrix() && !exp.chain[0].from.is_floating_point())
   1387 		{
   1388 			type.clear();
   1389 			write_type<false, false>(type, exp.type);
   1390 			expr_code = type + '(' + expr_code + ')';
   1391 		}
   1392 
   1393 		if (force_new_id)
   1394 		{
   1395 			// Need to store value in a new variable to comply with request for a new ID
   1396 			std::string &code = _blocks.at(_current_block);
   1397 
   1398 			code += '\t';
   1399 			write_type(code, exp.type);
   1400 			code += ' ' + id_to_name(res) + " = " + expr_code + ";\n";
   1401 		}
   1402 		else
   1403 		{
   1404 			// Avoid excessive variable definitions by instancing simple load operations in code every time
   1405 			define_name<naming::expression>(res, std::move(expr_code));
   1406 		}
   1407 
   1408 		return res;
   1409 	}
   1410 	void emit_store(const expression &exp, id value) override
   1411 	{
   1412 		if (const auto it = _remapped_sampler_variables.find(exp.base);
   1413 			it != _remapped_sampler_variables.end())
   1414 		{
   1415 			assert(it->second == 0);
   1416 			it->second = value;
   1417 			return;
   1418 		}
   1419 
   1420 		std::string &code = _blocks.at(_current_block);
   1421 
   1422 		write_location(code, exp.location);
   1423 
   1424 		code += '\t' + id_to_name(exp.base);
   1425 
   1426 		for (const auto &op : exp.chain)
   1427 		{
   1428 			switch (op.op)
   1429 			{
   1430 			case expression::operation::op_member:
   1431 				code += '.';
   1432 				code += escape_name(get_struct(op.from.definition).member_list[op.index].name);
   1433 				break;
   1434 			case expression::operation::op_dynamic_index:
   1435 				code += "[int(" + id_to_name(op.index) + ")]";
   1436 				break;
   1437 			case expression::operation::op_constant_index:
   1438 				code += '[' + std::to_string(op.index) + ']';
   1439 				break;
   1440 			case expression::operation::op_swizzle:
   1441 				if (op.from.is_matrix())
   1442 				{
   1443 					if (op.swizzle[1] < 0)
   1444 					{
   1445 						const int row = (op.swizzle[0] % 4);
   1446 						const int col = (op.swizzle[0] - row) / 4;
   1447 
   1448 						code += '[' + std::to_string(row) + "][" + std::to_string(col) + ']';
   1449 					}
   1450 					else
   1451 					{
   1452 						// TODO: Implement matrix to vector swizzles
   1453 						assert(false);
   1454 						code += "_NOT_IMPLEMENTED_"; // Make sure compilation fails
   1455 					}
   1456 				}
   1457 				else
   1458 				{
   1459 					code += '.';
   1460 					for (unsigned int i = 0; i < 4 && op.swizzle[i] >= 0; ++i)
   1461 						code += "xyzw"[op.swizzle[i]];
   1462 				}
   1463 				break;
   1464 			}
   1465 		}
   1466 
   1467 		code += " = ";
   1468 
   1469 		// GLSL matrices are always floating point, so need to cast type
   1470 		if (!exp.chain.empty() && exp.chain[0].from.is_matrix() && !exp.chain[0].from.is_floating_point())
   1471 			// Only supporting scalar assignments to matrices currently, so can assume to always cast to float
   1472 			code += "float(" + id_to_name(value) + ");\n";
   1473 		else
   1474 			code += id_to_name(value) + ";\n";
   1475 	}
   1476 
   1477 	id   emit_constant(const type &type, const constant &data) override
   1478 	{
   1479 		const id res = make_id();
   1480 
   1481 		if (type.is_array() || type.is_struct())
   1482 		{
   1483 			assert(type.has(type::q_const));
   1484 
   1485 			std::string &code = _blocks.at(_current_block);
   1486 
   1487 			code += '\t';
   1488 
   1489 			// GLSL requires constants to be initialized, but struct initialization is not supported right now
   1490 			if (!type.is_struct())
   1491 				code += "const ";
   1492 
   1493 			write_type(code, type);
   1494 			code += ' ' + id_to_name(res);
   1495 
   1496 			// Array constants need to be stored in a constant variable as they cannot be used in-place
   1497 			if (type.is_array())
   1498 				code += '[' + std::to_string(type.array_length) + ']';
   1499 
   1500 			// Struct initialization is not supported right now
   1501 			if (!type.is_struct()) {
   1502 				code += " = ";
   1503 				write_constant(code, type, data);
   1504 			}
   1505 
   1506 			code += ";\n";
   1507 			return res;
   1508 		}
   1509 
   1510 		std::string code;
   1511 		write_constant(code, type, data);
   1512 		define_name<naming::expression>(res, std::move(code));
   1513 
   1514 		return res;
   1515 	}
   1516 
   1517 	id   emit_unary_op(const location &loc, tokenid op, const type &res_type, id val) override
   1518 	{
   1519 		const id res = make_id();
   1520 
   1521 		std::string &code = _blocks.at(_current_block);
   1522 
   1523 		write_location(code, loc);
   1524 
   1525 		code += '\t';
   1526 		write_type(code, res_type);
   1527 		code += ' ' + id_to_name(res) + " = ";
   1528 
   1529 		switch (op)
   1530 		{
   1531 		case tokenid::minus:
   1532 			code += '-';
   1533 			break;
   1534 		case tokenid::tilde:
   1535 			code += '~';
   1536 			break;
   1537 		case tokenid::exclaim:
   1538 			if (res_type.is_vector())
   1539 				code += "not";
   1540 			else
   1541 				code += "!bool";
   1542 			break;
   1543 		default:
   1544 			assert(false);
   1545 		}
   1546 
   1547 		code += '(' + id_to_name(val) + ");\n";
   1548 
   1549 		return res;
   1550 	}
   1551 	id   emit_binary_op(const location &loc, tokenid op, const type &res_type, const type &type, id lhs, id rhs) override
   1552 	{
   1553 		const id res = make_id();
   1554 
   1555 		std::string &code = _blocks.at(_current_block);
   1556 
   1557 		write_location(code, loc);
   1558 
   1559 		code += '\t';
   1560 		write_type(code, res_type);
   1561 		code += ' ' + id_to_name(res) + " = ";
   1562 
   1563 		std::string intrinsic, operator_code;
   1564 
   1565 		switch (op)
   1566 		{
   1567 		case tokenid::plus:
   1568 		case tokenid::plus_plus:
   1569 		case tokenid::plus_equal:
   1570 			operator_code = '+';
   1571 			break;
   1572 		case tokenid::minus:
   1573 		case tokenid::minus_minus:
   1574 		case tokenid::minus_equal:
   1575 			operator_code = '-';
   1576 			break;
   1577 		case tokenid::star:
   1578 		case tokenid::star_equal:
   1579 			if (type.is_matrix())
   1580 				intrinsic = "matrixCompMult";
   1581 			else
   1582 				operator_code = '*';
   1583 			break;
   1584 		case tokenid::slash:
   1585 		case tokenid::slash_equal:
   1586 			operator_code = '/';
   1587 			break;
   1588 		case tokenid::percent:
   1589 		case tokenid::percent_equal:
   1590 			if (type.is_floating_point())
   1591 				intrinsic = "fmodHLSL",
   1592 				_uses_fmod = true;
   1593 			else
   1594 				operator_code = '%';
   1595 			break;
   1596 		case tokenid::caret:
   1597 		case tokenid::caret_equal:
   1598 			operator_code = '^';
   1599 			break;
   1600 		case tokenid::pipe:
   1601 		case tokenid::pipe_equal:
   1602 			operator_code = '|';
   1603 			break;
   1604 		case tokenid::ampersand:
   1605 		case tokenid::ampersand_equal:
   1606 			operator_code = '&';
   1607 			break;
   1608 		case tokenid::less_less:
   1609 		case tokenid::less_less_equal:
   1610 			operator_code = "<<";
   1611 			break;
   1612 		case tokenid::greater_greater:
   1613 		case tokenid::greater_greater_equal:
   1614 			operator_code = ">>";
   1615 			break;
   1616 		case tokenid::pipe_pipe:
   1617 			if (type.is_vector())
   1618 				intrinsic = "compOr",
   1619 				_uses_componentwise_or = true;
   1620 			else
   1621 				operator_code = "||";
   1622 			break;
   1623 		case tokenid::ampersand_ampersand:
   1624 			if (type.is_vector())
   1625 				intrinsic = "compAnd",
   1626 				_uses_componentwise_and = true;
   1627 			else
   1628 				operator_code = "&&";
   1629 			break;
   1630 		case tokenid::less:
   1631 			if (type.is_vector())
   1632 				intrinsic = "lessThan";
   1633 			else
   1634 				operator_code = '<';
   1635 			break;
   1636 		case tokenid::less_equal:
   1637 			if (type.is_vector())
   1638 				intrinsic = "lessThanEqual";
   1639 			else
   1640 				operator_code = "<=";
   1641 			break;
   1642 		case tokenid::greater:
   1643 			if (type.is_vector())
   1644 				intrinsic = "greaterThan";
   1645 			else
   1646 				operator_code = '>';
   1647 			break;
   1648 		case tokenid::greater_equal:
   1649 			if (type.is_vector())
   1650 				intrinsic = "greaterThanEqual";
   1651 			else
   1652 				operator_code = ">=";
   1653 			break;
   1654 		case tokenid::equal_equal:
   1655 			if (type.is_vector())
   1656 				intrinsic = "equal";
   1657 			else
   1658 				operator_code = "==";
   1659 			break;
   1660 		case tokenid::exclaim_equal:
   1661 			if (type.is_vector())
   1662 				intrinsic = "notEqual";
   1663 			else
   1664 				operator_code = "!=";
   1665 			break;
   1666 		default:
   1667 			assert(false);
   1668 		}
   1669 
   1670 		if (!intrinsic.empty())
   1671 			code += intrinsic + '(' + id_to_name(lhs) + ", " + id_to_name(rhs) + ')';
   1672 		else
   1673 			code += id_to_name(lhs) + ' ' + operator_code + ' ' + id_to_name(rhs);
   1674 
   1675 		code += ";\n";
   1676 
   1677 		return res;
   1678 	}
   1679 	id   emit_ternary_op(const location &loc, tokenid op, const type &res_type, id condition, id true_value, id false_value) override
   1680 	{
   1681 		if (op != tokenid::question)
   1682 			return assert(false), 0; // Should never happen, since this is the only ternary operator currently supported
   1683 
   1684 		const id res = make_id();
   1685 
   1686 		std::string &code = _blocks.at(_current_block);
   1687 
   1688 		write_location(code, loc);
   1689 
   1690 		code += '\t';
   1691 		write_type(code, res_type);
   1692 		code += ' ' + id_to_name(res);
   1693 
   1694 		if (res_type.is_array())
   1695 			code += '[' + std::to_string(res_type.array_length) + ']';
   1696 
   1697 		code += " = ";
   1698 
   1699 		if (res_type.is_vector())
   1700 			code += "compCond(" + id_to_name(condition) + ", " + id_to_name(true_value) + ", " + id_to_name(false_value) + ");\n",
   1701 			_uses_componentwise_cond = true;
   1702 		else // GLSL requires the conditional expression to be a scalar boolean
   1703 			code += id_to_name(condition) + " ? " + id_to_name(true_value) + " : " + id_to_name(false_value) + ";\n";
   1704 
   1705 		return res;
   1706 	}
   1707 	id   emit_call(const location &loc, id function, const type &res_type, const std::vector<expression> &args) override
   1708 	{
   1709 #ifndef NDEBUG
   1710 		for (const expression &arg : args)
   1711 			assert(arg.chain.empty() && arg.base != 0);
   1712 #endif
   1713 
   1714 		const id res = make_id();
   1715 
   1716 		std::string &code = _blocks.at(_current_block);
   1717 
   1718 		write_location(code, loc);
   1719 
   1720 		code += '\t';
   1721 
   1722 		if (!res_type.is_void())
   1723 		{
   1724 			write_type(code, res_type);
   1725 			code += ' ' + id_to_name(res);
   1726 
   1727 			if (res_type.is_array())
   1728 				code += '[' + std::to_string(res_type.array_length) + ']';
   1729 
   1730 			code += " = ";
   1731 		}
   1732 
   1733 		code += id_to_name(function) + '(';
   1734 
   1735 		for (size_t i = 0, num_args = args.size(); i < num_args; ++i)
   1736 		{
   1737 			code += id_to_name(args[i].base);
   1738 
   1739 			if (i < num_args - 1)
   1740 				code += ", ";
   1741 		}
   1742 
   1743 		code += ");\n";
   1744 
   1745 		return res;
   1746 	}
   1747 	id   emit_call_intrinsic(const location &loc, id intrinsic, const type &res_type, const std::vector<expression> &args) override
   1748 	{
   1749 #ifndef NDEBUG
   1750 		for (const expression &arg : args)
   1751 			assert(arg.chain.empty() && arg.base != 0);
   1752 #endif
   1753 
   1754 		const id res = make_id();
   1755 
   1756 		std::string &code = _blocks.at(_current_block);
   1757 
   1758 		write_location(code, loc);
   1759 
   1760 		code += '\t';
   1761 
   1762 		if (!res_type.is_void())
   1763 		{
   1764 			write_type(code, res_type);
   1765 			code += ' ' + id_to_name(res) + " = ";
   1766 		}
   1767 
   1768 		enum
   1769 		{
   1770 		#define IMPLEMENT_INTRINSIC_GLSL(name, i, code) name##i,
   1771 			#include "effect_symbol_table_intrinsics.inl"
   1772 		};
   1773 
   1774 		switch (intrinsic)
   1775 		{
   1776 		#define IMPLEMENT_INTRINSIC_GLSL(name, i, code) case name##i: code break;
   1777 			#include "effect_symbol_table_intrinsics.inl"
   1778 		default:
   1779 			assert(false);
   1780 		}
   1781 
   1782 		code += ";\n";
   1783 
   1784 		return res;
   1785 	}
   1786 	id   emit_construct(const location &loc, const type &type, const std::vector<expression> &args) override
   1787 	{
   1788 #ifndef NDEBUG
   1789 		for (const auto &arg : args)
   1790 			assert((arg.type.is_scalar() || type.is_array()) && arg.chain.empty() && arg.base != 0);
   1791 #endif
   1792 
   1793 		const id res = make_id();
   1794 
   1795 		std::string &code = _blocks.at(_current_block);
   1796 
   1797 		write_location(code, loc);
   1798 
   1799 		code += '\t';
   1800 		write_type(code, type);
   1801 		code += ' ' + id_to_name(res);
   1802 
   1803 		if (type.is_array())
   1804 			code += '[' + std::to_string(type.array_length) + ']';
   1805 
   1806 		code += " = ";
   1807 
   1808 		write_type<false, false>(code, type);
   1809 
   1810 		if (type.is_array())
   1811 			code += '[' + std::to_string(type.array_length) + ']';
   1812 
   1813 		code += '(';
   1814 
   1815 		for (size_t i = 0, num_args = args.size(); i < num_args; ++i)
   1816 		{
   1817 			code += id_to_name(args[i].base);
   1818 
   1819 			if (i < num_args - 1)
   1820 				code += ", ";
   1821 		}
   1822 
   1823 		code += ");\n";
   1824 
   1825 		return res;
   1826 	}
   1827 
   1828 	void emit_if(const location &loc, id condition_value, id condition_block, id true_statement_block, id false_statement_block, unsigned int flags) override
   1829 	{
   1830 		assert(condition_value != 0 && condition_block != 0 && true_statement_block != 0 && false_statement_block != 0);
   1831 
   1832 		std::string &code = _blocks.at(_current_block);
   1833 
   1834 		std::string &true_statement_data = _blocks.at(true_statement_block);
   1835 		std::string &false_statement_data = _blocks.at(false_statement_block);
   1836 
   1837 		increase_indentation_level(true_statement_data);
   1838 		increase_indentation_level(false_statement_data);
   1839 
   1840 		code += _blocks.at(condition_block);
   1841 
   1842 		write_location(code, loc);
   1843 
   1844 		if (flags != 0 && !_gles)
   1845 		{
   1846 			_enable_control_flow_attributes = true;
   1847 
   1848 			code += "#if GL_EXT_control_flow_attributes\n\t[[";
   1849 			if ((flags & 0x1) == 0x1)
   1850 				code += "flatten";
   1851 			if ((flags & 0x3) == 0x3)
   1852 				code += ", ";
   1853 			if ((flags & 0x2) == 0x2)
   1854 				code += "dont_flatten";
   1855 			code += "]]\n#endif\n";
   1856 		}
   1857 
   1858 		code += '\t';
   1859 		code += "if (" + id_to_name(condition_value) + ")\n\t{\n";
   1860 		code += true_statement_data;
   1861 		code += "\t}\n";
   1862 
   1863 		if (!false_statement_data.empty())
   1864 		{
   1865 			code += "\telse\n\t{\n";
   1866 			code += false_statement_data;
   1867 			code += "\t}\n";
   1868 		}
   1869 
   1870 		// Remove consumed blocks to save memory
   1871 		_blocks.erase(condition_block);
   1872 		_blocks.erase(true_statement_block);
   1873 		_blocks.erase(false_statement_block);
   1874 	}
   1875 	id   emit_phi(const location &loc, id condition_value, id condition_block, id true_value, id true_statement_block, id false_value, id false_statement_block, const type &type) override
   1876 	{
   1877 		assert(condition_value != 0 && condition_block != 0 && true_value != 0 && true_statement_block != 0 && false_value != 0 && false_statement_block != 0);
   1878 
   1879 		std::string &code = _blocks.at(_current_block);
   1880 
   1881 		std::string &true_statement_data = _blocks.at(true_statement_block);
   1882 		std::string &false_statement_data = _blocks.at(false_statement_block);
   1883 
   1884 		increase_indentation_level(true_statement_data);
   1885 		increase_indentation_level(false_statement_data);
   1886 
   1887 		const id res = make_id();
   1888 
   1889 		code += _blocks.at(condition_block);
   1890 
   1891 		code += '\t';
   1892 		write_type(code, type);
   1893 		code += ' ' + id_to_name(res) + ";\n";
   1894 
   1895 		write_location(code, loc);
   1896 
   1897 		code += "\tif (" + id_to_name(condition_value) + ")\n\t{\n";
   1898 		code += (true_statement_block != condition_block ? true_statement_data : std::string());
   1899 		code += "\t\t" + id_to_name(res) + " = " + id_to_name(true_value) + ";\n";
   1900 		code += "\t}\n\telse\n\t{\n";
   1901 		code += (false_statement_block != condition_block ? false_statement_data : std::string());
   1902 		code += "\t\t" + id_to_name(res) + " = " + id_to_name(false_value) + ";\n";
   1903 		code += "\t}\n";
   1904 
   1905 		// Remove consumed blocks to save memory
   1906 		_blocks.erase(condition_block);
   1907 		_blocks.erase(true_statement_block);
   1908 		_blocks.erase(false_statement_block);
   1909 
   1910 		return res;
   1911 	}
   1912 	void emit_loop(const location &loc, id condition_value, id prev_block, id header_block, id condition_block, id loop_block, id continue_block, unsigned int flags) override
   1913 	{
   1914 		assert(prev_block != 0 && header_block != 0 && loop_block != 0 && continue_block != 0);
   1915 
   1916 		std::string &code = _blocks.at(_current_block);
   1917 
   1918 		std::string &loop_data = _blocks.at(loop_block);
   1919 		std::string &continue_data = _blocks.at(continue_block);
   1920 
   1921 		increase_indentation_level(loop_data);
   1922 		increase_indentation_level(loop_data);
   1923 		increase_indentation_level(continue_data);
   1924 
   1925 		code += _blocks.at(prev_block);
   1926 
   1927 		std::string attributes;
   1928 		if (flags != 0 && !_gles)
   1929 		{
   1930 			_enable_control_flow_attributes = true;
   1931 
   1932 			attributes += "#if GL_EXT_control_flow_attributes\n\t[[";
   1933 			if ((flags & 0x1) == 0x1)
   1934 				attributes += "unroll";
   1935 			if ((flags & 0x3) == 0x3)
   1936 				attributes += ", ";
   1937 			if ((flags & 0x2) == 0x2)
   1938 				attributes += "dont_unroll";
   1939 			attributes += "]]\n#endif\n";
   1940 		}
   1941 
   1942 		// Condition value can be missing in infinite loop constructs like "for (;;)"
   1943 		std::string condition_name = condition_value != 0 ? id_to_name(condition_value) : "true";
   1944 
   1945 		if (condition_block == 0)
   1946 		{
   1947 			// Convert the last SSA variable initializer to an assignment statement
   1948 			auto pos_assign = continue_data.rfind(condition_name);
   1949 			auto pos_prev_assign = continue_data.rfind('\t', pos_assign);
   1950 			continue_data.erase(pos_prev_assign + 1, pos_assign - pos_prev_assign - 1);
   1951 
   1952 			// We need to add the continue block to all "continue" statements as well
   1953 			const std::string continue_id = "__CONTINUE__" + std::to_string(continue_block);
   1954 			for (size_t offset = 0; (offset = loop_data.find(continue_id, offset)) != std::string::npos; offset += continue_data.size())
   1955 				loop_data.replace(offset, continue_id.size(), continue_data);
   1956 
   1957 			code += "\tbool " + condition_name + ";\n";
   1958 
   1959 			write_location(code, loc);
   1960 
   1961 			code += attributes;
   1962 			code += '\t';
   1963 			code += "do\n\t{\n\t\t{\n";
   1964 			code += loop_data; // Encapsulate loop body into another scope, so not to confuse any local variables with the current iteration variable accessed in the continue block below
   1965 			code += "\t\t}\n";
   1966 			code += continue_data;
   1967 			code += "\t}\n\twhile (" + condition_name + ");\n";
   1968 		}
   1969 		else
   1970 		{
   1971 			std::string &condition_data = _blocks.at(condition_block);
   1972 
   1973 			// If the condition data is just a single line, then it is a simple expression, which we can just put into the loop condition as-is
   1974 			if (std::count(condition_data.begin(), condition_data.end(), '\n') == 1)
   1975 			{
   1976 				// Convert SSA variable initializer back to a condition expression
   1977 				auto pos_assign = condition_data.find('=');
   1978 				condition_data.erase(0, pos_assign + 2);
   1979 				auto pos_semicolon = condition_data.rfind(';');
   1980 				condition_data.erase(pos_semicolon);
   1981 
   1982 				condition_name = std::move(condition_data);
   1983 				assert(condition_data.empty());
   1984 			}
   1985 			else
   1986 			{
   1987 				code += condition_data;
   1988 
   1989 				increase_indentation_level(condition_data);
   1990 
   1991 				// Convert the last SSA variable initializer to an assignment statement
   1992 				auto pos_assign = condition_data.rfind(condition_name);
   1993 				auto pos_prev_assign = condition_data.rfind('\t', pos_assign);
   1994 				condition_data.erase(pos_prev_assign + 1, pos_assign - pos_prev_assign - 1);
   1995 			}
   1996 
   1997 			const std::string continue_id = "__CONTINUE__" + std::to_string(continue_block);
   1998 			for (size_t offset = 0; (offset = loop_data.find(continue_id, offset)) != std::string::npos; offset += continue_data.size())
   1999 				loop_data.replace(offset, continue_id.size(), continue_data + condition_data);
   2000 
   2001 			code += attributes;
   2002 			code += '\t';
   2003 			code += "while (" + condition_name + ")\n\t{\n\t\t{\n";
   2004 			code += loop_data;
   2005 			code += "\t\t}\n";
   2006 			code += continue_data;
   2007 			code += condition_data;
   2008 			code += "\t}\n";
   2009 
   2010 			_blocks.erase(condition_block);
   2011 		}
   2012 
   2013 		// Remove consumed blocks to save memory
   2014 		_blocks.erase(prev_block);
   2015 		_blocks.erase(header_block);
   2016 		_blocks.erase(loop_block);
   2017 		_blocks.erase(continue_block);
   2018 	}
   2019 	void emit_switch(const location &loc, id selector_value, id selector_block, id default_label, id default_block, const std::vector<id> &case_literal_and_labels, const std::vector<id> &case_blocks, unsigned int) override
   2020 	{
   2021 		assert(selector_value != 0 && selector_block != 0 && default_label != 0 && default_block != 0);
   2022 		assert(case_blocks.size() == case_literal_and_labels.size() / 2);
   2023 
   2024 		std::string &code = _blocks.at(_current_block);
   2025 
   2026 		code += _blocks.at(selector_block);
   2027 
   2028 		write_location(code, loc);
   2029 
   2030 		code += "\tswitch (" + id_to_name(selector_value) + ")\n\t{\n";
   2031 
   2032 		std::vector<id> labels = case_literal_and_labels;
   2033 		for (size_t i = 0; i < labels.size(); i += 2)
   2034 		{
   2035 			if (labels[i + 1] == 0)
   2036 				continue; // Happens if a case was already handled, see below
   2037 
   2038 			code += "\tcase " + std::to_string(labels[i]) + ": ";
   2039 
   2040 			if (labels[i + 1] == default_label)
   2041 			{
   2042 				code += "default: ";
   2043 				default_label = 0;
   2044 			}
   2045 			else
   2046 			{
   2047 				for (size_t k = i + 2; k < labels.size(); k += 2)
   2048 				{
   2049 					if (labels[k + 1] == 0 || labels[k + 1] != labels[i + 1])
   2050 						continue;
   2051 
   2052 					code += "case " + std::to_string(labels[k]) + ": ";
   2053 					labels[k + 1] = 0;
   2054 				}
   2055 			}
   2056 
   2057 			assert(case_blocks[i / 2] != 0);
   2058 			std::string &case_data = _blocks.at(case_blocks[i / 2]);
   2059 
   2060 			increase_indentation_level(case_data);
   2061 
   2062 			code += "{\n";
   2063 			code += case_data;
   2064 			code += "\t}\n";
   2065 		}
   2066 
   2067 
   2068 		if (default_label != 0 && default_block != _current_block)
   2069 		{
   2070 			std::string &default_data = _blocks.at(default_block);
   2071 
   2072 			increase_indentation_level(default_data);
   2073 
   2074 			code += "\tdefault: {\n";
   2075 			code += default_data;
   2076 			code += "\t}\n";
   2077 
   2078 			_blocks.erase(default_block);
   2079 		}
   2080 
   2081 		code += "\t}\n";
   2082 
   2083 		// Remove consumed blocks to save memory
   2084 		_blocks.erase(selector_block);
   2085 		for (const id case_block : case_blocks)
   2086 			_blocks.erase(case_block);
   2087 	}
   2088 
   2089 	id   create_block() override
   2090 	{
   2091 		const id res = make_id();
   2092 
   2093 		std::string &block = _blocks.emplace(res, std::string()).first->second;
   2094 		// Reserve a decently big enough memory block to avoid frequent reallocations
   2095 		block.reserve(4096);
   2096 
   2097 		return res;
   2098 	}
   2099 	id   set_block(id id) override
   2100 	{
   2101 		_last_block = _current_block;
   2102 		_current_block = id;
   2103 
   2104 		return _last_block;
   2105 	}
   2106 	void enter_block(id id) override
   2107 	{
   2108 		_current_block = id;
   2109 	}
   2110 	id   leave_block_and_kill() override
   2111 	{
   2112 		if (!is_in_block())
   2113 			return 0;
   2114 
   2115 		std::string &code = _blocks.at(_current_block);
   2116 
   2117 		code += "\tdiscard;\n";
   2118 
   2119 		const auto &return_type = _functions.back()->return_type;
   2120 		if (!return_type.is_void())
   2121 		{
   2122 			// Add a return statement to exit functions in case discard is the last control flow statement
   2123 			code += "\treturn ";
   2124 			write_constant(code, return_type, constant());
   2125 			code += ";\n";
   2126 		}
   2127 
   2128 		return set_block(0);
   2129 	}
   2130 	id   leave_block_and_return(id value) override
   2131 	{
   2132 		if (!is_in_block())
   2133 			return 0;
   2134 
   2135 		// Skip implicit return statement
   2136 		if (!_functions.back()->return_type.is_void() && value == 0)
   2137 			return set_block(0);
   2138 
   2139 		std::string &code = _blocks.at(_current_block);
   2140 
   2141 		code += "\treturn";
   2142 
   2143 		if (value != 0)
   2144 			code += ' ' + id_to_name(value);
   2145 
   2146 		code += ";\n";
   2147 
   2148 		return set_block(0);
   2149 	}
   2150 	id   leave_block_and_switch(id, id) override
   2151 	{
   2152 		if (!is_in_block())
   2153 			return _last_block;
   2154 
   2155 		return set_block(0);
   2156 	}
   2157 	id   leave_block_and_branch(id target, unsigned int loop_flow) override
   2158 	{
   2159 		if (!is_in_block())
   2160 			return _last_block;
   2161 
   2162 		std::string &code = _blocks.at(_current_block);
   2163 
   2164 		switch (loop_flow)
   2165 		{
   2166 		case 1:
   2167 			code += "\tbreak;\n";
   2168 			break;
   2169 		case 2: // Keep track of continue target block, so we can insert its code here later
   2170 			code += "__CONTINUE__" + std::to_string(target) + "\tcontinue;\n";
   2171 			break;
   2172 		}
   2173 
   2174 		return set_block(0);
   2175 	}
   2176 	id   leave_block_and_branch_conditional(id, id, id) override
   2177 	{
   2178 		if (!is_in_block())
   2179 			return _last_block;
   2180 
   2181 		return set_block(0);
   2182 	}
   2183 	void leave_function() override
   2184 	{
   2185 		assert(_last_block != 0);
   2186 
   2187 		_blocks.at(0) += "{\n" + _blocks.at(_last_block) + "}\n";
   2188 	}
   2189 };
   2190 } // namespace
   2191 
   2192 codegen *reshadefx::create_codegen_glsl(bool gles, bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types, bool flip_vert_y)
   2193 {
   2194 	return new codegen_glsl(gles, vulkan_semantics, debug_info, uniforms_to_spec_constants, enable_16bit_types, flip_vert_y);
   2195 }