| 79 | std::vector<std::tuple<type, constant, id>> _constant_lookup; |
| 80 | |
| 81 | std::string finalize_preamble() const |
| 82 | { |
| 83 | std::string preamble = "#version 430\n"; |
| 84 | |
| 85 | if (_enable_16bit_types) |
| 86 | // GL_NV_gpu_shader5, GL_AMD_gpu_shader_half_float or GL_EXT_shader_16bit_storage |
| 87 | preamble += "#extension GL_NV_gpu_shader5 : require\n"; |
| 88 | if (_uses_control_flow_attributes) |
| 89 | preamble += "#extension GL_EXT_control_flow_attributes : enable\n"; |
| 90 | if (_uses_derivative_control) |
| 91 | // Core only starting in GLSL version 4.5 |
| 92 | preamble += "#extension GL_ARB_derivative_control : enable\n"; |
| 93 | |
| 94 | if (_uses_fmod) |
| 95 | preamble += "float fmodHLSL(float x, float y) { return x - y * trunc(x / y); }\n" |
| 96 | "vec2 fmodHLSL(vec2 x, vec2 y) { return x - y * trunc(x / y); }\n" |
| 97 | "vec3 fmodHLSL(vec3 x, vec3 y) { return x - y * trunc(x / y); }\n" |
| 98 | "vec4 fmodHLSL(vec4 x, vec4 y) { return x - y * trunc(x / y); }\n" |
| 99 | "mat2 fmodHLSL(mat2 x, mat2 y) { return x - matrixCompMult(y, mat2(trunc(x[0] / y[0]), trunc(x[1] / y[1]))); }\n" |
| 100 | "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" |
| 101 | "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"; |
| 102 | if (_uses_componentwise_or) |
| 103 | preamble += |
| 104 | "bvec2 compOr(bvec2 a, bvec2 b) { return bvec2(a.x || b.x, a.y || b.y); }\n" |
| 105 | "bvec3 compOr(bvec3 a, bvec3 b) { return bvec3(a.x || b.x, a.y || b.y, a.z || b.z); }\n" |
| 106 | "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"; |
| 107 | if (_uses_componentwise_and) |
| 108 | preamble += |
| 109 | "bvec2 compAnd(bvec2 a, bvec2 b) { return bvec2(a.x && b.x, a.y && b.y); }\n" |
| 110 | "bvec3 compAnd(bvec3 a, bvec3 b) { return bvec3(a.x && b.x, a.y && b.y, a.z && b.z); }\n" |
| 111 | "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"; |
| 112 | if (_uses_componentwise_cond) |
| 113 | preamble += |
| 114 | "vec2 compCond(bvec2 cond, vec2 a, vec2 b) { return vec2(cond.x ? a.x : b.x, cond.y ? a.y : b.y); }\n" |
| 115 | "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" |
| 116 | "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" |
| 117 | "bvec2 compCond(bvec2 cond, bvec2 a, bvec2 b) { return bvec2(cond.x ? a.x : b.x, cond.y ? a.y : b.y); }\n" |
| 118 | "bvec3 compCond(bvec3 cond, bvec3 a, bvec3 b) { return bvec3(cond.x ? a.x : b.x, cond.y ? a.y : b.y, cond.z ? a.z : b.z); }\n" |
| 119 | "bvec4 compCond(bvec4 cond, bvec4 a, bvec4 b) { return bvec4(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" |
| 120 | "ivec2 compCond(bvec2 cond, ivec2 a, ivec2 b) { return ivec2(cond.x ? a.x : b.x, cond.y ? a.y : b.y); }\n" |
| 121 | "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" |
| 122 | "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" |
| 123 | "uvec2 compCond(bvec2 cond, uvec2 a, uvec2 b) { return uvec2(cond.x ? a.x : b.x, cond.y ? a.y : b.y); }\n" |
| 124 | "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" |
| 125 | "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"; |
| 126 | |
| 127 | if (_uniforms_to_spec_constants) |
| 128 | { |
| 129 | // Apply any specialization constant values set between code generation and assembling |
| 130 | for (const uniform &spec_constant : _module.spec_constants) |
| 131 | { |
| 132 | // Check if this is a split specialization constant and move data accordingly |
| 133 | constant initializer_value = spec_constant.initializer_value; |
| 134 | if (spec_constant.type.is_scalar() && spec_constant.offset != 0) |
| 135 | initializer_value.as_uint[0] = initializer_value.as_uint[spec_constant.offset]; |
| 136 | |
| 137 | preamble += "#define SPEC_CONSTANT_" + spec_constant.unique_name + ' '; |
| 138 |
nothing calls this directly
no test coverage detected