#include "main/shaderobj.h"
#include "ir.h"
#include "ir_builder.h"
+#include "builtin_functions.h"
using namespace ir_builder;
* (|). The operands must be of type signed or unsigned integers or
* integer vectors."
*/
- if (!type_a->is_integer()) {
+ if (!type_a->is_integer_32_64()) {
_mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
ast_expression::operator_string(op));
return glsl_type::error_type;
}
- if (!type_b->is_integer()) {
+ if (!type_b->is_integer_32_64()) {
_mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
ast_expression::operator_string(op));
return glsl_type::error_type;
* "The operator modulus (%) operates on signed or unsigned integers or
* integer vectors."
*/
- if (!type_a->is_integer()) {
+ if (!type_a->is_integer_32_64()) {
_mesa_glsl_error(loc, state, "LHS of operator %% must be an integer");
return glsl_type::error_type;
}
- if (!type_b->is_integer()) {
+ if (!type_b->is_integer_32_64()) {
_mesa_glsl_error(loc, state, "RHS of operator %% must be an integer");
return glsl_type::error_type;
}
* must be signed or unsigned integers or integer vectors. One operand
* can be signed while the other is unsigned."
*/
- if (!type_a->is_integer()) {
+ if (!type_a->is_integer_32_64()) {
_mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
"integer vector", ast_expression::operator_string(op));
return glsl_type::error_type;
error_emitted = true;
}
- if (!op[0]->type->is_integer()) {
+ if (!op[0]->type->is_integer_32_64()) {
_mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
error_emitted = true;
}
case GLSL_TYPE_SAMPLER: {
const unsigned type_idx =
type->sampler_array + 2 * type->sampler_shadow;
- const unsigned offset = type->base_type == GLSL_TYPE_SAMPLER ? 0 : 4;
+ const unsigned offset = type->is_sampler() ? 0 : 4;
assert(type_idx < 4);
switch (type->sampled_type) {
case GLSL_TYPE_FLOAT:
switch (type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"sampler1D", "sampler1DArray",
"sampler1DShadow", "sampler1DArrayShadow"
return names[offset + type_idx];
}
case GLSL_SAMPLER_DIM_MS: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"sampler2DMS", "sampler2DMSArray", NULL, NULL
};
return names[type_idx];
}
case GLSL_SAMPLER_DIM_RECT: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"samplerRect", NULL, "samplerRectShadow", NULL
};
return names[offset + type_idx];
}
case GLSL_SAMPLER_DIM_EXTERNAL: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"samplerExternalOES", NULL, NULL, NULL
};
case GLSL_TYPE_INT:
switch (type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"isampler1D", "isampler1DArray", NULL, NULL
};
return names[offset + type_idx];
}
case GLSL_SAMPLER_DIM_MS: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"isampler2DMS", "isampler2DMSArray", NULL, NULL
};
return names[type_idx];
}
case GLSL_SAMPLER_DIM_RECT: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"isamplerRect", NULL, "isamplerRectShadow", NULL
};
case GLSL_TYPE_UINT:
switch (type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"usampler1D", "usampler1DArray", NULL, NULL
};
return names[offset + type_idx];
}
case GLSL_SAMPLER_DIM_MS: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"usampler2DMS", "usampler2DMSArray", NULL, NULL
};
return names[type_idx];
}
case GLSL_SAMPLER_DIM_RECT: {
- assert(type->base_type == GLSL_TYPE_SAMPLER);
+ assert(type->is_sampler());
static const char *const names[4] = {
"usamplerRect", NULL, "usamplerRectShadow", NULL
};
/* Layout qualifiers for gl_FragDepth, which are enabled by extension
* AMD_conservative_depth.
*/
- int depth_layout_count = qual->flags.q.depth_any
- + qual->flags.q.depth_greater
- + qual->flags.q.depth_less
- + qual->flags.q.depth_unchanged;
- if (depth_layout_count > 0
+ if (qual->flags.q.depth_type
&& !state->is_version(420, 0)
&& !state->AMD_conservative_depth_enable
&& !state->ARB_conservative_depth_enable) {
"extension GL_AMD_conservative_depth or "
"GL_ARB_conservative_depth must be enabled "
"to use depth layout qualifiers");
- } else if (depth_layout_count > 0
+ } else if (qual->flags.q.depth_type
&& strcmp(var->name, "gl_FragDepth") != 0) {
_mesa_glsl_error(loc, state,
"depth layout qualifiers can be applied only to "
"gl_FragDepth");
- } else if (depth_layout_count > 1
- && strcmp(var->name, "gl_FragDepth") == 0) {
- _mesa_glsl_error(loc, state,
- "at most one depth layout qualifier can be applied to "
- "gl_FragDepth");
}
- if (qual->flags.q.depth_any)
+
+ switch (qual->depth_type) {
+ case ast_depth_any:
var->data.depth_layout = ir_depth_layout_any;
- else if (qual->flags.q.depth_greater)
+ break;
+ case ast_depth_greater:
var->data.depth_layout = ir_depth_layout_greater;
- else if (qual->flags.q.depth_less)
+ break;
+ case ast_depth_less:
var->data.depth_layout = ir_depth_layout_less;
- else if (qual->flags.q.depth_unchanged)
- var->data.depth_layout = ir_depth_layout_unchanged;
- else
- var->data.depth_layout = ir_depth_layout_none;
+ break;
+ case ast_depth_unchanged:
+ var->data.depth_layout = ir_depth_layout_unchanged;
+ break;
+ default:
+ var->data.depth_layout = ir_depth_layout_none;
+ break;
+ }
if (qual->flags.q.std140 ||
qual->flags.q.std430 ||
"varying variables may not be of type struct");
break;
case GLSL_TYPE_DOUBLE:
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_INT64:
break;
default:
_mesa_glsl_error(loc, state, "illegal type for a varying variable");
}
/**
- * Get the variable that is being redeclared by this declaration
+ * Get the variable that is being redeclared by this declaration or if it
+ * does not exist, the current declared variable.
*
* Semantic checks to verify the validity of the redeclaration are also
* performed. If semantic checks fail, compilation error will be emitted via
*
* \returns
* A pointer to an existing variable in the current scope if the declaration
- * is a redeclaration, \c NULL otherwise.
+ * is a redeclaration, current variable otherwise. \c is_declared boolean
+ * will return \c true if the declaration is a redeclaration, \c false
+ * otherwise.
*/
static ir_variable *
get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
struct _mesa_glsl_parse_state *state,
- bool allow_all_redeclarations)
+ bool allow_all_redeclarations,
+ bool *is_redeclaration)
{
/* Check if this declaration is actually a re-declaration, either to
* resize an array or add qualifiers to an existing variable.
if (earlier == NULL ||
(state->current_function != NULL &&
!state->symbols->name_declared_this_scope(var->name))) {
- return NULL;
+ *is_redeclaration = false;
+ return var;
}
+ *is_redeclaration = true;
/* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
*
if (var->data.patch)
return;
- var->data.tess_varying_implicit_sized_array = var->type->is_unsized_array();
-
validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
&state->tcs_output_size,
"tessellation control shader output");
if (var->type->is_unsized_array()) {
var->type = glsl_type::get_array_instance(var->type->fields.array,
state->Const.MaxPatchVertices);
- var->data.tess_varying_implicit_sized_array = true;
} else if (var->type->length != state->Const.MaxPatchVertices) {
_mesa_glsl_error(&loc, state,
"per-vertex tessellation shader input arrays must be "
if ((var->data.mode == ir_var_auto || var->data.mode == ir_var_temporary)
&& (var->type->is_numeric() || var->type->is_boolean())
&& state->zero_init) {
- const ir_constant_data data = {0};
+ const ir_constant_data data = { { 0 } };
var->data.has_initializer = true;
var->constant_initializer = new(var) ir_constant(var->type, &data);
}
switch (check_type->base_type) {
case GLSL_TYPE_FLOAT:
break;
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_INT64:
+ break;
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
if (state->is_version(120, 300))
/* Examine var name here since var may get deleted in the next call */
bool var_is_gl_id = is_gl_identifier(var->name);
- ir_variable *earlier =
+ bool is_redeclaration;
+ ir_variable *declared_var =
get_variable_being_redeclared(var, decl->get_location(), state,
- false /* allow_all_redeclarations */);
- if (earlier != NULL) {
+ false /* allow_all_redeclarations */,
+ &is_redeclaration);
+ if (is_redeclaration) {
if (var_is_gl_id &&
- earlier->data.how_declared == ir_var_declared_in_block) {
+ declared_var->data.how_declared == ir_var_declared_in_block) {
_mesa_glsl_error(&loc, state,
"`%s' has already been redeclared using "
- "gl_PerVertex", earlier->name);
+ "gl_PerVertex", declared_var->name);
}
- earlier->data.how_declared = ir_var_declared_normally;
+ declared_var->data.how_declared = ir_var_declared_normally;
}
if (decl->initializer != NULL) {
- result = process_initializer((earlier == NULL) ? var : earlier,
+ result = process_initializer(declared_var,
decl, this->type,
&initializer_instructions, state);
} else {
}
if (state->es_shader) {
- const glsl_type *const t = (earlier == NULL)
- ? var->type : earlier->type;
+ const glsl_type *const t = declared_var->type;
/* Skip the unsized array check for TCS/TES/GS inputs & TCS outputs.
*
* present, as per the following table."
*/
const bool implicitly_sized =
- (var->data.mode == ir_var_shader_in &&
+ (declared_var->data.mode == ir_var_shader_in &&
state->stage >= MESA_SHADER_TESS_CTRL &&
state->stage <= MESA_SHADER_GEOMETRY) ||
- (var->data.mode == ir_var_shader_out &&
+ (declared_var->data.mode == ir_var_shader_out &&
state->stage == MESA_SHADER_TESS_CTRL);
if (t->is_unsized_array() && !implicitly_sized)
* semantic checks that must be applied. In addition, variable that was
* created for the declaration should be added to the IR stream.
*/
- if (earlier == NULL) {
+ if (!is_redeclaration) {
validate_identifier(decl->identifier, loc, state);
/* Add the variable to the symbol table. Note that the initializer's
* after the initializer if present or immediately after the name
* being declared if not."
*/
- if (!state->symbols->add_variable(var)) {
+ if (!state->symbols->add_variable(declared_var)) {
YYLTYPE loc = this->get_location();
_mesa_glsl_error(&loc, state, "name `%s' already taken in the "
"current scope", decl->identifier);
* global var is decled, then the function is defined with usage of
* the global var. See glslparsertest's CorrectModule.frag.
*/
- instructions->push_head(var);
+ instructions->push_head(declared_var);
}
instructions->append_list(&initializer_instructions);
bool var_is_gl_id = is_gl_identifier(var->name);
if (redeclaring_per_vertex) {
- ir_variable *earlier =
+ bool is_redeclaration;
+ ir_variable *declared_var =
get_variable_being_redeclared(var, loc, state,
- true /* allow_all_redeclarations */);
- if (!var_is_gl_id || earlier == NULL) {
+ true /* allow_all_redeclarations */,
+ &is_redeclaration);
+ if (!var_is_gl_id || !is_redeclaration) {
_mesa_glsl_error(&loc, state,
"redeclaration of gl_PerVertex can only "
"include built-in variables");
- } else if (earlier->data.how_declared == ir_var_declared_normally) {
+ } else if (declared_var->data.how_declared == ir_var_declared_normally) {
_mesa_glsl_error(&loc, state,
"`%s' has already been redeclared",
- earlier->name);
+ declared_var->name);
} else {
- earlier->data.how_declared = ir_var_declared_in_block;
- earlier->reinit_interface_type(block_type);
+ declared_var->data.how_declared = ir_var_declared_in_block;
+ declared_var->reinit_interface_type(block_type);
}
continue;
}
}
if (var->type->is_unsized_array()) {
- if (var->is_in_shader_storage_block()) {
- if (is_unsized_array_last_element(var)) {
- var->data.from_ssbo_unsized_array = true;
- }
+ if (var->is_in_shader_storage_block() &&
+ is_unsized_array_last_element(var)) {
+ var->data.from_ssbo_unsized_array = true;
} else {
/* From GLSL ES 3.10 spec, section 4.1.9 "Arrays":
*
* block and the size is not specified at compile-time, it is
* sized at run-time. In all other cases, arrays are sized only
* at compile-time."
+ *
+ * In desktop GLSL it is allowed to have unsized-arrays that are
+ * not last, as long as we can determine that they are implicitly
+ * sized.
*/
if (state->es_shader) {
_mesa_glsl_error(&loc, state, "unsized array `%s' "