X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fbuiltin_variables.cpp;h=c10ea9e61a5003d0131ed8421f5fb100a70e92ba;hb=9950523368026f900fe901eb5921fd2283e5280c;hp=f31f9f61ef6126077e78e7ef02e70b67e7518661;hpb=6a049687841d87fc5bbd0fb0a192f03776f67630;p=mesa.git diff --git a/src/compiler/glsl/builtin_variables.cpp b/src/compiler/glsl/builtin_variables.cpp index f31f9f61ef6..c10ea9e61a5 100644 --- a/src/compiler/glsl/builtin_variables.cpp +++ b/src/compiler/glsl/builtin_variables.cpp @@ -21,15 +21,31 @@ * DEALINGS IN THE SOFTWARE. */ + +/** + * Building this file with MinGW g++ 7.3 or 7.4 with: + * scons platform=windows toolchain=crossmingw machine=x86 build=profile + * triggers an internal compiler error. + * Overriding the optimization level to -O1 works around the issue. + * MinGW 5.3.1 does not seem to have the bug, neither does 8.3. So for now + * we're simply testing for version 7.x here. + */ +#if defined(__MINGW32__) && __GNUC__ == 7 +#warning "disabling optimizations for this file to work around compiler bug in MinGW gcc 7.x" +#pragma GCC optimize("O1") +#endif + + #include "ir.h" #include "ir_builder.h" #include "linker.h" #include "glsl_parser_extras.h" #include "glsl_symbol_table.h" -#include "main/core.h" +#include "main/mtypes.h" #include "main/uniforms.h" #include "program/prog_statevars.h" #include "program/prog_instruction.h" +#include "builtin_functions.h" using namespace ir_builder; @@ -84,9 +100,9 @@ static const struct gl_builtin_uniform_element gl_LightSource_elements[] = { SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z)}, - {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW}, - {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX}, {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW}, + {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX}, + {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW}, {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX}, {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY}, {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ}, @@ -298,11 +314,12 @@ class per_vertex_accumulator { public: per_vertex_accumulator(); - void add_field(int slot, const glsl_type *type, const char *name); + void add_field(int slot, const glsl_type *type, int precision, + const char *name); const glsl_type *construct_interface_instance() const; private: - glsl_struct_field fields[10]; + glsl_struct_field fields[11]; unsigned num_fields; }; @@ -316,7 +333,7 @@ per_vertex_accumulator::per_vertex_accumulator() void per_vertex_accumulator::add_field(int slot, const glsl_type *type, - const char *name) + int precision, const char *name) { assert(this->num_fields < ARRAY_SIZE(this->fields)); this->fields[this->num_fields].type = type; @@ -324,16 +341,17 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type, this->fields[this->num_fields].matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; this->fields[this->num_fields].location = slot; this->fields[this->num_fields].offset = -1; - this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE; + this->fields[this->num_fields].interpolation = INTERP_MODE_NONE; this->fields[this->num_fields].centroid = 0; this->fields[this->num_fields].sample = 0; this->fields[this->num_fields].patch = 0; - this->fields[this->num_fields].precision = GLSL_PRECISION_NONE; - this->fields[this->num_fields].image_read_only = 0; - this->fields[this->num_fields].image_write_only = 0; - this->fields[this->num_fields].image_coherent = 0; - this->fields[this->num_fields].image_volatile = 0; - this->fields[this->num_fields].image_restrict = 0; + this->fields[this->num_fields].precision = precision; + this->fields[this->num_fields].memory_read_only = 0; + this->fields[this->num_fields].memory_write_only = 0; + this->fields[this->num_fields].memory_coherent = 0; + this->fields[this->num_fields].memory_volatile = 0; + this->fields[this->num_fields].memory_restrict = 0; + this->fields[this->num_fields].image_format = 0; this->fields[this->num_fields].explicit_xfb_buffer = 0; this->fields[this->num_fields].xfb_buffer = -1; this->fields[this->num_fields].xfb_stride = -1; @@ -346,6 +364,7 @@ per_vertex_accumulator::construct_interface_instance() const { return glsl_type::get_interface_instance(this->fields, this->num_fields, GLSL_INTERFACE_PACKING_STD140, + false, "gl_PerVertex"); } @@ -357,6 +376,7 @@ public: struct _mesa_glsl_parse_state *state); void generate_constants(); void generate_uniforms(); + void generate_special_vars(); void generate_vs_special_vars(); void generate_tcs_special_vars(); void generate_tes_special_vars(); @@ -376,35 +396,70 @@ private: return symtab->get_type(name); } + ir_variable *add_input(int slot, const glsl_type *type, int precision, + const char *name) + { + return add_variable(name, type, precision, ir_var_shader_in, slot); + } + ir_variable *add_input(int slot, const glsl_type *type, const char *name) { - return add_variable(name, type, ir_var_shader_in, slot); + return add_input(slot, type, GLSL_PRECISION_NONE, name); + } + + ir_variable *add_output(int slot, const glsl_type *type, int precision, + const char *name) + { + return add_variable(name, type, precision, ir_var_shader_out, slot); } ir_variable *add_output(int slot, const glsl_type *type, const char *name) { - return add_variable(name, type, ir_var_shader_out, slot); + return add_output(slot, type, GLSL_PRECISION_NONE, name); } - ir_variable *add_index_output(int slot, int index, const glsl_type *type, const char *name) + ir_variable *add_index_output(int slot, int index, const glsl_type *type, + int precision, const char *name) { - return add_index_variable(name, type, ir_var_shader_out, slot, index); + return add_index_variable(name, type, precision, ir_var_shader_out, slot, + index); } + ir_variable *add_system_value(int slot, const glsl_type *type, int precision, + const char *name) + { + return add_variable(name, type, precision, ir_var_system_value, slot); + } ir_variable *add_system_value(int slot, const glsl_type *type, const char *name) { - return add_variable(name, type, ir_var_system_value, slot); + return add_system_value(slot, type, GLSL_PRECISION_NONE, name); } ir_variable *add_variable(const char *name, const glsl_type *type, - enum ir_variable_mode mode, int slot); + int precision, enum ir_variable_mode mode, + int slot); ir_variable *add_index_variable(const char *name, const glsl_type *type, - enum ir_variable_mode mode, int slot, int index); - ir_variable *add_uniform(const glsl_type *type, const char *name); - ir_variable *add_const(const char *name, int value); + int precision, enum ir_variable_mode mode, + int slot, int index); + ir_variable *add_uniform(const glsl_type *type, int precision, + const char *name); + ir_variable *add_uniform(const glsl_type *type, const char *name) + { + return add_uniform(type, GLSL_PRECISION_NONE, name); + } + ir_variable *add_const(const char *name, int precision, int value); + ir_variable *add_const(const char *name, int value) + { + return add_const(name, GLSL_PRECISION_MEDIUM, value); + } ir_variable *add_const_ivec3(const char *name, int x, int y, int z); - void add_varying(int slot, const glsl_type *type, const char *name); + void add_varying(int slot, const glsl_type *type, int precision, + const char *name); + void add_varying(int slot, const glsl_type *type, const char *name) + { + add_varying(slot, type, GLSL_PRECISION_NONE, name); + } exec_list * const instructions; struct _mesa_glsl_parse_state * const state; @@ -420,6 +475,7 @@ private: const glsl_type * const bool_t; const glsl_type * const int_t; const glsl_type * const uint_t; + const glsl_type * const uint64_t; const glsl_type * const float_t; const glsl_type * const vec2_t; const glsl_type * const vec3_t; @@ -436,9 +492,10 @@ private: builtin_variable_generator::builtin_variable_generator( exec_list *instructions, struct _mesa_glsl_parse_state *state) : instructions(instructions), state(state), symtab(state->symbols), - compatibility(!state->is_version(140, 100)), + compatibility(state->compat_shader || state->ARB_compatibility_enable), bool_t(glsl_type::bool_type), int_t(glsl_type::int_type), uint_t(glsl_type::uint_type), + uint64_t(glsl_type::uint64_t_type), float_t(glsl_type::float_type), vec2_t(glsl_type::vec2_type), vec3_t(glsl_type::vec3_type), vec4_t(glsl_type::vec4_type), uvec3_t(glsl_type::uvec3_type), @@ -448,8 +505,10 @@ builtin_variable_generator::builtin_variable_generator( ir_variable * builtin_variable_generator::add_index_variable(const char *name, - const glsl_type *type, - enum ir_variable_mode mode, int slot, int index) + const glsl_type *type, + int precision, + enum ir_variable_mode mode, + int slot, int index) { ir_variable *var = new(symtab) ir_variable(type, name, mode); var->data.how_declared = ir_var_declared_implicitly; @@ -478,6 +537,9 @@ builtin_variable_generator::add_index_variable(const char *name, var->data.explicit_index = 1; var->data.index = index; + if (state->es_shader) + var->data.precision = precision; + /* Once the variable is created an initialized, add it to the symbol table * and add the declaration to the IR stream. */ @@ -490,6 +552,7 @@ builtin_variable_generator::add_index_variable(const char *name, ir_variable * builtin_variable_generator::add_variable(const char *name, const glsl_type *type, + int precision, enum ir_variable_mode mode, int slot) { ir_variable *var = new(symtab) ir_variable(type, name, mode); @@ -518,6 +581,9 @@ builtin_variable_generator::add_variable(const char *name, var->data.explicit_location = (slot >= 0); var->data.explicit_index = 0; + if (state->es_shader) + var->data.precision = precision; + /* Once the variable is created an initialized, add it to the symbol table * and add the declaration to the IR stream. */ @@ -527,23 +593,28 @@ builtin_variable_generator::add_variable(const char *name, return var; } +extern "C" const struct gl_builtin_uniform_desc * +_mesa_glsl_get_builtin_uniform_desc(const char *name) +{ + for (unsigned i = 0; _mesa_builtin_uniform_desc[i].name != NULL; i++) { + if (strcmp(_mesa_builtin_uniform_desc[i].name, name) == 0) { + return &_mesa_builtin_uniform_desc[i]; + } + } + return NULL; +} ir_variable * builtin_variable_generator::add_uniform(const glsl_type *type, + int precision, const char *name) { - ir_variable *const uni = add_variable(name, type, ir_var_uniform, -1); - - unsigned i; - for (i = 0; _mesa_builtin_uniform_desc[i].name != NULL; i++) { - if (strcmp(_mesa_builtin_uniform_desc[i].name, name) == 0) { - break; - } - } + ir_variable *const uni = + add_variable(name, type, precision, ir_var_uniform, -1); - assert(_mesa_builtin_uniform_desc[i].name != NULL); const struct gl_builtin_uniform_desc* const statevar = - &_mesa_builtin_uniform_desc[i]; + _mesa_glsl_get_builtin_uniform_desc(name); + assert(statevar != NULL); const unsigned array_count = type->is_array() ? type->length : 1; @@ -575,10 +646,11 @@ builtin_variable_generator::add_uniform(const glsl_type *type, ir_variable * -builtin_variable_generator::add_const(const char *name, int value) +builtin_variable_generator::add_const(const char *name, int precision, + int value) { ir_variable *const var = add_variable(name, glsl_type::int_type, - ir_var_auto, -1); + precision, ir_var_auto, -1); var->constant_value = new(var) ir_constant(value); var->constant_initializer = new(var) ir_constant(value); var->data.has_initializer = true; @@ -591,6 +663,7 @@ builtin_variable_generator::add_const_ivec3(const char *name, int x, int y, int z) { ir_variable *const var = add_variable(name, glsl_type::ivec3_type, + GLSL_PRECISION_HIGH, ir_var_auto, -1); ir_constant_data data; memset(&data, 0, sizeof(data)); @@ -617,9 +690,17 @@ builtin_variable_generator::generate_constants() add_const("gl_MaxDrawBuffers", state->Const.MaxDrawBuffers); /* Max uniforms/varyings: GLSL ES counts these in units of vectors; desktop - * GL counts them in units of "components" or "floats". + * GL counts them in units of "components" or "floats" and also in units + * of vectors since GL 4.1 */ - if (state->es_shader) { + if (!state->es_shader) { + add_const("gl_MaxFragmentUniformComponents", + state->Const.MaxFragmentUniformComponents); + add_const("gl_MaxVertexUniformComponents", + state->Const.MaxVertexUniformComponents); + } + + if (state->is_version(410, 100)) { add_const("gl_MaxVertexUniformVectors", state->Const.MaxVertexUniformComponents / 4); add_const("gl_MaxFragmentUniformVectors", @@ -646,16 +727,10 @@ builtin_variable_generator::generate_constants() state->Const.MaxDualSourceDrawBuffers); } } else { - add_const("gl_MaxVertexUniformComponents", - state->Const.MaxVertexUniformComponents); - /* Note: gl_MaxVaryingFloats was deprecated in GLSL 1.30+, but not * removed */ add_const("gl_MaxVaryingFloats", state->ctx->Const.MaxVarying * 4); - - add_const("gl_MaxFragmentUniformComponents", - state->Const.MaxFragmentUniformComponents); } /* Texel offsets were introduced in ARB_shading_language_420pack (which @@ -671,10 +746,17 @@ builtin_variable_generator::generate_constants() state->Const.MaxProgramTexelOffset); } - if (state->is_version(130, 0)) { + if (state->has_clip_distance()) { add_const("gl_MaxClipDistances", state->Const.MaxClipPlanes); + } + if (state->is_version(130, 0)) { add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4); } + if (state->has_cull_distance()) { + add_const("gl_MaxCullDistances", state->Const.MaxClipPlanes); + add_const("gl_MaxCombinedClipAndCullDistances", + state->Const.MaxClipPlanes); + } if (state->has_geometry_shader()) { add_const("gl_MaxVertexOutputComponents", @@ -743,7 +825,7 @@ builtin_variable_generator::generate_constants() add_const("gl_MaxGeometryAtomicCounters", state->Const.MaxGeometryAtomicCounters); } - if (!state->es_shader) { + if (state->is_version(110, 320)) { add_const("gl_MaxTessControlAtomicCounters", state->Const.MaxTessControlAtomicCounters); add_const("gl_MaxTessEvaluationAtomicCounters", @@ -765,7 +847,7 @@ builtin_variable_generator::generate_constants() add_const("gl_MaxGeometryAtomicCounterBuffers", state->Const.MaxGeometryAtomicCounterBuffers); } - if (!state->es_shader) { + if (state->is_version(110, 320)) { add_const("gl_MaxTessControlAtomicCounterBuffers", state->Const.MaxTessControlAtomicCounterBuffers); add_const("gl_MaxTessEvaluationAtomicCounterBuffers", @@ -822,8 +904,7 @@ builtin_variable_generator::generate_constants() state->Const.MaxTransformFeedbackInterleavedComponents); } - if (state->is_version(420, 310) || - state->ARB_shader_image_load_store_enable) { + if (state->has_shader_image_load_store()) { add_const("gl_MaxImageUnits", state->Const.MaxImageUnits); add_const("gl_MaxVertexImageUniforms", @@ -845,8 +926,7 @@ builtin_variable_generator::generate_constants() state->Const.MaxImageSamples); } - if (state->is_version(400, 0) || - state->ARB_tessellation_shader_enable) { + if (state->has_tessellation_shader()) { add_const("gl_MaxTessControlImageUniforms", state->Const.MaxTessControlImageUniforms); add_const("gl_MaxTessEvaluationImageUniforms", @@ -854,18 +934,20 @@ builtin_variable_generator::generate_constants() } } - if (state->is_version(450, 310) || + if (state->is_version(440, 310) || state->ARB_ES3_1_compatibility_enable) { add_const("gl_MaxCombinedShaderOutputResources", state->Const.MaxCombinedShaderOutputResources); } if (state->is_version(410, 0) || - state->ARB_viewport_array_enable) - add_const("gl_MaxViewports", state->Const.MaxViewports); + state->ARB_viewport_array_enable || + state->OES_viewport_array_enable) { + add_const("gl_MaxViewports", GLSL_PRECISION_HIGH, + state->Const.MaxViewports); + } - if (state->is_version(400, 0) || - state->ARB_tessellation_shader_enable) { + if (state->has_tessellation_shader()) { add_const("gl_MaxPatchVertices", state->Const.MaxPatchVertices); add_const("gl_MaxTessGenLevel", state->Const.MaxTessGenLevel); add_const("gl_MaxTessControlInputComponents", state->Const.MaxTessControlInputComponents); @@ -896,7 +978,7 @@ builtin_variable_generator::generate_uniforms() if (state->is_version(400, 320) || state->ARB_sample_shading_enable || state->OES_sample_variables_enable) - add_uniform(int_t, "gl_NumSamples"); + add_uniform(int_t, GLSL_PRECISION_LOW, "gl_NumSamples"); add_uniform(type("gl_DepthRangeParameters"), "gl_DepthRange"); add_uniform(array(vec4_t, VERT_ATTRIB_MAX), "gl_CurrentAttribVertMESA"); add_uniform(array(vec4_t, VARYING_SLOT_MAX), "gl_CurrentAttribFragMESA"); @@ -967,6 +1049,24 @@ builtin_variable_generator::generate_uniforms() } +/** + * Generate special variables which exist in all shaders. + */ +void +builtin_variable_generator::generate_special_vars() +{ + if (state->ARB_shader_ballot_enable) { + add_system_value(SYSTEM_VALUE_SUBGROUP_SIZE, uint_t, "gl_SubGroupSizeARB"); + add_system_value(SYSTEM_VALUE_SUBGROUP_INVOCATION, uint_t, "gl_SubGroupInvocationARB"); + add_system_value(SYSTEM_VALUE_SUBGROUP_EQ_MASK, uint64_t, "gl_SubGroupEqMaskARB"); + add_system_value(SYSTEM_VALUE_SUBGROUP_GE_MASK, uint64_t, "gl_SubGroupGeMaskARB"); + add_system_value(SYSTEM_VALUE_SUBGROUP_GT_MASK, uint64_t, "gl_SubGroupGtMaskARB"); + add_system_value(SYSTEM_VALUE_SUBGROUP_LE_MASK, uint64_t, "gl_SubGroupLeMaskARB"); + add_system_value(SYSTEM_VALUE_SUBGROUP_LT_MASK, uint64_t, "gl_SubGroupLtMaskARB"); + } +} + + /** * Generate variables which only exist in vertex shaders. */ @@ -975,24 +1075,36 @@ builtin_variable_generator::generate_vs_special_vars() { ir_variable *var; - if (state->is_version(130, 300)) - add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, "gl_VertexID"); + if (state->is_version(130, 300) || state->EXT_gpu_shader4_enable) { + add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, GLSL_PRECISION_HIGH, + "gl_VertexID"); + } + if (state->is_version(460, 0)) { + add_system_value(SYSTEM_VALUE_BASE_VERTEX, int_t, "gl_BaseVertex"); + add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstance"); + add_system_value(SYSTEM_VALUE_DRAW_ID, int_t, "gl_DrawID"); + } if (state->ARB_draw_instanced_enable) add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, "gl_InstanceIDARB"); - if (state->ARB_draw_instanced_enable || state->is_version(140, 300)) - add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, "gl_InstanceID"); + if (state->ARB_draw_instanced_enable || state->is_version(140, 300) || + state->EXT_gpu_shader4_enable) { + add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_InstanceID"); + } if (state->ARB_shader_draw_parameters_enable) { add_system_value(SYSTEM_VALUE_BASE_VERTEX, int_t, "gl_BaseVertexARB"); add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstanceARB"); add_system_value(SYSTEM_VALUE_DRAW_ID, int_t, "gl_DrawIDARB"); } - if (state->AMD_vertex_shader_layer_enable) { + if (state->AMD_vertex_shader_layer_enable || + state->ARB_shader_viewport_layer_array_enable) { var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; + var->data.interpolation = INTERP_MODE_FLAT; } - if (state->AMD_vertex_shader_viewport_index_enable) { + if (state->AMD_vertex_shader_viewport_index_enable || + state->ARB_shader_viewport_layer_array_enable) { var = add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; + var->data.interpolation = INTERP_MODE_FLAT; } if (compatibility) { add_input(VERT_ATTRIB_POS, vec4_t, "gl_Vertex"); @@ -1018,14 +1130,31 @@ builtin_variable_generator::generate_vs_special_vars() void builtin_variable_generator::generate_tcs_special_vars() { - add_system_value(SYSTEM_VALUE_PRIMITIVE_ID, int_t, "gl_PrimitiveID"); - add_system_value(SYSTEM_VALUE_VERTICES_IN, int_t, "gl_PatchVerticesIn"); - add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, "gl_InvocationID"); + add_system_value(SYSTEM_VALUE_PRIMITIVE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_PrimitiveID"); + add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, GLSL_PRECISION_HIGH, + "gl_InvocationID"); + add_system_value(SYSTEM_VALUE_VERTICES_IN, int_t, GLSL_PRECISION_HIGH, + "gl_PatchVerticesIn"); add_output(VARYING_SLOT_TESS_LEVEL_OUTER, array(float_t, 4), - "gl_TessLevelOuter")->data.patch = 1; + GLSL_PRECISION_HIGH, "gl_TessLevelOuter")->data.patch = 1; add_output(VARYING_SLOT_TESS_LEVEL_INNER, array(float_t, 2), - "gl_TessLevelInner")->data.patch = 1; + GLSL_PRECISION_HIGH, "gl_TessLevelInner")->data.patch = 1; + /* XXX What to do if multiple are flipped on? */ + int bbox_slot = state->ctx->Const.NoPrimitiveBoundingBoxOutput ? -1 : + VARYING_SLOT_BOUNDING_BOX0; + if (state->EXT_primitive_bounding_box_enable) + add_output(bbox_slot, array(vec4_t, 2), "gl_BoundingBoxEXT") + ->data.patch = 1; + if (state->OES_primitive_bounding_box_enable) { + add_output(bbox_slot, array(vec4_t, 2), GLSL_PRECISION_HIGH, + "gl_BoundingBoxOES")->data.patch = 1; + } + if (state->is_version(0, 320) || state->ARB_ES3_2_compatibility_enable) { + add_output(bbox_slot, array(vec4_t, 2), GLSL_PRECISION_HIGH, + "gl_BoundingBox")->data.patch = 1; + } } @@ -1035,13 +1164,31 @@ builtin_variable_generator::generate_tcs_special_vars() void builtin_variable_generator::generate_tes_special_vars() { - add_system_value(SYSTEM_VALUE_PRIMITIVE_ID, int_t, "gl_PrimitiveID"); - add_system_value(SYSTEM_VALUE_VERTICES_IN, int_t, "gl_PatchVerticesIn"); - add_system_value(SYSTEM_VALUE_TESS_COORD, vec3_t, "gl_TessCoord"); - add_system_value(SYSTEM_VALUE_TESS_LEVEL_OUTER, array(float_t, 4), - "gl_TessLevelOuter"); - add_system_value(SYSTEM_VALUE_TESS_LEVEL_INNER, array(float_t, 2), - "gl_TessLevelInner"); + ir_variable *var; + + add_system_value(SYSTEM_VALUE_PRIMITIVE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_PrimitiveID"); + add_system_value(SYSTEM_VALUE_VERTICES_IN, int_t, GLSL_PRECISION_HIGH, + "gl_PatchVerticesIn"); + add_system_value(SYSTEM_VALUE_TESS_COORD, vec3_t, GLSL_PRECISION_HIGH, + "gl_TessCoord"); + if (this->state->ctx->Const.GLSLTessLevelsAsInputs) { + add_input(VARYING_SLOT_TESS_LEVEL_OUTER, array(float_t, 4), + GLSL_PRECISION_HIGH, "gl_TessLevelOuter")->data.patch = 1; + add_input(VARYING_SLOT_TESS_LEVEL_INNER, array(float_t, 2), + GLSL_PRECISION_HIGH, "gl_TessLevelInner")->data.patch = 1; + } else { + add_system_value(SYSTEM_VALUE_TESS_LEVEL_OUTER, array(float_t, 4), + GLSL_PRECISION_HIGH, "gl_TessLevelOuter"); + add_system_value(SYSTEM_VALUE_TESS_LEVEL_INNER, array(float_t, 2), + GLSL_PRECISION_HIGH, "gl_TessLevelInner"); + } + if (state->ARB_shader_viewport_layer_array_enable) { + var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); + var->data.interpolation = INTERP_MODE_FLAT; + var = add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); + var->data.interpolation = INTERP_MODE_FLAT; + } } @@ -1053,14 +1200,19 @@ builtin_variable_generator::generate_gs_special_vars() { ir_variable *var; - var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; - if (state->is_version(410, 0) || state->ARB_viewport_array_enable) { - var = add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; + var = add_output(VARYING_SLOT_LAYER, int_t, GLSL_PRECISION_HIGH, "gl_Layer"); + var->data.interpolation = INTERP_MODE_FLAT; + if (state->is_version(410, 0) || state->ARB_viewport_array_enable || + state->OES_viewport_array_enable) { + var = add_output(VARYING_SLOT_VIEWPORT, int_t, GLSL_PRECISION_HIGH, + "gl_ViewportIndex"); + var->data.interpolation = INTERP_MODE_FLAT; + } + if (state->is_version(400, 320) || state->ARB_gpu_shader5_enable || + state->OES_geometry_shader_enable || state->EXT_geometry_shader_enable) { + add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, GLSL_PRECISION_HIGH, + "gl_InvocationID"); } - if (state->is_version(400, 0) || state->ARB_gpu_shader5_enable) - add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, "gl_InvocationID"); /* Although gl_PrimitiveID appears in tessellation control and tessellation * evaluation shaders, it has a different function there than it has in @@ -1072,10 +1224,12 @@ builtin_variable_generator::generate_gs_special_vars() * the specific case of gl_PrimitiveIDIn. So we don't need to treat * gl_PrimitiveIDIn as an {ARB,EXT}_geometry_shader4-only variable. */ - var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveIDIn"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; - var = add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; + var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_PrimitiveIDIn"); + var->data.interpolation = INTERP_MODE_FLAT; + var = add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_PrimitiveID"); + var->data.interpolation = INTERP_MODE_FLAT; } @@ -1087,22 +1241,35 @@ builtin_variable_generator::generate_fs_special_vars() { ir_variable *var; - if (this->state->ctx->Const.GLSLFragCoordIsSysVal) - add_system_value(SYSTEM_VALUE_FRAG_COORD, vec4_t, "gl_FragCoord"); - else - add_input(VARYING_SLOT_POS, vec4_t, "gl_FragCoord"); + int frag_coord_precision = (state->is_version(0, 300) ? + GLSL_PRECISION_HIGH : + GLSL_PRECISION_MEDIUM); + + if (this->state->ctx->Const.GLSLFragCoordIsSysVal) { + add_system_value(SYSTEM_VALUE_FRAG_COORD, vec4_t, frag_coord_precision, + "gl_FragCoord"); + } else { + add_input(VARYING_SLOT_POS, vec4_t, frag_coord_precision, "gl_FragCoord"); + } if (this->state->ctx->Const.GLSLFrontFacingIsSysVal) add_system_value(SYSTEM_VALUE_FRONT_FACE, bool_t, "gl_FrontFacing"); else add_input(VARYING_SLOT_FACE, bool_t, "gl_FrontFacing"); - if (state->is_version(120, 100)) - add_input(VARYING_SLOT_PNTC, vec2_t, "gl_PointCoord"); + if (state->is_version(120, 100)) { + if (this->state->ctx->Const.GLSLPointCoordIsSysVal) + add_system_value(SYSTEM_VALUE_POINT_COORD, vec2_t, + GLSL_PRECISION_MEDIUM, "gl_PointCoord"); + else + add_input(VARYING_SLOT_PNTC, vec2_t, GLSL_PRECISION_MEDIUM, + "gl_PointCoord"); + } - if (state->has_geometry_shader()) { - var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; + if (state->has_geometry_shader() || state->EXT_gpu_shader4_enable) { + var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_PrimitiveID"); + var->data.interpolation = INTERP_MODE_FLAT; } /* gl_FragColor and gl_FragData were deprecated starting in desktop GLSL @@ -1110,29 +1277,43 @@ builtin_variable_generator::generate_fs_special_vars() * They were removed from GLSL ES 3.00. */ if (compatibility || !state->is_version(420, 300)) { - add_output(FRAG_RESULT_COLOR, vec4_t, "gl_FragColor"); + add_output(FRAG_RESULT_COLOR, vec4_t, GLSL_PRECISION_MEDIUM, + "gl_FragColor"); add_output(FRAG_RESULT_DATA0, - array(vec4_t, state->Const.MaxDrawBuffers), "gl_FragData"); + array(vec4_t, state->Const.MaxDrawBuffers), + GLSL_PRECISION_MEDIUM, + "gl_FragData"); + } + + if (state->has_framebuffer_fetch() && !state->is_version(130, 300)) { + ir_variable *const var = + add_output(FRAG_RESULT_DATA0, + array(vec4_t, state->Const.MaxDrawBuffers), + "gl_LastFragData"); + var->data.precision = GLSL_PRECISION_MEDIUM; + var->data.read_only = 1; + var->data.fb_fetch_output = 1; + var->data.memory_coherent = 1; } if (state->es_shader && state->language_version == 100 && state->EXT_blend_func_extended_enable) { - /* We make an assumption here that there will only ever be one dual-source draw buffer - * In case this assumption is ever proven to be false, make sure to assert here - * since we don't handle this case. - * In practice, this issue will never arise since no hardware will support it. - */ - assert(state->Const.MaxDualSourceDrawBuffers <= 1); - add_index_output(FRAG_RESULT_DATA0, 1, vec4_t, "gl_SecondaryFragColorEXT"); + add_index_output(FRAG_RESULT_COLOR, 1, vec4_t, + GLSL_PRECISION_MEDIUM, "gl_SecondaryFragColorEXT"); add_index_output(FRAG_RESULT_DATA0, 1, array(vec4_t, state->Const.MaxDualSourceDrawBuffers), - "gl_SecondaryFragDataEXT"); + GLSL_PRECISION_MEDIUM, "gl_SecondaryFragDataEXT"); } /* gl_FragDepth has always been in desktop GLSL, but did not appear in GLSL * ES 1.00. */ - if (state->is_version(110, 300)) - add_output(FRAG_RESULT_DEPTH, float_t, "gl_FragDepth"); + if (state->is_version(110, 300)) { + add_output(FRAG_RESULT_DEPTH, float_t, GLSL_PRECISION_HIGH, + "gl_FragDepth"); + } + + if (state->EXT_frag_depth_enable) + add_output(FRAG_RESULT_DEPTH, float_t, "gl_FragDepthEXT"); if (state->ARB_shader_stencil_export_enable) { ir_variable *const var = @@ -1151,8 +1332,10 @@ builtin_variable_generator::generate_fs_special_vars() if (state->is_version(400, 320) || state->ARB_sample_shading_enable || state->OES_sample_variables_enable) { - add_system_value(SYSTEM_VALUE_SAMPLE_ID, int_t, "gl_SampleID"); - add_system_value(SYSTEM_VALUE_SAMPLE_POS, vec2_t, "gl_SamplePosition"); + add_system_value(SYSTEM_VALUE_SAMPLE_ID, int_t, GLSL_PRECISION_LOW, + "gl_SampleID"); + add_system_value(SYSTEM_VALUE_SAMPLE_POS, vec2_t, GLSL_PRECISION_MEDIUM, + "gl_SamplePosition"); /* From the ARB_sample_shading specification: * "The number of elements in the array is ceil(/32), where * is the maximum number of color samples supported by the @@ -1160,20 +1343,31 @@ builtin_variable_generator::generate_fs_special_vars() * Since no drivers expose more than 32x MSAA, we can simply set * the array size to 1 rather than computing it. */ - add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), "gl_SampleMask"); + add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), + GLSL_PRECISION_HIGH, "gl_SampleMask"); } if (state->is_version(400, 320) || state->ARB_gpu_shader5_enable || state->OES_sample_variables_enable) { - add_system_value(SYSTEM_VALUE_SAMPLE_MASK_IN, array(int_t, 1), "gl_SampleMaskIn"); + add_system_value(SYSTEM_VALUE_SAMPLE_MASK_IN, array(int_t, 1), + GLSL_PRECISION_HIGH, "gl_SampleMaskIn"); } - if (state->is_version(430, 0) || state->ARB_fragment_layer_viewport_enable) { - var = add_input(VARYING_SLOT_LAYER, int_t, "gl_Layer"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; + if (state->is_version(430, 320) || + state->ARB_fragment_layer_viewport_enable || + state->OES_geometry_shader_enable || + state->EXT_geometry_shader_enable) { + var = add_input(VARYING_SLOT_LAYER, int_t, GLSL_PRECISION_HIGH, + "gl_Layer"); + var->data.interpolation = INTERP_MODE_FLAT; + } + + if (state->is_version(430, 0) || + state->ARB_fragment_layer_viewport_enable || + state->OES_viewport_array_enable) { var = add_input(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); - var->data.interpolation = INTERP_QUALIFIER_FLAT; + var->data.interpolation = INTERP_MODE_FLAT; } if (state->is_version(450, 310) || state->ARB_ES3_1_compatibility_enable) @@ -1191,8 +1385,16 @@ builtin_variable_generator::generate_cs_special_vars() "gl_LocalInvocationID"); add_system_value(SYSTEM_VALUE_WORK_GROUP_ID, uvec3_t, "gl_WorkGroupID"); add_system_value(SYSTEM_VALUE_NUM_WORK_GROUPS, uvec3_t, "gl_NumWorkGroups"); - add_variable("gl_GlobalInvocationID", uvec3_t, ir_var_auto, 0); - add_variable("gl_LocalInvocationIndex", uint_t, ir_var_auto, 0); + + if (state->ARB_compute_variable_group_size_enable) { + add_system_value(SYSTEM_VALUE_LOCAL_GROUP_SIZE, + uvec3_t, "gl_LocalGroupSizeARB"); + } + + add_system_value(SYSTEM_VALUE_GLOBAL_INVOCATION_ID, + uvec3_t, "gl_GlobalInvocationID"); + add_system_value(SYSTEM_VALUE_LOCAL_INVOCATION_INDEX, + uint_t, "gl_LocalInvocationIndex"); } @@ -1203,23 +1405,25 @@ builtin_variable_generator::generate_cs_special_vars() */ void builtin_variable_generator::add_varying(int slot, const glsl_type *type, - const char *name) + int precision, const char *name) { switch (state->stage) { case MESA_SHADER_TESS_CTRL: case MESA_SHADER_TESS_EVAL: case MESA_SHADER_GEOMETRY: - this->per_vertex_in.add_field(slot, type, name); + this->per_vertex_in.add_field(slot, type, precision, name); /* FALLTHROUGH */ case MESA_SHADER_VERTEX: - this->per_vertex_out.add_field(slot, type, name); + this->per_vertex_out.add_field(slot, type, precision, name); break; case MESA_SHADER_FRAGMENT: - add_input(slot, type, name); + add_input(slot, type, precision, name); break; case MESA_SHADER_COMPUTE: /* Compute shaders don't have varyings. */ break; + default: + break; } } @@ -1233,18 +1437,32 @@ builtin_variable_generator::generate_varyings() { /* gl_Position and gl_PointSize are not visible from fragment shaders. */ if (state->stage != MESA_SHADER_FRAGMENT) { - add_varying(VARYING_SLOT_POS, vec4_t, "gl_Position"); + add_varying(VARYING_SLOT_POS, vec4_t, GLSL_PRECISION_HIGH, "gl_Position"); if (!state->es_shader || state->stage == MESA_SHADER_VERTEX || (state->stage == MESA_SHADER_GEOMETRY && - state->OES_geometry_point_size_enable)) { - add_varying(VARYING_SLOT_PSIZ, float_t, "gl_PointSize"); + (state->OES_geometry_point_size_enable || + state->EXT_geometry_point_size_enable)) || + ((state->stage == MESA_SHADER_TESS_CTRL || + state->stage == MESA_SHADER_TESS_EVAL) && + (state->OES_tessellation_point_size_enable || + state->EXT_tessellation_point_size_enable))) { + add_varying(VARYING_SLOT_PSIZ, + float_t, + state->is_version(0, 300) ? + GLSL_PRECISION_HIGH : + GLSL_PRECISION_MEDIUM, + "gl_PointSize"); } } - if (state->is_version(130, 0)) { + if (state->has_clip_distance()) { add_varying(VARYING_SLOT_CLIP_DIST0, array(float_t, 0), - "gl_ClipDistance"); + GLSL_PRECISION_HIGH, "gl_ClipDistance"); + } + if (state->has_cull_distance()) { + add_varying(VARYING_SLOT_CULL_DIST0, array(float_t, 0), + GLSL_PRECISION_HIGH, "gl_CullDistance"); } if (compatibility) { @@ -1279,19 +1497,19 @@ builtin_variable_generator::generate_varyings() const glsl_type *per_vertex_in_type = this->per_vertex_in.construct_interface_instance(); add_variable("gl_in", array(per_vertex_in_type, state->Const.MaxPatchVertices), - ir_var_shader_in, -1); + GLSL_PRECISION_NONE, ir_var_shader_in, -1); } if (state->stage == MESA_SHADER_GEOMETRY) { const glsl_type *per_vertex_in_type = this->per_vertex_in.construct_interface_instance(); add_variable("gl_in", array(per_vertex_in_type, 0), - ir_var_shader_in, -1); + GLSL_PRECISION_NONE, ir_var_shader_in, -1); } if (state->stage == MESA_SHADER_TESS_CTRL) { const glsl_type *per_vertex_out_type = this->per_vertex_out.construct_interface_instance(); add_variable("gl_out", array(per_vertex_out_type, 0), - ir_var_shader_out, -1); + GLSL_PRECISION_NONE, ir_var_shader_out, -1); } if (state->stage == MESA_SHADER_VERTEX || state->stage == MESA_SHADER_TESS_EVAL || @@ -1301,13 +1519,12 @@ builtin_variable_generator::generate_varyings() const glsl_struct_field *fields = per_vertex_out_type->fields.structure; for (unsigned i = 0; i < per_vertex_out_type->length; i++) { ir_variable *var = - add_variable(fields[i].name, fields[i].type, ir_var_shader_out, - fields[i].location); + add_variable(fields[i].name, fields[i].type, fields[i].precision, + ir_var_shader_out, fields[i].location); var->data.interpolation = fields[i].interpolation; var->data.centroid = fields[i].centroid; var->data.sample = fields[i].sample; var->data.patch = fields[i].patch; - var->data.precision = fields[i].precision; var->init_interface_type(per_vertex_out_type); } } @@ -1325,6 +1542,7 @@ _mesa_glsl_initialize_variables(exec_list *instructions, gen.generate_constants(); gen.generate_uniforms(); + gen.generate_special_vars(); gen.generate_varyings(); @@ -1347,86 +1565,7 @@ _mesa_glsl_initialize_variables(exec_list *instructions, case MESA_SHADER_COMPUTE: gen.generate_cs_special_vars(); break; + default: + break; } } - - -/** - * Initialize compute shader variables with values that are derived from other - * compute shader variable. - */ -static void -initialize_cs_derived_variables(gl_shader *shader, - ir_function_signature *const main_sig) -{ - assert(shader->Stage == MESA_SHADER_COMPUTE); - - ir_variable *gl_GlobalInvocationID = - shader->symbols->get_variable("gl_GlobalInvocationID"); - assert(gl_GlobalInvocationID); - ir_variable *gl_WorkGroupID = - shader->symbols->get_variable("gl_WorkGroupID"); - assert(gl_WorkGroupID); - ir_variable *gl_WorkGroupSize = - shader->symbols->get_variable("gl_WorkGroupSize"); - if (gl_WorkGroupSize == NULL) { - void *const mem_ctx = ralloc_parent(shader->ir); - gl_WorkGroupSize = new(mem_ctx) ir_variable(glsl_type::uvec3_type, - "gl_WorkGroupSize", - ir_var_auto); - gl_WorkGroupSize->data.how_declared = ir_var_declared_implicitly; - gl_WorkGroupSize->data.read_only = true; - shader->ir->push_head(gl_WorkGroupSize); - } - ir_variable *gl_LocalInvocationID = - shader->symbols->get_variable("gl_LocalInvocationID"); - assert(gl_LocalInvocationID); - - /* gl_GlobalInvocationID = - * gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID - */ - ir_instruction *inst = - assign(gl_GlobalInvocationID, - add(mul(gl_WorkGroupID, gl_WorkGroupSize), - gl_LocalInvocationID)); - main_sig->body.push_head(inst); - - /* gl_LocalInvocationIndex = - * gl_LocalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y + - * gl_LocalInvocationID.y * gl_WorkGroupSize.x + - * gl_LocalInvocationID.x; - */ - ir_expression *index_z = - mul(mul(swizzle_z(gl_LocalInvocationID), swizzle_x(gl_WorkGroupSize)), - swizzle_y(gl_WorkGroupSize)); - ir_expression *index_y = - mul(swizzle_y(gl_LocalInvocationID), swizzle_x(gl_WorkGroupSize)); - ir_expression *index_y_plus_z = add(index_y, index_z); - operand index_x(swizzle_x(gl_LocalInvocationID)); - ir_expression *index_x_plus_y_plus_z = add(index_y_plus_z, index_x); - ir_variable *gl_LocalInvocationIndex = - shader->symbols->get_variable("gl_LocalInvocationIndex"); - assert(gl_LocalInvocationIndex); - inst = assign(gl_LocalInvocationIndex, index_x_plus_y_plus_z); - main_sig->body.push_head(inst); -} - - -/** - * Initialize builtin variables with values based on other builtin variables. - * These are initialized in the main function. - */ -void -_mesa_glsl_initialize_derived_variables(gl_shader *shader) -{ - /* We only need to set CS variables currently. */ - if (shader->Stage != MESA_SHADER_COMPUTE) - return; - - ir_function_signature *const main_sig = - _mesa_get_main_function_signature(shader); - if (main_sig == NULL) - return; - - initialize_cs_derived_variables(shader, main_sig); -}