X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fbuiltin_variables.cpp;h=e8eab808a190a6cd4f4ffcb50f4e016f9d7d19a2;hb=839793680f99b8387bee9489733d5071c10f3ace;hp=3e7a84521e932ea95c6f33684afd7982f2a2c993;hpb=0398b69954eb8e73e9ae663ce200170ff70d216d;p=mesa.git diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp index 3e7a84521e9..e8eab808a19 100644 --- a/src/glsl/builtin_variables.cpp +++ b/src/glsl/builtin_variables.cpp @@ -22,29 +22,32 @@ */ #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/uniforms.h" -#include "program/prog_parameter.h" #include "program/prog_statevars.h" #include "program/prog_instruction.h" -static struct gl_builtin_uniform_element gl_NumSamples_elements[] = { +using namespace ir_builder; + +static const struct gl_builtin_uniform_element gl_NumSamples_elements[] = { {NULL, {STATE_NUM_SAMPLES, 0, 0}, SWIZZLE_XXXX} }; -static struct gl_builtin_uniform_element gl_DepthRange_elements[] = { +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}, {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ}, }; -static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = { +static const struct gl_builtin_uniform_element gl_ClipPlane_elements[] = { {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW} }; -static struct gl_builtin_uniform_element gl_Point_elements[] = { +static const struct gl_builtin_uniform_element gl_Point_elements[] = { {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX}, {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY}, {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ}, @@ -54,7 +57,7 @@ static struct gl_builtin_uniform_element gl_Point_elements[] = { {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ}, }; -static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = { +static const struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = { {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW}, {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, @@ -62,7 +65,7 @@ static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = { {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX}, }; -static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = { +static const struct gl_builtin_uniform_element gl_BackMaterial_elements[] = { {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW}, {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW}, {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW}, @@ -70,7 +73,7 @@ static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = { {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX}, }; -static struct gl_builtin_uniform_element gl_LightSource_elements[] = { +static const struct gl_builtin_uniform_element gl_LightSource_elements[] = { {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, @@ -89,67 +92,67 @@ static struct gl_builtin_uniform_element gl_LightSource_elements[] = { {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ}, }; -static struct gl_builtin_uniform_element gl_LightModel_elements[] = { +static const struct gl_builtin_uniform_element gl_LightModel_elements[] = { {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = { +static const struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = { {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = { +static const struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = { {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = { +static const struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = { {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = { +static const struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = { {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW}, {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW}, {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = { +static const struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = { {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = { +static const struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = { +static const struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = { +static const struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = { +static const struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = { +static const struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = { +static const struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = { +static const struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = { +static const struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = { {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_Fog_elements[] = { +static const struct gl_builtin_uniform_element gl_Fog_elements[] = { {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW}, {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX}, {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY}, @@ -157,32 +160,24 @@ static struct gl_builtin_uniform_element gl_Fog_elements[] = { {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW}, }; -static struct gl_builtin_uniform_element gl_NormalScale_elements[] = { +static const struct gl_builtin_uniform_element gl_NormalScale_elements[] = { {NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX}, }; -static struct gl_builtin_uniform_element gl_BumpRotMatrix0MESA_elements[] = { - {NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_0}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_BumpRotMatrix1MESA_elements[] = { - {NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_1}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = { +static const struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = { {NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = { +static const struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = { {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB, 0}, SWIZZLE_XYZW}, }; -static struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = { +static const struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = { {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, 0}, SWIZZLE_XYZW}, }; #define MATRIX(name, statevar, modifier) \ - static struct gl_builtin_uniform_element name ## _elements[] = { \ + static const struct gl_builtin_uniform_element name ## _elements[] = { \ { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \ { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \ { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \ @@ -225,7 +220,7 @@ MATRIX(gl_TextureMatrixTranspose, MATRIX(gl_TextureMatrixInverseTranspose, STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE); -static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = { +static const struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = { { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE}, MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) }, { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE}, @@ -236,7 +231,7 @@ static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = { #undef MATRIX -#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)} +#define STATEVAR(name) {#name, name ## _elements, ARRAY_SIZE(name ## _elements)} static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = { STATEVAR(gl_NumSamples), @@ -285,8 +280,6 @@ static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = { STATEVAR(gl_NormalMatrix), STATEVAR(gl_NormalScale), - STATEVAR(gl_BumpRotMatrix0MESA), - STATEVAR(gl_BumpRotMatrix1MESA), STATEVAR(gl_FogParamsOptimizedMESA), STATEVAR(gl_CurrentAttribVertMESA), STATEVAR(gl_CurrentAttribFragMESA), @@ -328,11 +321,13 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type, assert(this->num_fields < ARRAY_SIZE(this->fields)); this->fields[this->num_fields].type = type; this->fields[this->num_fields].name = name; - this->fields[this->num_fields].row_major = false; + this->fields[this->num_fields].matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; this->fields[this->num_fields].location = slot; this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_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->num_fields++; } @@ -354,6 +349,8 @@ public: void generate_constants(); void generate_uniforms(); void generate_vs_special_vars(); + void generate_tcs_special_vars(); + void generate_tes_special_vars(); void generate_gs_special_vars(); void generate_fs_special_vars(); void generate_cs_special_vars(); @@ -380,6 +377,11 @@ private: return add_variable(name, type, ir_var_shader_out, slot); } + ir_variable *add_index_output(int slot, int index, const glsl_type *type, const char *name) + { + return add_index_variable(name, type, ir_var_shader_out, slot, index); + } + ir_variable *add_system_value(int slot, const glsl_type *type, const char *name) { @@ -388,11 +390,12 @@ private: ir_variable *add_variable(const char *name, const glsl_type *type, 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); 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, - const char *name_as_gs_input); + void add_varying(int slot, const glsl_type *type, const char *name); exec_list * const instructions; struct _mesa_glsl_parse_state * const state; @@ -407,10 +410,12 @@ private: const glsl_type * const bool_t; const glsl_type * const int_t; + const glsl_type * const uint_t; const glsl_type * const float_t; const glsl_type * const vec2_t; const glsl_type * const vec3_t; const glsl_type * const vec4_t; + const glsl_type * const uvec3_t; const glsl_type * const mat3_t; const glsl_type * const mat4_t; @@ -424,12 +429,54 @@ builtin_variable_generator::builtin_variable_generator( : instructions(instructions), state(state), symtab(state->symbols), compatibility(!state->is_version(140, 100)), bool_t(glsl_type::bool_type), int_t(glsl_type::int_type), + uint_t(glsl_type::uint_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), mat3_t(glsl_type::mat3_type), mat4_t(glsl_type::mat4_type) { } +ir_variable * +builtin_variable_generator::add_index_variable(const char *name, + const glsl_type *type, + 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; + + switch (var->data.mode) { + case ir_var_auto: + case ir_var_shader_in: + case ir_var_uniform: + case ir_var_system_value: + var->data.read_only = true; + break; + case ir_var_shader_out: + case ir_var_shader_storage: + break; + default: + /* The only variables that are added using this function should be + * uniforms, shader storage, shader inputs, and shader outputs, constants + * (which use ir_var_auto), and system values. + */ + assert(0); + break; + } + + var->data.location = slot; + var->data.explicit_location = (slot >= 0); + var->data.explicit_index = 1; + var->data.index = index; + + /* Once the variable is created an initialized, add it to the symbol table + * and add the declaration to the IR stream. + */ + instructions->push_tail(var); + + symtab->add_variable(var); + return var; +} ir_variable * builtin_variable_generator::add_variable(const char *name, @@ -447,11 +494,12 @@ builtin_variable_generator::add_variable(const char *name, var->data.read_only = true; break; case ir_var_shader_out: + case ir_var_shader_storage: break; default: /* The only variables that are added using this function should be - * uniforms, shader inputs, and shader outputs, constants (which use - * ir_var_auto), and system values. + * uniforms, shader storage, shader inputs, and shader outputs, constants + * (which use ir_var_auto), and system values. */ assert(0); break; @@ -489,16 +537,14 @@ builtin_variable_generator::add_uniform(const glsl_type *type, &_mesa_builtin_uniform_desc[i]; const unsigned array_count = type->is_array() ? type->length : 1; - uni->num_state_slots = array_count * statevar->num_elements; ir_state_slot *slots = - ralloc_array(uni, ir_state_slot, uni->num_state_slots); - - uni->state_slots = slots; + uni->allocate_state_slots(array_count * statevar->num_elements); for (unsigned a = 0; a < array_count; a++) { for (unsigned j = 0; j < statevar->num_elements; j++) { - struct gl_builtin_uniform_element *element = &statevar->elements[j]; + const struct gl_builtin_uniform_element *element = + &statevar->elements[j]; memcpy(slots->tokens, element->tokens, sizeof(element->tokens)); if (type->is_array()) { @@ -582,6 +628,14 @@ builtin_variable_generator::generate_constants() add_const("gl_MaxVaryingVectors", state->ctx->Const.MaxVarying); } + + /* EXT_blend_func_extended brings a built in constant + * for determining number of dual source draw buffers + */ + if (state->EXT_blend_func_extended_enable) { + add_const("gl_MaxDualSourceDrawBuffersEXT", + state->Const.MaxDualSourceDrawBuffers); + } } else { add_const("gl_MaxVertexUniformComponents", state->Const.MaxVertexUniformComponents); @@ -666,22 +720,59 @@ builtin_variable_generator::generate_constants() add_const("gl_MaxTextureCoords", state->Const.MaxTextureCoords); } - if (state->ARB_shader_atomic_counters_enable) { + if (state->has_atomic_counters()) { add_const("gl_MaxVertexAtomicCounters", state->Const.MaxVertexAtomicCounters); - add_const("gl_MaxGeometryAtomicCounters", - state->Const.MaxGeometryAtomicCounters); add_const("gl_MaxFragmentAtomicCounters", state->Const.MaxFragmentAtomicCounters); add_const("gl_MaxCombinedAtomicCounters", state->Const.MaxCombinedAtomicCounters); add_const("gl_MaxAtomicCounterBindings", state->Const.MaxAtomicBufferBindings); - add_const("gl_MaxTessControlAtomicCounters", 0); - add_const("gl_MaxTessEvaluationAtomicCounters", 0); + + /* When Mesa adds support for GL_OES_geometry_shader and + * GL_OES_tessellation_shader, this will need to change. + */ + if (!state->es_shader) { + add_const("gl_MaxGeometryAtomicCounters", + state->Const.MaxGeometryAtomicCounters); + add_const("gl_MaxTessControlAtomicCounters", + state->Const.MaxTessControlAtomicCounters); + add_const("gl_MaxTessEvaluationAtomicCounters", + state->Const.MaxTessEvaluationAtomicCounters); + } } - if (state->is_version(430, 0) || state->ARB_compute_shader_enable) { + if (state->is_version(420, 310)) { + add_const("gl_MaxVertexAtomicCounterBuffers", + state->Const.MaxVertexAtomicCounterBuffers); + add_const("gl_MaxFragmentAtomicCounterBuffers", + state->Const.MaxFragmentAtomicCounterBuffers); + add_const("gl_MaxCombinedAtomicCounterBuffers", + state->Const.MaxCombinedAtomicCounterBuffers); + add_const("gl_MaxAtomicCounterBufferSize", + state->Const.MaxAtomicCounterBufferSize); + + /* When Mesa adds support for GL_OES_geometry_shader and + * GL_OES_tessellation_shader, this will need to change. + */ + if (!state->es_shader) { + add_const("gl_MaxGeometryAtomicCounterBuffers", + state->Const.MaxGeometryAtomicCounterBuffers); + add_const("gl_MaxTessControlAtomicCounterBuffers", + state->Const.MaxTessControlAtomicCounterBuffers); + add_const("gl_MaxTessEvaluationAtomicCounterBuffers", + state->Const.MaxTessEvaluationAtomicCounterBuffers); + } + } + + if (state->is_version(430, 310) || state->ARB_compute_shader_enable) { + add_const("gl_MaxComputeAtomicCounterBuffers", MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS); + add_const("gl_MaxComputeAtomicCounters", MAX_COMPUTE_ATOMIC_COUNTERS); + add_const("gl_MaxComputeImageUniforms", MAX_COMPUTE_IMAGE_UNIFORMS); + add_const("gl_MaxComputeTextureImageUnits", MAX_COMPUTE_TEXTURE_IMAGE_UNITS); + add_const("gl_MaxComputeUniformComponents", MAX_COMPUTE_UNIFORM_COMPONENTS); + add_const_ivec3("gl_MaxComputeWorkGroupCount", state->Const.MaxComputeWorkGroupCount[0], state->Const.MaxComputeWorkGroupCount[1], @@ -690,6 +781,80 @@ builtin_variable_generator::generate_constants() state->Const.MaxComputeWorkGroupSize[0], state->Const.MaxComputeWorkGroupSize[1], state->Const.MaxComputeWorkGroupSize[2]); + + /* From the GLSL 4.40 spec, section 7.1 (Built-In Language Variables): + * + * The built-in constant gl_WorkGroupSize is a compute-shader + * constant containing the local work-group size of the shader. The + * size of the work group in the X, Y, and Z dimensions is stored in + * the x, y, and z components. The constants values in + * gl_WorkGroupSize will match those specified in the required + * local_size_x, local_size_y, and local_size_z layout qualifiers + * for the current shader. This is a constant so that it can be + * used to size arrays of memory that can be shared within the local + * work group. It is a compile-time error to use gl_WorkGroupSize + * in a shader that does not declare a fixed local group size, or + * before that shader has declared a fixed local group size, using + * local_size_x, local_size_y, and local_size_z. + * + * To prevent the shader from trying to refer to gl_WorkGroupSize before + * the layout declaration, we don't define it here. Intead we define it + * in ast_cs_input_layout::hir(). + */ + } + + if (state->is_version(420, 310) || + state->ARB_shader_image_load_store_enable) { + add_const("gl_MaxImageUnits", + state->Const.MaxImageUnits); + add_const("gl_MaxVertexImageUniforms", + state->Const.MaxVertexImageUniforms); + add_const("gl_MaxFragmentImageUniforms", + state->Const.MaxFragmentImageUniforms); + add_const("gl_MaxCombinedImageUniforms", + state->Const.MaxCombinedImageUniforms); + + if (!state->es_shader) { + add_const("gl_MaxCombinedImageUnitsAndFragmentOutputs", + state->Const.MaxCombinedShaderOutputResources); + add_const("gl_MaxImageSamples", + state->Const.MaxImageSamples); + add_const("gl_MaxGeometryImageUniforms", + state->Const.MaxGeometryImageUniforms); + } + + if (state->is_version(450, 310)) { + add_const("gl_MaxCombinedShaderOutputResources", + state->Const.MaxCombinedShaderOutputResources); + } + + if (state->is_version(400, 0) || + state->ARB_tessellation_shader_enable) { + add_const("gl_MaxTessControlImageUniforms", + state->Const.MaxTessControlImageUniforms); + add_const("gl_MaxTessEvaluationImageUniforms", + state->Const.MaxTessEvaluationImageUniforms); + } + } + + if (state->is_version(410, 0) || + state->ARB_viewport_array_enable) + add_const("gl_MaxViewports", state->Const.MaxViewports); + + if (state->is_version(400, 0) || + state->ARB_tessellation_shader_enable) { + add_const("gl_MaxPatchVertices", state->Const.MaxPatchVertices); + add_const("gl_MaxTessGenLevel", state->Const.MaxTessGenLevel); + add_const("gl_MaxTessControlInputComponents", state->Const.MaxTessControlInputComponents); + add_const("gl_MaxTessControlOutputComponents", state->Const.MaxTessControlOutputComponents); + add_const("gl_MaxTessControlTextureImageUnits", state->Const.MaxTessControlTextureImageUnits); + add_const("gl_MaxTessEvaluationInputComponents", state->Const.MaxTessEvaluationInputComponents); + add_const("gl_MaxTessEvaluationOutputComponents", state->Const.MaxTessEvaluationOutputComponents); + add_const("gl_MaxTessEvaluationTextureImageUnits", state->Const.MaxTessEvaluationTextureImageUnits); + add_const("gl_MaxTessPatchComponents", state->Const.MaxTessPatchComponents); + add_const("gl_MaxTessControlTotalOutputComponents", state->Const.MaxTessControlTotalOutputComponents); + add_const("gl_MaxTessControlUniformComponents", state->Const.MaxTessControlUniformComponents); + add_const("gl_MaxTessEvaluationUniformComponents", state->Const.MaxTessEvaluationUniformComponents); } } @@ -700,7 +865,8 @@ builtin_variable_generator::generate_constants() void builtin_variable_generator::generate_uniforms() { - add_uniform(int_t, "gl_NumSamples"); + if (state->is_version(400, 0) || state->ARB_sample_shading_enable) + add_uniform(int_t, "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"); @@ -721,8 +887,6 @@ builtin_variable_generator::generate_uniforms() add_uniform(mat4_t, "gl_ModelViewProjectionMatrixInverseTranspose"); add_uniform(float_t, "gl_NormalScale"); add_uniform(type("gl_LightModelParameters"), "gl_LightModel"); - add_uniform(vec2_t, "gl_BumpRotMatrix0MESA"); - add_uniform(vec2_t, "gl_BumpRotMatrix1MESA"); add_uniform(vec4_t, "gl_FogParamsOptimizedMESA"); const glsl_type *const mat4_array_type = @@ -779,14 +943,22 @@ builtin_variable_generator::generate_uniforms() void 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->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->AMD_vertex_shader_layer_enable) - add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); + if (state->AMD_vertex_shader_layer_enable) { + var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); + var->data.interpolation = INTERP_QUALIFIER_FLAT; + } + if (state->AMD_vertex_shader_viewport_index_enable) { + var = add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); + var->data.interpolation = INTERP_QUALIFIER_FLAT; + } if (compatibility) { add_input(VERT_ATTRIB_POS, vec4_t, "gl_Vertex"); add_input(VERT_ATTRIB_NORMAL, vec3_t, "gl_Normal"); @@ -805,15 +977,55 @@ builtin_variable_generator::generate_vs_special_vars() } +/** + * Generate variables which only exist in tessellation control shaders. + */ +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_output(VARYING_SLOT_TESS_LEVEL_OUTER, array(float_t, 4), + "gl_TessLevelOuter")->data.patch = 1; + add_output(VARYING_SLOT_TESS_LEVEL_INNER, array(float_t, 2), + "gl_TessLevelInner")->data.patch = 1; +} + + +/** + * Generate variables which only exist in tessellation evaluation shaders. + */ +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"); +} + + /** * Generate variables which only exist in geometry shaders. */ void builtin_variable_generator::generate_gs_special_vars() { - add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); - if (state->ARB_viewport_array_enable) - add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); + 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; + } + 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 @@ -825,7 +1037,6 @@ 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. */ - ir_variable *var; 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"); @@ -839,14 +1050,15 @@ builtin_variable_generator::generate_gs_special_vars() void builtin_variable_generator::generate_fs_special_vars() { + ir_variable *var; + add_input(VARYING_SLOT_POS, vec4_t, "gl_FragCoord"); 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(150, 0)) { - ir_variable *var = - add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID"); + var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID"); var->data.interpolation = INTERP_QUALIFIER_FLAT; } @@ -860,6 +1072,19 @@ builtin_variable_generator::generate_fs_special_vars() array(vec4_t, state->Const.MaxDrawBuffers), "gl_FragData"); } + 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_DATA0, 1, + array(vec4_t, state->Const.MaxDualSourceDrawBuffers), + "gl_SecondaryFragDataEXT"); + } + /* gl_FragDepth has always been in desktop GLSL, but did not appear in GLSL * ES 1.00. */ @@ -870,17 +1095,17 @@ builtin_variable_generator::generate_fs_special_vars() ir_variable *const var = add_output(FRAG_RESULT_STENCIL, int_t, "gl_FragStencilRefARB"); if (state->ARB_shader_stencil_export_warn) - var->warn_extension = "GL_ARB_shader_stencil_export"; + var->enable_extension_warning("GL_ARB_shader_stencil_export"); } if (state->AMD_shader_stencil_export_enable) { ir_variable *const var = add_output(FRAG_RESULT_STENCIL, int_t, "gl_FragStencilRefAMD"); if (state->AMD_shader_stencil_export_warn) - var->warn_extension = "GL_AMD_shader_stencil_export"; + var->enable_extension_warning("GL_AMD_shader_stencil_export"); } - if (state->ARB_sample_shading_enable) { + if (state->is_version(400, 0) || state->ARB_sample_shading_enable) { add_system_value(SYSTEM_VALUE_SAMPLE_ID, int_t, "gl_SampleID"); add_system_value(SYSTEM_VALUE_SAMPLE_POS, vec2_t, "gl_SamplePosition"); /* From the ARB_sample_shading specification: @@ -893,9 +1118,19 @@ builtin_variable_generator::generate_fs_special_vars() add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), "gl_SampleMask"); } - if (state->ARB_gpu_shader5_enable) { + if (state->is_version(400, 0) || state->ARB_gpu_shader5_enable) { add_system_value(SYSTEM_VALUE_SAMPLE_MASK_IN, array(int_t, 1), "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; + var = add_input(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); + var->data.interpolation = INTERP_QUALIFIER_FLAT; + } + + if (state->is_version(450, 310)/* || state->ARB_ES3_1_compatibility_enable*/) + add_system_value(SYSTEM_VALUE_HELPER_INVOCATION, bool_t, "gl_HelperInvocation"); } @@ -905,22 +1140,27 @@ builtin_variable_generator::generate_fs_special_vars() void builtin_variable_generator::generate_cs_special_vars() { - /* TODO: finish this. */ + add_system_value(SYSTEM_VALUE_LOCAL_INVOCATION_ID, uvec3_t, + "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); } /** * Add a single "varying" variable. The variable's type and direction (input * or output) are adjusted as appropriate for the type of shader being - * compiled. For geometry shaders using {ARB,EXT}_geometry_shader4, - * name_as_gs_input is used for the input (to avoid ambiguity). + * compiled. */ void builtin_variable_generator::add_varying(int slot, const glsl_type *type, - const char *name, - const char *name_as_gs_input) + 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); /* FALLTHROUGH */ @@ -944,42 +1184,66 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type, void builtin_variable_generator::generate_varyings() { -#define ADD_VARYING(loc, type, name) \ - add_varying(loc, type, name, name "In") - /* 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_PSIZ, float_t, "gl_PointSize"); + add_varying(VARYING_SLOT_POS, vec4_t, "gl_Position"); + add_varying(VARYING_SLOT_PSIZ, float_t, "gl_PointSize"); } if (state->is_version(130, 0)) { - ADD_VARYING(VARYING_SLOT_CLIP_DIST0, array(float_t, 0), + add_varying(VARYING_SLOT_CLIP_DIST0, array(float_t, 0), "gl_ClipDistance"); } if (compatibility) { - ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord"); - ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord"); + add_varying(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord"); + add_varying(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord"); if (state->stage == MESA_SHADER_FRAGMENT) { - ADD_VARYING(VARYING_SLOT_COL0, vec4_t, "gl_Color"); - ADD_VARYING(VARYING_SLOT_COL1, vec4_t, "gl_SecondaryColor"); + add_varying(VARYING_SLOT_COL0, vec4_t, "gl_Color"); + add_varying(VARYING_SLOT_COL1, vec4_t, "gl_SecondaryColor"); } else { - ADD_VARYING(VARYING_SLOT_CLIP_VERTEX, vec4_t, "gl_ClipVertex"); - ADD_VARYING(VARYING_SLOT_COL0, vec4_t, "gl_FrontColor"); - ADD_VARYING(VARYING_SLOT_BFC0, vec4_t, "gl_BackColor"); - ADD_VARYING(VARYING_SLOT_COL1, vec4_t, "gl_FrontSecondaryColor"); - ADD_VARYING(VARYING_SLOT_BFC1, vec4_t, "gl_BackSecondaryColor"); + add_varying(VARYING_SLOT_CLIP_VERTEX, vec4_t, "gl_ClipVertex"); + add_varying(VARYING_SLOT_COL0, vec4_t, "gl_FrontColor"); + add_varying(VARYING_SLOT_BFC0, vec4_t, "gl_BackColor"); + add_varying(VARYING_SLOT_COL1, vec4_t, "gl_FrontSecondaryColor"); + add_varying(VARYING_SLOT_BFC1, vec4_t, "gl_BackSecondaryColor"); } } + /* Section 7.1 (Built-In Language Variables) of the GLSL 4.00 spec + * says: + * + * "In the tessellation control language, built-in variables are + * intrinsically declared as: + * + * in gl_PerVertex { + * vec4 gl_Position; + * float gl_PointSize; + * float gl_ClipDistance[]; + * } gl_in[gl_MaxPatchVertices];" + */ + if (state->stage == MESA_SHADER_TESS_CTRL || + state->stage == MESA_SHADER_TESS_EVAL) { + 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); + } 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); } - if (state->stage == MESA_SHADER_VERTEX || state->stage == MESA_SHADER_GEOMETRY) { + 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); + } + if (state->stage == MESA_SHADER_VERTEX || + state->stage == MESA_SHADER_TESS_EVAL || + state->stage == MESA_SHADER_GEOMETRY) { const glsl_type *per_vertex_out_type = this->per_vertex_out.construct_interface_instance(); const glsl_struct_field *fields = per_vertex_out_type->fields.structure; @@ -990,6 +1254,8 @@ builtin_variable_generator::generate_varyings() 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); } } @@ -1014,6 +1280,12 @@ _mesa_glsl_initialize_variables(exec_list *instructions, case MESA_SHADER_VERTEX: gen.generate_vs_special_vars(); break; + case MESA_SHADER_TESS_CTRL: + gen.generate_tcs_special_vars(); + break; + case MESA_SHADER_TESS_EVAL: + gen.generate_tes_special_vars(); + break; case MESA_SHADER_GEOMETRY: gen.generate_gs_special_vars(); break; @@ -1025,3 +1297,84 @@ _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(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); +}