X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fbuiltin_variables.cpp;h=24d0d403328819967c81e3b466d9302e987dba50;hb=39006590517de05709d32378d6024de8041035d0;hp=405502eb8a43628d4c5294f0ecf821d189bb976c;hpb=ada3c3aa3da5d04bd597014dc1b5d4b028313513;p=mesa.git diff --git a/src/compiler/glsl/builtin_variables.cpp b/src/compiler/glsl/builtin_variables.cpp index 405502eb8a4..24d0d403328 100644 --- a/src/compiler/glsl/builtin_variables.cpp +++ b/src/compiler/glsl/builtin_variables.cpp @@ -21,12 +21,27 @@ * 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" @@ -38,11 +53,6 @@ static const struct gl_builtin_uniform_element gl_NumSamples_elements[] = { {NULL, {STATE_NUM_SAMPLES, 0, 0}, SWIZZLE_XXXX} }; -/* only for TCS */ -static const struct gl_builtin_uniform_element gl_PatchVerticesIn_elements[] = { - {NULL, {STATE_INTERNAL, STATE_TCS_PATCH_VERTICES_IN}, SWIZZLE_XXXX} -}; - static const struct gl_builtin_uniform_element gl_DepthRange_elements[] = { {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX}, {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY}, @@ -91,11 +101,11 @@ static const struct gl_builtin_uniform_element gl_LightSource_elements[] = { 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}, {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX}, {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY}, {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ}, + {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW}, + {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX}, }; static const struct gl_builtin_uniform_element gl_LightModel_elements[] = { @@ -240,7 +250,6 @@ static const struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = { #define STATEVAR(name) {#name, name ## _elements, ARRAY_SIZE(name ## _elements)} static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = { - STATEVAR(gl_PatchVerticesIn), STATEVAR(gl_NumSamples), STATEVAR(gl_DepthRange), STATEVAR(gl_ClipPlane), @@ -305,7 +314,8 @@ 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, enum glsl_interp_mode interp); const glsl_type *construct_interface_instance() const; private: @@ -323,7 +333,8 @@ 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, + enum glsl_interp_mode interp) { assert(this->num_fields < ARRAY_SIZE(this->fields)); this->fields[this->num_fields].type = type; @@ -331,17 +342,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_MODE_NONE; + this->fields[this->num_fields].interpolation = interp; 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].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].image_format = PIPE_FORMAT_NONE; 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; @@ -386,35 +397,74 @@ private: return symtab->get_type(name); } - ir_variable *add_input(int slot, const glsl_type *type, const char *name) + ir_variable *add_input(int slot, const glsl_type *type, int precision, + const char *name, + enum glsl_interp_mode interp = INTERP_MODE_NONE) + { + return add_variable(name, type, precision, ir_var_shader_in, slot, interp); + } + + ir_variable *add_input(int slot, const glsl_type *type, const char *name, + enum glsl_interp_mode interp = INTERP_MODE_NONE) + { + return add_input(slot, type, GLSL_PRECISION_NONE, name, interp); + } + + ir_variable *add_output(int slot, const glsl_type *type, int precision, + const char *name) { - return add_variable(name, type, ir_var_shader_in, slot); + 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, enum glsl_interp_mode interp = INTERP_MODE_NONE); 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, + enum glsl_interp_mode interp = INTERP_MODE_NONE); + void add_varying(int slot, const glsl_type *type, const char *name, + enum glsl_interp_mode interp = INTERP_MODE_NONE) + { + add_varying(slot, type, GLSL_PRECISION_NONE, name, interp); + } exec_list * const instructions; struct _mesa_glsl_parse_state * const state; @@ -447,7 +497,7 @@ 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->compat_shader || !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), @@ -460,8 +510,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; @@ -490,6 +542,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. */ @@ -502,7 +557,9 @@ builtin_variable_generator::add_index_variable(const char *name, ir_variable * builtin_variable_generator::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, + enum glsl_interp_mode interp) { ir_variable *var = new(symtab) ir_variable(type, name, mode); var->data.how_declared = ir_var_declared_implicitly; @@ -529,6 +586,10 @@ builtin_variable_generator::add_variable(const char *name, var->data.location = slot; var->data.explicit_location = (slot >= 0); var->data.explicit_index = 0; + var->data.interpolation = interp; + + 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. @@ -552,9 +613,11 @@ _mesa_glsl_get_builtin_uniform_desc(const char *name) 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); + ir_variable *const uni = + add_variable(name, type, precision, ir_var_uniform, -1); const struct gl_builtin_uniform_desc* const statevar = _mesa_glsl_get_builtin_uniform_desc(name); @@ -590,10 +653,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; @@ -606,6 +670,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)); @@ -632,8 +697,16 @@ 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) { + 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); @@ -661,16 +734,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 @@ -882,8 +949,10 @@ builtin_variable_generator::generate_constants() if (state->is_version(410, 0) || state->ARB_viewport_array_enable || - state->OES_viewport_array_enable) - add_const("gl_MaxViewports", state->Const.MaxViewports); + state->OES_viewport_array_enable) { + add_const("gl_MaxViewports", GLSL_PRECISION_HIGH, + state->Const.MaxViewports); + } if (state->has_tessellation_shader()) { add_const("gl_MaxPatchVertices", state->Const.MaxPatchVertices); @@ -916,7 +985,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"); @@ -1011,29 +1080,32 @@ builtin_variable_generator::generate_special_vars() void builtin_variable_generator::generate_vs_special_vars() { - ir_variable *var; + 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->EXT_draw_instanced_enable && state->is_version(0, 100)) + add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_InstanceIDEXT"); - if (state->is_version(130, 300)) - add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, "gl_VertexID"); 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 || - state->ARB_shader_viewport_layer_array_enable) { - var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); - var->data.interpolation = INTERP_MODE_FLAT; - } - 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_MODE_FLAT; - } if (compatibility) { add_input(VERT_ATTRIB_POS, vec4_t, "gl_Vertex"); add_input(VERT_ATTRIB_NORMAL, vec3_t, "gl_Normal"); @@ -1058,31 +1130,42 @@ 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_INVOCATION_ID, int_t, "gl_InvocationID"); - - if (state->ctx->Const.LowerTCSPatchVerticesIn) { - add_uniform(int_t, "gl_PatchVerticesIn"); - } else { - add_system_value(SYSTEM_VALUE_VERTICES_IN, int_t, "gl_PatchVerticesIn"); - } + 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), "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), "gl_BoundingBox") - ->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; + } + + /* NOTE: These are completely pointless. Writing these will never go + * anywhere. But the specs demands it. So we add them with a slot of -1, + * which makes the data go nowhere. + */ + if (state->NV_viewport_array2_enable) { + add_output(-1, int_t, "gl_Layer"); + add_output(-1, int_t, "gl_ViewportIndex"); + add_output(-1, array(int_t, 1), "gl_ViewportMask"); + } + } @@ -1094,26 +1177,35 @@ builtin_variable_generator::generate_tes_special_vars() { ir_variable *var; - 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_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), - "gl_TessLevelOuter")->data.patch = 1; + GLSL_PRECISION_HIGH, "gl_TessLevelOuter")->data.patch = 1; add_input(VARYING_SLOT_TESS_LEVEL_INNER, array(float_t, 2), - "gl_TessLevelInner")->data.patch = 1; + GLSL_PRECISION_HIGH, "gl_TessLevelInner")->data.patch = 1; } else { add_system_value(SYSTEM_VALUE_TESS_LEVEL_OUTER, array(float_t, 4), - "gl_TessLevelOuter"); + GLSL_PRECISION_HIGH, "gl_TessLevelOuter"); add_system_value(SYSTEM_VALUE_TESS_LEVEL_INNER, array(float_t, 2), - "gl_TessLevelInner"); + GLSL_PRECISION_HIGH, "gl_TessLevelInner"); } - if (state->ARB_shader_viewport_layer_array_enable) { + if (state->ARB_shader_viewport_layer_array_enable || + state->NV_viewport_array2_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; } + if (state->NV_viewport_array2_enable) { + var = add_output(VARYING_SLOT_VIEWPORT_MASK, array(int_t, 1), + "gl_ViewportMask"); + var->data.interpolation = INTERP_MODE_FLAT; + } } @@ -1125,16 +1217,23 @@ builtin_variable_generator::generate_gs_special_vars() { ir_variable *var; - var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); + 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, "gl_ViewportIndex"); + var = add_output(VARYING_SLOT_VIEWPORT, int_t, GLSL_PRECISION_HIGH, + "gl_ViewportIndex"); + var->data.interpolation = INTERP_MODE_FLAT; + } + if (state->NV_viewport_array2_enable) { + var = add_output(VARYING_SLOT_VIEWPORT_MASK, array(int_t, 1), + "gl_ViewportMask"); 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, "gl_InvocationID"); + add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, GLSL_PRECISION_HIGH, + "gl_InvocationID"); } /* Although gl_PrimitiveID appears in tessellation control and tessellation @@ -1147,9 +1246,11 @@ 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 = 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, "gl_PrimitiveID"); + var = add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, GLSL_PRECISION_HIGH, + "gl_PrimitiveID"); var->data.interpolation = INTERP_MODE_FLAT; } @@ -1162,21 +1263,37 @@ 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.GLSLFrontFacingIsSysVal) - add_system_value(SYSTEM_VALUE_FRONT_FACE, bool_t, "gl_FrontFacing"); - else - add_input(VARYING_SLOT_FACE, bool_t, "gl_FrontFacing"); + 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 (state->is_version(120, 100)) - add_input(VARYING_SLOT_PNTC, vec2_t, "gl_PointCoord"); + if (this->state->ctx->Const.GLSLFrontFacingIsSysVal) { + var = add_system_value(SYSTEM_VALUE_FRONT_FACE, bool_t, "gl_FrontFacing"); + var->data.interpolation = INTERP_MODE_FLAT; + } else { + var = add_input(VARYING_SLOT_FACE, bool_t, "gl_FrontFacing"); + var->data.interpolation = INTERP_MODE_FLAT; + } - if (state->has_geometry_shader()) { - var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID"); + 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() || 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; } @@ -1185,9 +1302,12 @@ 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)) { @@ -1198,21 +1318,24 @@ builtin_variable_generator::generate_fs_special_vars() 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) { add_index_output(FRAG_RESULT_COLOR, 1, vec4_t, - "gl_SecondaryFragColorEXT"); + 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"); @@ -1234,8 +1357,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 @@ -1243,28 +1368,29 @@ 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, 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, "gl_Layer"); - var->data.interpolation = INTERP_MODE_FLAT; + add_varying(VARYING_SLOT_LAYER, int_t, GLSL_PRECISION_HIGH, + "gl_Layer", 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_MODE_FLAT; + add_varying(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex", INTERP_MODE_FLAT); } if (state->is_version(450, 310) || state->ARB_ES3_1_compatibility_enable) @@ -1288,15 +1414,10 @@ builtin_variable_generator::generate_cs_special_vars() uvec3_t, "gl_LocalGroupSizeARB"); } - if (state->ctx->Const.LowerCsDerivedVariables) { - add_variable("gl_GlobalInvocationID", uvec3_t, ir_var_auto, 0); - add_variable("gl_LocalInvocationIndex", uint_t, ir_var_auto, 0); - } else { - add_system_value(SYSTEM_VALUE_GLOBAL_INVOCATION_ID, - uvec3_t, "gl_GlobalInvocationID"); - add_system_value(SYSTEM_VALUE_LOCAL_INVOCATION_INDEX, - uint_t, "gl_LocalInvocationIndex"); - } + add_system_value(SYSTEM_VALUE_GLOBAL_INVOCATION_ID, + uvec3_t, "gl_GlobalInvocationID"); + add_system_value(SYSTEM_VALUE_LOCAL_INVOCATION_INDEX, + uint_t, "gl_LocalInvocationIndex"); } @@ -1307,19 +1428,20 @@ 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, + enum glsl_interp_mode interp) { 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, interp); /* FALLTHROUGH */ case MESA_SHADER_VERTEX: - this->per_vertex_out.add_field(slot, type, name); + this->per_vertex_out.add_field(slot, type, precision, name, interp); break; case MESA_SHADER_FRAGMENT: - add_input(slot, type, name); + add_input(slot, type, precision, name, interp); break; case MESA_SHADER_COMPUTE: /* Compute shaders don't have varyings. */ @@ -1337,9 +1459,12 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type, void builtin_variable_generator::generate_varyings() { + struct gl_shader_compiler_options *options = + &state->ctx->Const.ShaderCompilerOptions[state->stage]; + /* 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 && @@ -1349,17 +1474,50 @@ builtin_variable_generator::generate_varyings() 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, "gl_PointSize"); + add_varying(VARYING_SLOT_PSIZ, + float_t, + state->is_version(0, 300) ? + GLSL_PRECISION_HIGH : + GLSL_PRECISION_MEDIUM, + "gl_PointSize"); } + if (state->stage == MESA_SHADER_VERTEX) { + if (state->AMD_vertex_shader_viewport_index_enable || + state->ARB_shader_viewport_layer_array_enable || + state->NV_viewport_array2_enable) { + add_varying(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex", INTERP_MODE_FLAT); + } + + if (state->AMD_vertex_shader_layer_enable || + state->ARB_shader_viewport_layer_array_enable || + state->NV_viewport_array2_enable) { + add_varying(VARYING_SLOT_LAYER, int_t, GLSL_PRECISION_HIGH, + "gl_Layer", INTERP_MODE_FLAT); + } + + /* From the NV_viewport_array2 specification: + * + * "The variable gl_ViewportMask[] is available as an output variable + * in the VTG languages. The array has ceil(v/32) elements where v is + * the maximum number of viewports supported by the implementation." + * + * Since no drivers expose more than 16 viewports, we can simply set the + * array size to 1 rather than computing it and dealing with varying + * slot complication. + */ + if (state->NV_viewport_array2_enable) + add_varying(VARYING_SLOT_VIEWPORT_MASK, array(int_t, 1), + "gl_ViewportMask", INTERP_MODE_FLAT); + } } 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), - "gl_CullDistance"); + GLSL_PRECISION_HIGH, "gl_CullDistance"); } if (compatibility) { @@ -1394,19 +1552,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 || @@ -1416,14 +1574,16 @@ 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); + + var->data.invariant = fields[i].location == VARYING_SLOT_POS && + options->PositionAlwaysInvariant; } } } @@ -1467,84 +1627,3 @@ _mesa_glsl_initialize_variables(exec_list *instructions, 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(struct gl_context *ctx, - gl_shader *shader) -{ - /* We only need to set CS variables currently. */ - if (shader->Stage == MESA_SHADER_COMPUTE && - ctx->Const.LowerCsDerivedVariables) { - ir_function_signature *const main_sig = - _mesa_get_main_function_signature(shader->symbols); - - if (main_sig != NULL) - initialize_cs_derived_variables(shader, main_sig); - } -}