summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorKristian Høgsberg Kristensen <[email protected]>2016-02-24 12:50:27 -0800
committerKristian Høgsberg Kristensen <[email protected]>2016-02-24 13:04:54 -0800
commit59f57289959702e528b68bdd0d06488089517a00 (patch)
treea266656ac6129f5ad14b9d0d0c69c7077466c3f3 /src/compiler
parent25c2470b24ce8411f6747eb887137b2511b6d529 (diff)
parentc95d5c5f6fbfe4a96276e67ed279562b33432fb5 (diff)
Merge remote-tracking branch 'origin/master' into vulkan
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/builtin_type_macros.h1
-rw-r--r--src/compiler/glsl/ast.h12
-rw-r--r--src/compiler/glsl/ast_function.cpp163
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp26
-rw-r--r--src/compiler/glsl/ast_type.cpp13
-rw-r--r--src/compiler/glsl/builtin_functions.cpp65
-rw-r--r--src/compiler/glsl/builtin_variables.cpp15
-rw-r--r--src/compiler/glsl/glcpp/glcpp-parse.y6
-rw-r--r--src/compiler/glsl/glsl_lexer.ll4
-rw-r--r--src/compiler/glsl/glsl_parser_extras.cpp32
-rw-r--r--src/compiler/glsl/glsl_parser_extras.h7
-rw-r--r--src/compiler/glsl/ir.cpp17
-rw-r--r--src/compiler/glsl/ir.h11
-rw-r--r--src/compiler/glsl/ir_clone.cpp2
-rw-r--r--src/compiler/glsl/link_uniform_initializers.cpp2
-rw-r--r--src/compiler/glsl/link_uniforms.cpp86
-rw-r--r--src/compiler/glsl/link_varyings.cpp23
-rw-r--r--src/compiler/glsl/linker.cpp70
-rw-r--r--src/compiler/glsl/linker.h17
-rw-r--r--src/compiler/glsl/lower_discard_flow.cpp4
-rw-r--r--src/compiler/glsl/main.cpp17
-rw-r--r--src/compiler/glsl/tests/sampler_types_test.cpp2
-rw-r--r--src/compiler/glsl/tests/uniform_initializer_utils.cpp3
-rw-r--r--src/compiler/glsl_types.cpp14
-rw-r--r--src/compiler/glsl_types.h4
-rw-r--r--src/compiler/nir_types.cpp9
-rw-r--r--src/compiler/nir_types.h1
27 files changed, 369 insertions, 257 deletions
diff --git a/src/compiler/builtin_type_macros.h b/src/compiler/builtin_type_macros.h
index 7bd2e4e6558..da3f19e7ab2 100644
--- a/src/compiler/builtin_type_macros.h
+++ b/src/compiler/builtin_type_macros.h
@@ -78,6 +78,7 @@ DECL_TYPE(dmat3x4, GL_DOUBLE_MAT3x4, GLSL_TYPE_DOUBLE, 4, 3)
DECL_TYPE(dmat4x2, GL_DOUBLE_MAT4x2, GLSL_TYPE_DOUBLE, 2, 4)
DECL_TYPE(dmat4x3, GL_DOUBLE_MAT4x3, GLSL_TYPE_DOUBLE, 3, 4)
+DECL_TYPE(sampler, GL_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_VOID)
DECL_TYPE(sampler1D, GL_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT)
DECL_TYPE(sampler2D, GL_SAMPLER_2D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT)
DECL_TYPE(sampler3D, GL_SAMPLER_3D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT)
diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
index 03df6c08b2b..9aa5bb99f49 100644
--- a/src/compiler/glsl/ast.h
+++ b/src/compiler/glsl/ast.h
@@ -685,18 +685,6 @@ struct ast_type_qualifier {
*/
bool has_auxiliary_storage() const;
- /**
- * \brief Return string representation of interpolation qualifier.
- *
- * If an interpolation qualifier is present, then return that qualifier's
- * string representation. Otherwise, return null. For example, if the
- * noperspective bit is set, then this returns "noperspective".
- *
- * If multiple interpolation qualifiers are somehow present, then the
- * returned string is undefined but not null.
- */
- const char *interpolation_string() const;
-
bool merge_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
const ast_type_qualifier &q,
diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp
index c7fdcb24379..1a440203cfc 100644
--- a/src/compiler/glsl/ast_function.cpp
+++ b/src/compiler/glsl/ast_function.cpp
@@ -1405,9 +1405,9 @@ emit_inline_matrix_constructor(const glsl_type *type,
zero.d[i] = 0.0;
ir_instruction *inst =
- new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var),
- new(ctx) ir_constant(rhs_var->type, &zero),
- NULL);
+ new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var),
+ new(ctx) ir_constant(rhs_var->type, &zero),
+ NULL);
instructions->push_tail(inst);
ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
@@ -1422,36 +1422,36 @@ emit_inline_matrix_constructor(const glsl_type *type,
* columns than rows).
*/
static const unsigned rhs_swiz[4][4] = {
- { 0, 1, 1, 1 },
- { 1, 0, 1, 1 },
- { 1, 1, 0, 1 },
- { 1, 1, 1, 0 }
+ { 0, 1, 1, 1 },
+ { 1, 0, 1, 1 },
+ { 1, 1, 0, 1 },
+ { 1, 1, 1, 0 }
};
const unsigned cols_to_init = MIN2(type->matrix_columns,
- type->vector_elements);
+ type->vector_elements);
for (unsigned i = 0; i < cols_to_init; i++) {
- ir_constant *const col_idx = new(ctx) ir_constant(i);
- ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx);
+ ir_constant *const col_idx = new(ctx) ir_constant(i);
+ ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx);
- ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
- ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i],
- type->vector_elements);
+ ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
+ ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i],
+ type->vector_elements);
- inst = new(ctx) ir_assignment(col_ref, rhs, NULL);
- instructions->push_tail(inst);
+ inst = new(ctx) ir_assignment(col_ref, rhs, NULL);
+ instructions->push_tail(inst);
}
for (unsigned i = cols_to_init; i < type->matrix_columns; i++) {
- ir_constant *const col_idx = new(ctx) ir_constant(i);
- ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx);
+ ir_constant *const col_idx = new(ctx) ir_constant(i);
+ ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx);
- ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
- ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1,
- type->vector_elements);
+ ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
+ ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1,
+ type->vector_elements);
- inst = new(ctx) ir_assignment(col_ref, rhs, NULL);
- instructions->push_tail(inst);
+ inst = new(ctx) ir_assignment(col_ref, rhs, NULL);
+ instructions->push_tail(inst);
}
} else if (first_param->type->is_matrix()) {
/* From page 50 (56 of the PDF) of the GLSL 1.50 spec:
@@ -1469,36 +1469,43 @@ emit_inline_matrix_constructor(const glsl_type *type,
/* If the source matrix is smaller, pre-initialize the relavent parts of
* the destination matrix to the identity matrix.
*/
- if ((src_matrix->type->matrix_columns < var->type->matrix_columns)
- || (src_matrix->type->vector_elements < var->type->vector_elements)) {
-
- /* If the source matrix has fewer rows, every column of the destination
- * must be initialized. Otherwise only the columns in the destination
- * that do not exist in the source must be initialized.
- */
- unsigned col =
- (src_matrix->type->vector_elements < var->type->vector_elements)
- ? 0 : src_matrix->type->matrix_columns;
-
- const glsl_type *const col_type = var->type->column_type();
- for (/* empty */; col < var->type->matrix_columns; col++) {
- ir_constant_data ident;
+ if ((src_matrix->type->matrix_columns < var->type->matrix_columns) ||
+ (src_matrix->type->vector_elements < var->type->vector_elements)) {
- ident.f[0] = 0.0;
- ident.f[1] = 0.0;
- ident.f[2] = 0.0;
- ident.f[3] = 0.0;
-
- ident.f[col] = 1.0;
+ /* If the source matrix has fewer rows, every column of the destination
+ * must be initialized. Otherwise only the columns in the destination
+ * that do not exist in the source must be initialized.
+ */
+ unsigned col =
+ (src_matrix->type->vector_elements < var->type->vector_elements)
+ ? 0 : src_matrix->type->matrix_columns;
+
+ const glsl_type *const col_type = var->type->column_type();
+ for (/* empty */; col < var->type->matrix_columns; col++) {
+ ir_constant_data ident;
+
+ if (!col_type->is_double()) {
+ ident.f[0] = 0.0f;
+ ident.f[1] = 0.0f;
+ ident.f[2] = 0.0f;
+ ident.f[3] = 0.0f;
+ ident.f[col] = 1.0f;
+ } else {
+ ident.d[0] = 0.0;
+ ident.d[1] = 0.0;
+ ident.d[2] = 0.0;
+ ident.d[3] = 0.0;
+ ident.d[col] = 1.0;
+ }
- ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident);
+ ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident);
- ir_rvalue *const lhs =
- new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col));
+ ir_rvalue *const lhs =
+ new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col));
- ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL);
- instructions->push_tail(inst);
- }
+ ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL);
+ instructions->push_tail(inst);
+ }
}
/* Assign columns from the source matrix to the destination matrix.
@@ -1507,51 +1514,51 @@ emit_inline_matrix_constructor(const glsl_type *type,
* generate a temporary and copy the paramter there.
*/
ir_variable *const rhs_var =
- new(ctx) ir_variable(first_param->type, "mat_ctor_mat",
- ir_var_temporary);
+ new(ctx) ir_variable(first_param->type, "mat_ctor_mat",
+ ir_var_temporary);
instructions->push_tail(rhs_var);
ir_dereference *const rhs_var_ref =
- new(ctx) ir_dereference_variable(rhs_var);
+ new(ctx) ir_dereference_variable(rhs_var);
ir_instruction *const inst =
- new(ctx) ir_assignment(rhs_var_ref, first_param, NULL);
+ new(ctx) ir_assignment(rhs_var_ref, first_param, NULL);
instructions->push_tail(inst);
const unsigned last_row = MIN2(src_matrix->type->vector_elements,
- var->type->vector_elements);
+ var->type->vector_elements);
const unsigned last_col = MIN2(src_matrix->type->matrix_columns,
- var->type->matrix_columns);
+ var->type->matrix_columns);
unsigned swiz[4] = { 0, 0, 0, 0 };
for (unsigned i = 1; i < last_row; i++)
- swiz[i] = i;
+ swiz[i] = i;
- const unsigned write_mask = (1U << last_row) - 1;
+ const unsigned write_mask = (1U << last_row) - 1;
for (unsigned i = 0; i < last_col; i++) {
- ir_dereference *const lhs =
- new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i));
- ir_rvalue *const rhs_col =
- new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i));
-
- /* If one matrix has columns that are smaller than the columns of the
- * other matrix, wrap the column access of the larger with a swizzle
- * so that the LHS and RHS of the assignment have the same size (and
- * therefore have the same type).
- *
- * It would be perfectly valid to unconditionally generate the
- * swizzles, this this will typically result in a more compact IR tree.
- */
- ir_rvalue *rhs;
- if (lhs->type->vector_elements != rhs_col->type->vector_elements) {
- rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row);
- } else {
- rhs = rhs_col;
- }
+ ir_dereference *const lhs =
+ new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i));
+ ir_rvalue *const rhs_col =
+ new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i));
+
+ /* If one matrix has columns that are smaller than the columns of the
+ * other matrix, wrap the column access of the larger with a swizzle
+ * so that the LHS and RHS of the assignment have the same size (and
+ * therefore have the same type).
+ *
+ * It would be perfectly valid to unconditionally generate the
+ * swizzles, this this will typically result in a more compact IR tree.
+ */
+ ir_rvalue *rhs;
+ if (lhs->type->vector_elements != rhs_col->type->vector_elements) {
+ rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row);
+ } else {
+ rhs = rhs_col;
+ }
- ir_instruction *inst =
- new(ctx) ir_assignment(lhs, rhs, NULL, write_mask);
- instructions->push_tail(inst);
+ ir_instruction *inst =
+ new(ctx) ir_assignment(lhs, rhs, NULL, write_mask);
+ instructions->push_tail(inst);
}
} else {
const unsigned cols = type->matrix_columns;
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index 9e811661a2e..75abef6a8f9 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -1133,9 +1133,9 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_IMAGE:
case GLSL_TYPE_INTERFACE:
- case GLSL_TYPE_FUNCTION:
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_SUBROUTINE:
+ case GLSL_TYPE_FUNCTION:
/* I assume a comparison of a struct containing a sampler just
* ignores the sampler present in the type.
*/
@@ -2268,7 +2268,7 @@ get_type_name_for_precision_qualifier(const glsl_type *type)
type->sampler_array + 2 * type->sampler_shadow;
const unsigned offset = type->base_type == GLSL_TYPE_SAMPLER ? 0 : 4;
assert(type_idx < 4);
- switch (type->sampler_type) {
+ switch (type->sampled_type) {
case GLSL_TYPE_FLOAT:
switch (type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D: {
@@ -2750,6 +2750,17 @@ interpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
"vertex shader inputs or fragment shader outputs",
interpolation_string(interpolation));
}
+ } else if (state->es_shader &&
+ ((mode == ir_var_shader_in &&
+ state->stage != MESA_SHADER_VERTEX) ||
+ (mode == ir_var_shader_out &&
+ state->stage != MESA_SHADER_FRAGMENT))) {
+ /* Section 4.3.9 (Interpolation) of the GLSL ES 3.00 spec says:
+ *
+ * "When no interpolation qualifier is present, smooth interpolation
+ * is used."
+ */
+ interpolation = INTERP_QUALIFIER_SMOOTH;
}
return interpolation;
@@ -2954,7 +2965,7 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual,
"used on image function parameters");
}
- if (qual->image_base_type != base_type->sampler_type) {
+ if (qual->image_base_type != base_type->sampled_type) {
_mesa_glsl_error(loc, state, "format qualifier doesn't match the "
"base data type of the image");
}
@@ -4679,8 +4690,7 @@ ast_declarator_list::hir(exec_list *instructions,
&& this->type->qualifier.has_interpolation()
&& this->type->qualifier.flags.q.varying) {
- const char *i = this->type->qualifier.interpolation_string();
- assert(i != NULL);
+ const char *i = interpolation_string(var->data.interpolation);
const char *s;
if (this->type->qualifier.flags.q.centroid)
s = "centroid varying";
@@ -4710,9 +4720,7 @@ ast_declarator_list::hir(exec_list *instructions,
if (state->is_version(130, 300)
&& this->type->qualifier.has_interpolation()) {
- const char *i = this->type->qualifier.interpolation_string();
- assert(i != NULL);
-
+ const char *i = interpolation_string(var->data.interpolation);
switch (state->stage) {
case MESA_SHADER_VERTEX:
if (this->type->qualifier.flags.q.in) {
@@ -6259,7 +6267,7 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
decl_count);
bool first_member = true;
- bool first_member_has_explicit_location;
+ bool first_member_has_explicit_location = false;
unsigned i = 0;
foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp
index e0e331152dd..dcd83efa6ff 100644
--- a/src/compiler/glsl/ast_type.cpp
+++ b/src/compiler/glsl/ast_type.cpp
@@ -102,19 +102,6 @@ ast_type_qualifier::has_auxiliary_storage() const
|| this->flags.q.patch;
}
-const char*
-ast_type_qualifier::interpolation_string() const
-{
- if (this->flags.q.smooth)
- return "smooth";
- else if (this->flags.q.flat)
- return "flat";
- else if (this->flags.q.noperspective)
- return "noperspective";
- else
- return NULL;
-}
-
/**
* This function merges both duplicate identifies within a single layout and
* multiple layout qualifiers on a single variable declaration. The
diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
index 5512a33f114..bbb237a102c 100644
--- a/src/compiler/glsl/builtin_functions.cpp
+++ b/src/compiler/glsl/builtin_functions.cpp
@@ -448,8 +448,16 @@ shader_image_load_store(const _mesa_glsl_parse_state *state)
static bool
shader_image_atomic(const _mesa_glsl_parse_state *state)
{
- return (state->is_version(420, 0) ||
- state->ARB_shader_image_load_store_enable);
+ return (state->is_version(420, 320) ||
+ state->ARB_shader_image_load_store_enable ||
+ state->OES_shader_image_atomic_enable);
+}
+
+static bool
+shader_image_atomic_exchange_float(const _mesa_glsl_parse_state *state)
+{
+ return (state->is_version(450, 320) ||
+ state->OES_shader_image_atomic_enable);
}
static bool
@@ -577,17 +585,6 @@ private:
unsigned num_arguments,
unsigned flags);
- enum image_function_flags {
- IMAGE_FUNCTION_EMIT_STUB = (1 << 0),
- IMAGE_FUNCTION_RETURNS_VOID = (1 << 1),
- IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE = (1 << 2),
- IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE = (1 << 3),
- IMAGE_FUNCTION_READ_ONLY = (1 << 4),
- IMAGE_FUNCTION_WRITE_ONLY = (1 << 5),
- IMAGE_FUNCTION_AVAIL_ATOMIC = (1 << 6),
- IMAGE_FUNCTION_MS_ONLY = (1 << 7),
- };
-
/**
* Create a new image built-in function for all known image types.
* \p flags is a bitfield of \c image_function_flags flags.
@@ -836,6 +833,18 @@ private:
/** @} */
};
+enum image_function_flags {
+ IMAGE_FUNCTION_EMIT_STUB = (1 << 0),
+ IMAGE_FUNCTION_RETURNS_VOID = (1 << 1),
+ IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE = (1 << 2),
+ IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE = (1 << 3),
+ IMAGE_FUNCTION_READ_ONLY = (1 << 4),
+ IMAGE_FUNCTION_WRITE_ONLY = (1 << 5),
+ IMAGE_FUNCTION_AVAIL_ATOMIC = (1 << 6),
+ IMAGE_FUNCTION_MS_ONLY = (1 << 7),
+ IMAGE_FUNCTION_AVAIL_ATOMIC_EXCHANGE = (1 << 8)
+};
+
} /* anonymous namespace */
/**
@@ -2921,7 +2930,7 @@ builtin_builder::add_image_function(const char *name,
ir_function *f = new(mem_ctx) ir_function(name);
for (unsigned i = 0; i < ARRAY_SIZE(types); ++i) {
- if ((types[i]->sampler_type != GLSL_TYPE_FLOAT ||
+ if ((types[i]->sampled_type != GLSL_TYPE_FLOAT ||
(flags & IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE)) &&
(types[i]->sampler_dimensionality == GLSL_SAMPLER_DIM_MS ||
!(flags & IMAGE_FUNCTION_MS_ONLY)))
@@ -2981,7 +2990,9 @@ builtin_builder::add_image_functions(bool glsl)
add_image_function((glsl ? "imageAtomicExchange" :
"__intrinsic_image_atomic_exchange"),
"__intrinsic_image_atomic_exchange",
- &builtin_builder::_image_prototype, 1, atom_flags);
+ &builtin_builder::_image_prototype, 1,
+ (flags | IMAGE_FUNCTION_AVAIL_ATOMIC_EXCHANGE |
+ IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE));
add_image_function((glsl ? "imageAtomicCompSwap" :
"__intrinsic_image_atomic_comp_swap"),
@@ -5232,13 +5243,28 @@ builtin_builder::_mid3(const glsl_type *type)
return sig;
}
+static builtin_available_predicate
+get_image_available_predicate(const glsl_type *type, unsigned flags)
+{
+ if ((flags & IMAGE_FUNCTION_AVAIL_ATOMIC_EXCHANGE) &&
+ type->sampled_type == GLSL_TYPE_FLOAT)
+ return shader_image_atomic_exchange_float;
+
+ else if (flags & (IMAGE_FUNCTION_AVAIL_ATOMIC_EXCHANGE |
+ IMAGE_FUNCTION_AVAIL_ATOMIC))
+ return shader_image_atomic;
+
+ else
+ return shader_image_load_store;
+}
+
ir_function_signature *
builtin_builder::_image_prototype(const glsl_type *image_type,
unsigned num_arguments,
unsigned flags)
{
const glsl_type *data_type = glsl_type::get_instance(
- image_type->sampler_type,
+ image_type->sampled_type,
(flags & IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE ? 4 : 1),
1);
const glsl_type *ret_type = (flags & IMAGE_FUNCTION_RETURNS_VOID ?
@@ -5249,10 +5275,9 @@ builtin_builder::_image_prototype(const glsl_type *image_type,
ir_variable *coord = in_var(
glsl_type::ivec(image_type->coordinate_components()), "coord");
- const builtin_available_predicate avail =
- (flags & IMAGE_FUNCTION_AVAIL_ATOMIC ? shader_image_atomic :
- shader_image_load_store);
- ir_function_signature *sig = new_sig(ret_type, avail, 2, image, coord);
+ ir_function_signature *sig = new_sig(
+ ret_type, get_image_available_predicate(image_type, flags),
+ 2, image, coord);
/* Sample index for multisample images. */
if (image_type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS)
diff --git a/src/compiler/glsl/builtin_variables.cpp b/src/compiler/glsl/builtin_variables.cpp
index 6db74f1c634..d20fc4a816c 100644
--- a/src/compiler/glsl/builtin_variables.cpp
+++ b/src/compiler/glsl/builtin_variables.cpp
@@ -770,11 +770,16 @@ builtin_variable_generator::generate_constants()
}
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("gl_MaxComputeAtomicCounterBuffers",
+ state->Const.MaxComputeAtomicCounterBuffers);
+ add_const("gl_MaxComputeAtomicCounters",
+ state->Const.MaxComputeAtomicCounters);
+ add_const("gl_MaxComputeImageUniforms",
+ state->Const.MaxComputeImageUniforms);
+ add_const("gl_MaxComputeTextureImageUnits",
+ state->Const.MaxComputeTextureImageUnits);
+ add_const("gl_MaxComputeUniformComponents",
+ state->Const.MaxComputeUniformComponents);
add_const_ivec3("gl_MaxComputeWorkGroupCount",
state->Const.MaxComputeWorkGroupCount[0],
diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
index 43a1aa94aff..b03e1910758 100644
--- a/src/compiler/glsl/glcpp/glcpp-parse.y
+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
@@ -2096,6 +2096,9 @@ _check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
if (strncmp(identifier, "GL_", 3) == 0) {
glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n");
}
+ if (strcmp(identifier, "defined") == 0) {
+ glcpp_error (loc, parser, "\"defined\" cannot be used as a macro name");
+ }
}
static int
@@ -2388,6 +2391,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
add_builtin_define(parser, "GL_EXT_blend_func_extended", 1);
if (version >= 310) {
+ if (extensions->ARB_shader_image_load_store)
+ add_builtin_define(parser, "GL_OES_shader_image_atomic", 1);
+
if (extensions->OES_geometry_shader) {
add_builtin_define(parser, "GL_OES_geometry_point_size", 1);
add_builtin_define(parser, "GL_OES_geometry_shader", 1);
diff --git a/src/compiler/glsl/glsl_lexer.ll b/src/compiler/glsl/glsl_lexer.ll
index e59f93e10ef..9704fc7ac4f 100644
--- a/src/compiler/glsl/glsl_lexer.ll
+++ b/src/compiler/glsl/glsl_lexer.ll
@@ -113,11 +113,7 @@ literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
if (base == 16)
digits += 2;
-#ifdef _MSC_VER
- unsigned __int64 value = _strtoui64(digits, NULL, base);
-#else
unsigned long long value = strtoull(digits, NULL, base);
-#endif
lval->n = (int)value;
diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp
index 86cf091b4fe..8ccbefc3f71 100644
--- a/src/compiler/glsl/glsl_parser_extras.cpp
+++ b/src/compiler/glsl/glsl_parser_extras.cpp
@@ -120,6 +120,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->Const.MaxTessEvaluationAtomicCounters = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicCounters;
this->Const.MaxGeometryAtomicCounters = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters;
this->Const.MaxFragmentAtomicCounters = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters;
+ this->Const.MaxComputeAtomicCounters = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters;
this->Const.MaxCombinedAtomicCounters = ctx->Const.MaxCombinedAtomicCounters;
this->Const.MaxAtomicBufferBindings = ctx->Const.MaxAtomicBufferBindings;
this->Const.MaxVertexAtomicCounterBuffers =
@@ -132,6 +133,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers;
this->Const.MaxFragmentAtomicCounterBuffers =
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers;
+ this->Const.MaxComputeAtomicCounterBuffers =
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers;
this->Const.MaxCombinedAtomicCounterBuffers =
ctx->Const.MaxCombinedAtomicBuffers;
this->Const.MaxAtomicCounterBufferSize =
@@ -143,6 +146,9 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
for (unsigned i = 0; i < ARRAY_SIZE(this->Const.MaxComputeWorkGroupSize); i++)
this->Const.MaxComputeWorkGroupSize[i] = ctx->Const.MaxComputeWorkGroupSize[i];
+ this->Const.MaxComputeTextureImageUnits = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;
+ this->Const.MaxComputeUniformComponents = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents;
+
this->Const.MaxImageUnits = ctx->Const.MaxImageUnits;
this->Const.MaxCombinedShaderOutputResources = ctx->Const.MaxCombinedShaderOutputResources;
this->Const.MaxImageSamples = ctx->Const.MaxImageSamples;
@@ -151,6 +157,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->Const.MaxTessEvaluationImageUniforms = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxImageUniforms;
this->Const.MaxGeometryImageUniforms = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms;
this->Const.MaxFragmentImageUniforms = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms;
+ this->Const.MaxComputeImageUniforms = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms;
this->Const.MaxCombinedImageUniforms = ctx->Const.MaxCombinedImageUniforms;
/* ARB_viewport_array */
@@ -601,6 +608,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(OES_EGL_image_external, false, true, OES_EGL_image_external),
EXT(OES_geometry_point_size, false, true, OES_geometry_shader),
EXT(OES_geometry_shader, false, true, OES_geometry_shader),
+ EXT(OES_shader_image_atomic, false, true, ARB_shader_image_load_store),
EXT(OES_standard_derivatives, false, true, OES_standard_derivatives),
EXT(OES_texture_3D, false, true, dummy_true),
EXT(OES_texture_storage_multisample_2d_array, false, true, ARB_texture_multisample),
@@ -946,27 +954,11 @@ _mesa_ast_process_interface_block(YYLTYPE *locp,
"the interface block");
}
- /* From GLSL ES 3.0, chapter 4.3.7 "Interface Blocks":
- *
- * "GLSL ES 3.0 does not support interface blocks for shader inputs or
- * outputs."
- *
- * And from GLSL ES 3.0, chapter 4.6.1 "The invariant qualifier":.
- *
- * "Only variables output from a shader can be candidates for
- * invariance."
- *
- * From GLSL 4.40 and GLSL 1.50, section "Interface Blocks":
- *
- * "If optional qualifiers are used, they can include interpolation
- * qualifiers, auxiliary storage qualifiers, and storage qualifiers
- * and they must declare an input, output, or uniform member
- * consistent with the interface qualifier of the block"
- */
- if (qualifier.flags.q.invariant)
+ if (!(q.flags.q.in || q.flags.q.out) && qualifier.flags.q.invariant)
_mesa_glsl_error(locp, state,
- "invariant qualifiers cannot be used "
- "with interface blocks members");
+ "invariant qualifiers can be used only "
+ "in interface block members for shader "
+ "inputs or outputs");
}
}
diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h
index 4dacc2ac62b..86ec057f288 100644
--- a/src/compiler/glsl/glsl_parser_extras.h
+++ b/src/compiler/glsl/glsl_parser_extras.h
@@ -422,6 +422,11 @@ struct _mesa_glsl_parse_state {
unsigned MaxAtomicCounterBufferSize;
/* ARB_compute_shader */
+ unsigned MaxComputeAtomicCounterBuffers;
+ unsigned MaxComputeAtomicCounters;
+ unsigned MaxComputeImageUniforms;
+ unsigned MaxComputeTextureImageUnits;
+ unsigned MaxComputeUniformComponents;
unsigned MaxComputeWorkGroupCount[3];
unsigned MaxComputeWorkGroupSize[3];
@@ -588,6 +593,8 @@ struct _mesa_glsl_parse_state {
bool OES_geometry_point_size_warn;
bool OES_geometry_shader_enable;
bool OES_geometry_shader_warn;
+ bool OES_shader_image_atomic_enable;
+ bool OES_shader_image_atomic_warn;
bool OES_standard_derivatives_enable;
bool OES_standard_derivatives_warn;
bool OES_texture_3D_enable;
diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp
index 5debca32411..750f61744e7 100644
--- a/src/compiler/glsl/ir.cpp
+++ b/src/compiler/glsl/ir.cpp
@@ -1442,7 +1442,7 @@ ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
assert(sampler->type->base_type == GLSL_TYPE_SAMPLER);
assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS);
} else {
- assert(sampler->type->sampler_type == (int) type->base_type);
+ assert(sampler->type->sampled_type == (int) type->base_type);
if (sampler->type->sampler_shadow)
assert(type->vector_elements == 4 || type->vector_elements == 1);
else
@@ -1696,21 +1696,6 @@ interpolation_string(unsigned interpolation)
return "";
}
-
-glsl_interp_qualifier
-ir_variable::determine_interpolation_mode(bool flat_shade)
-{
- if (this->data.interpolation != INTERP_QUALIFIER_NONE)
- return (glsl_interp_qualifier) this->data.interpolation;
- int location = this->data.location;
- bool is_gl_Color =
- location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1;
- if (flat_shade && is_gl_Color)
- return INTERP_QUALIFIER_FLAT;
- else
- return INTERP_QUALIFIER_SMOOTH;
-}
-
const char *const ir_variable::warn_extension_table[] = {
"",
"GL_ARB_shader_stencil_export",
diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
index bf9b7caffae..93c893d36fe 100644
--- a/src/compiler/glsl/ir.h
+++ b/src/compiler/glsl/ir.h
@@ -432,17 +432,6 @@ public:
/**
- * Determine how this variable should be interpolated based on its
- * interpolation qualifier (if present), whether it is gl_Color or
- * gl_SecondaryColor, and whether flatshading is enabled in the current GL
- * state.
- *
- * The return value will always be either INTERP_QUALIFIER_SMOOTH,
- * INTERP_QUALIFIER_NOPERSPECTIVE, or INTERP_QUALIFIER_FLAT.
- */
- glsl_interp_qualifier determine_interpolation_mode(bool flat_shade);
-
- /**
* Determine whether or not a variable is part of a uniform or
* shader storage block.
*/
diff --git a/src/compiler/glsl/ir_clone.cpp b/src/compiler/glsl/ir_clone.cpp
index b32ec17f1af..43ffffb0a38 100644
--- a/src/compiler/glsl/ir_clone.cpp
+++ b/src/compiler/glsl/ir_clone.cpp
@@ -366,7 +366,6 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
return c;
}
- case GLSL_TYPE_FUNCTION:
case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_IMAGE:
case GLSL_TYPE_ATOMIC_UINT:
@@ -374,6 +373,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
case GLSL_TYPE_ERROR:
case GLSL_TYPE_SUBROUTINE:
case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_FUNCTION:
assert(!"Should not get here.");
break;
}
diff --git a/src/compiler/glsl/link_uniform_initializers.cpp b/src/compiler/glsl/link_uniform_initializers.cpp
index cdc1d3ac7be..3609f81771e 100644
--- a/src/compiler/glsl/link_uniform_initializers.cpp
+++ b/src/compiler/glsl/link_uniform_initializers.cpp
@@ -88,9 +88,9 @@ copy_constant_to_storage(union gl_constant_value *storage,
case GLSL_TYPE_IMAGE:
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_INTERFACE:
- case GLSL_TYPE_FUNCTION:
case GLSL_TYPE_VOID:
case GLSL_TYPE_SUBROUTINE:
+ case GLSL_TYPE_FUNCTION:
case GLSL_TYPE_ERROR:
/* All other types should have already been filtered by other
* paths in the caller.
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index 7072c16cb28..deaba94df1c 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -649,15 +649,15 @@ private:
current_var->data.image_write_only ? GL_WRITE_ONLY :
GL_READ_WRITE);
- for (unsigned j = 0; j < MAX2(1, uniform->array_elements); ++j)
- prog->_LinkedShaders[shader_type]->
- ImageAccess[this->next_image + j] = access;
+ const unsigned first = this->next_image;
/* Increment the image index by 1 for non-arrays and by the
* number of array elements for arrays.
*/
this->next_image += MAX2(1, uniform->array_elements);
+ for (unsigned i = first; i < MIN2(next_image, MAX_IMAGE_UNIFORMS); i++)
+ prog->_LinkedShaders[shader_type]->ImageAccess[i] = access;
}
}
@@ -1038,9 +1038,43 @@ assign_hidden_uniform_slot_id(const char *name, unsigned hidden_id,
uniform_size->map->put(hidden_uniform_start + hidden_id, name);
}
+/**
+ * Search through the list of empty blocks to find one that fits the current
+ * uniform.
+ */
+static int
+find_empty_block(struct gl_shader_program *prog,
+ struct gl_uniform_storage *uniform)
+{
+ const unsigned entries = MAX2(1, uniform->array_elements);
+
+ foreach_list_typed(struct empty_uniform_block, block, link,
+ &prog->EmptyUniformLocations) {
+ /* Found a block with enough slots to fit the uniform */
+ if (block->slots == entries) {
+ unsigned start = block->start;
+ exec_node_remove(&block->link);
+ ralloc_free(block);
+
+ return start;
+ /* Found a block with more slots than needed. It can still be used. */
+ } else if (block->slots > entries) {
+ unsigned start = block->start;
+ block->start += entries;
+ block->slots -= entries;
+
+ return start;
+ }
+ }
+
+ return -1;
+}
+
void
link_assign_uniform_locations(struct gl_shader_program *prog,
- unsigned int boolean_true)
+ unsigned int boolean_true,
+ unsigned int num_explicit_uniform_locs,
+ unsigned int max_uniform_locs)
{
ralloc_free(prog->UniformStorage);
prog->UniformStorage = NULL;
@@ -1131,6 +1165,9 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
parcel_out_uniform_storage parcel(prog, prog->UniformHash, uniforms, data);
+ unsigned total_entries = num_explicit_uniform_locs;
+ unsigned empty_locs = prog->NumUniformRemapTable - num_explicit_uniform_locs;
+
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
if (prog->_LinkedShaders[i] == NULL)
continue;
@@ -1194,21 +1231,44 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
/* how many new entries for this uniform? */
const unsigned entries = MAX2(1, uniforms[i].array_elements);
- /* resize remap table to fit new entries */
- prog->UniformRemapTable =
- reralloc(prog,
- prog->UniformRemapTable,
- gl_uniform_storage *,
- prog->NumUniformRemapTable + entries);
+ /* Find UniformRemapTable for empty blocks where we can fit this uniform. */
+ int chosen_location = -1;
+
+ if (empty_locs)
+ chosen_location = find_empty_block(prog, &uniforms[i]);
+
+ /* Add new entries to the total amount of entries. */
+ total_entries += entries;
+
+ if (chosen_location != -1) {
+ empty_locs -= entries;
+ } else {
+ chosen_location = prog->NumUniformRemapTable;
+
+ /* resize remap table to fit new entries */
+ prog->UniformRemapTable =
+ reralloc(prog,
+ prog->UniformRemapTable,
+ gl_uniform_storage *,
+ prog->NumUniformRemapTable + entries);
+ prog->NumUniformRemapTable += entries;
+ }
/* set pointers for this uniform */
for (unsigned j = 0; j < entries; j++)
- prog->UniformRemapTable[prog->NumUniformRemapTable+j] = &uniforms[i];
+ prog->UniformRemapTable[chosen_location + j] = &uniforms[i];
/* set the base location in remap table for the uniform */
- uniforms[i].remap_location = prog->NumUniformRemapTable;
+ uniforms[i].remap_location = chosen_location;
+ }
+
+ /* Verify that total amount of entries for explicit and implicit locations
+ * is less than MAX_UNIFORM_LOCATIONS.
+ */
- prog->NumUniformRemapTable += entries;
+ if (total_entries > max_uniform_locs) {
+ linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS"
+ "(%u > %u)", total_entries, max_uniform_locs);
}
/* Reserve all the explicit locations of the active subroutine uniforms. */
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index 590de174507..05cc1a2b7f8 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -1739,22 +1739,7 @@ assign_varying_locations(struct gl_context *ctx,
if (var && var->data.mode == ir_var_shader_in &&
var->data.is_unmatched_generic_inout) {
- if (prog->IsES) {
- /*
- * On Page 91 (Page 97 of the PDF) of the GLSL ES 1.0 spec:
- *
- * If the vertex shader declares but doesn't write to a
- * varying and the fragment shader declares and reads it,
- * is this an error?
- *
- * RESOLUTION: No.
- */
- linker_warning(prog, "%s shader varying %s not written "
- "by %s shader\n.",
- _mesa_shader_stage_to_string(consumer->Stage),
- var->name,
- _mesa_shader_stage_to_string(producer->Stage));
- } else if (prog->Version <= 120) {
+ if (!prog->IsES && prog->Version <= 120) {
/* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
*
* Only those varying variables used (i.e. read) in
@@ -1772,6 +1757,12 @@ assign_varying_locations(struct gl_context *ctx,
_mesa_shader_stage_to_string(consumer->Stage),
var->name,
_mesa_shader_stage_to_string(producer->Stage));
+ } else {
+ linker_warning(prog, "%s shader varying %s not written "
+ "by %s shader\n.",
+ _mesa_shader_stage_to_string(consumer->Stage),
+ var->name,
+ _mesa_shader_stage_to_string(producer->Stage));
}
}
}
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index bad1c1742b7..5326bfd4d68 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -3008,12 +3008,13 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
* for a variable, checks for overlaps between other uniforms using explicit
* locations.
*/
-static bool
+static int
reserve_explicit_locations(struct gl_shader_program *prog,
string_to_uint_map *map, ir_variable *var)
{
unsigned slots = var->type->uniform_locations();
unsigned max_loc = var->data.location + slots - 1;
+ unsigned return_value = slots;
/* Resize remap table if locations do not fit in the current one. */
if (max_loc + 1 > prog->NumUniformRemapTable) {
@@ -3024,7 +3025,7 @@ reserve_explicit_locations(struct gl_shader_program *prog,
if (!prog->UniformRemapTable) {
linker_error(prog, "Out of memory during linking.\n");
- return false;
+ return -1;
}
/* Initialize allocated space. */
@@ -3042,8 +3043,10 @@ reserve_explicit_locations(struct gl_shader_program *prog,
/* Possibly same uniform from a different stage, this is ok. */
unsigned hash_loc;
- if (map->get(hash_loc, var->name) && hash_loc == loc - i)
- continue;
+ if (map->get(hash_loc, var->name) && hash_loc == loc - i) {
+ return_value = 0;
+ continue;
+ }
/* ARB_explicit_uniform_location specification states:
*
@@ -3055,7 +3058,7 @@ reserve_explicit_locations(struct gl_shader_program *prog,
"location qualifier for uniform %s overlaps "
"previously used location\n",
var->name);
- return false;
+ return -1;
}
/* Initialize location as inactive before optimization
@@ -3067,7 +3070,7 @@ reserve_explicit_locations(struct gl_shader_program *prog,
/* Note, base location used for arrays. */
map->put(var->data.location, var->name);
- return true;
+ return return_value;
}
static bool
@@ -3128,12 +3131,12 @@ reserve_subroutine_explicit_locations(struct gl_shader_program *prog,
* any optimizations happen to handle also inactive uniforms and
* inactive array elements that may get trimmed away.
*/
-static void
+static int
check_explicit_uniform_locations(struct gl_context *ctx,
struct gl_shader_program *prog)
{
if (!ctx->Extensions.ARB_explicit_uniform_location)
- return;
+ return -1;
/* This map is used to detect if overlapping explicit locations
* occur with the same uniform (from different stage) or a different one.
@@ -3142,7 +3145,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
if (!uniform_map) {
linker_error(prog, "Out of memory during linking.\n");
- return;
+ return -1;
}
unsigned entries_total = 0;
@@ -3157,31 +3160,47 @@ check_explicit_uniform_locations(struct gl_context *ctx,
if (!var || var->data.mode != ir_var_uniform)
continue;
- entries_total += var->type->uniform_locations();
-
if (var->data.explicit_location) {
- bool ret;
+ bool ret = false;
if (var->type->without_array()->is_subroutine())
ret = reserve_subroutine_explicit_locations(prog, sh, var);
- else
- ret = reserve_explicit_locations(prog, uniform_map, var);
+ else {
+ int slots = reserve_explicit_locations(prog, uniform_map,
+ var);
+ if (slots != -1) {
+ ret = true;
+ entries_total += slots;
+ }
+ }
if (!ret) {
delete uniform_map;
- return;
+ return -1;
}
}
}
}
- /* Verify that total amount of entries for explicit and implicit locations
- * is less than MAX_UNIFORM_LOCATIONS.
- */
- if (entries_total >= ctx->Const.MaxUserAssignableUniformLocations) {
- linker_error(prog, "count of uniform locations >= MAX_UNIFORM_LOCATIONS"
- "(%u >= %u)", entries_total,
- ctx->Const.MaxUserAssignableUniformLocations);
+ exec_list_make_empty(&prog->EmptyUniformLocations);
+ struct empty_uniform_block *current_block = NULL;
+
+ for (unsigned i = 0; i < prog->NumUniformRemapTable; i++) {
+ /* We found empty space in UniformRemapTable. */
+ if (prog->UniformRemapTable[i] == NULL) {
+ /* We've found the beginning of a new continous block of empty slots */
+ if (!current_block || current_block->start + current_block->slots != i) {
+ current_block = rzalloc(prog, struct empty_uniform_block);
+ current_block->start = i;
+ exec_list_push_tail(&prog->EmptyUniformLocations,
+ &current_block->link);
+ }
+
+ /* The current block continues, so we simply increment its slots */
+ current_block->slots++;
+ }
}
+
delete uniform_map;
+ return entries_total;
}
static bool
@@ -4129,6 +4148,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
tfeedback_decl *tfeedback_decls = NULL;
unsigned num_tfeedback_decls = prog->TransformFeedback.NumVarying;
+ unsigned int num_explicit_uniform_locs = 0;
void *mem_ctx = ralloc_context(NULL); // temporary linker context
@@ -4310,7 +4330,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
last = i;
}
- check_explicit_uniform_locations(ctx, prog);
+ num_explicit_uniform_locs = check_explicit_uniform_locations(ctx, prog);
link_assign_subroutine_types(prog);
if (!prog->LinkStatus)
@@ -4541,7 +4561,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
update_array_sizes(prog);
- link_assign_uniform_locations(prog, ctx->Const.UniformBooleanTrue);
+ link_assign_uniform_locations(prog, ctx->Const.UniformBooleanTrue,
+ num_explicit_uniform_locs,
+ ctx->Const.MaxUserAssignableUniformLocations);
link_assign_atomic_counter_resources(ctx, prog);
store_fragdepth_layout(prog);
diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h
index c80be1c7e22..a60bb6ed087 100644
--- a/src/compiler/glsl/linker.h
+++ b/src/compiler/glsl/linker.h
@@ -35,7 +35,9 @@ link_invalidate_variable_locations(exec_list *ir);
extern void
link_assign_uniform_locations(struct gl_shader_program *prog,
- unsigned int boolean_true);
+ unsigned int boolean_true,
+ unsigned int num_explicit_uniform_locs,
+ unsigned int max_uniform_locs);
extern void
link_set_uniform_initializers(struct gl_shader_program *prog,
@@ -202,4 +204,17 @@ linker_error(gl_shader_program *prog, const char *fmt, ...);
void
linker_warning(gl_shader_program *prog, const char *fmt, ...);
+/**
+ * Sometimes there are empty slots left over in UniformRemapTable after we
+ * allocate slots to explicit locations. This struct represents a single
+ * continouous block of empty slots in UniformRemapTable.
+ */
+struct empty_uniform_block {
+ struct exec_node link;
+ /* The start location of the block */
+ unsigned start;
+ /* The number of slots in the block */
+ unsigned slots;
+};
+
#endif /* GLSL_LINKER_H */
diff --git a/src/compiler/glsl/lower_discard_flow.cpp b/src/compiler/glsl/lower_discard_flow.cpp
index 9d0a56b230d..9e3a7c05583 100644
--- a/src/compiler/glsl/lower_discard_flow.cpp
+++ b/src/compiler/glsl/lower_discard_flow.cpp
@@ -62,8 +62,8 @@ public:
{
}
+ ir_visitor_status visit(ir_loop_jump *ir);
ir_visitor_status visit_enter(ir_discard *ir);
- ir_visitor_status visit_enter(ir_loop_jump *ir);
ir_visitor_status visit_enter(ir_loop *ir);
ir_visitor_status visit_enter(ir_function_signature *ir);
@@ -76,7 +76,7 @@ public:
} /* anonymous namespace */
ir_visitor_status
-lower_discard_flow_visitor::visit_enter(ir_loop_jump *ir)
+lower_discard_flow_visitor::visit(ir_loop_jump *ir)
{
if (ir->mode != ir_loop_jump::jump_continue)
return visit_continue;
diff --git a/src/compiler/glsl/main.cpp b/src/compiler/glsl/main.cpp
index df93a013ede..d2535758e1a 100644
--- a/src/compiler/glsl/main.cpp
+++ b/src/compiler/glsl/main.cpp
@@ -58,10 +58,16 @@ initialize_context(struct gl_context *ctx, gl_api api)
ctx->Const.MaxComputeWorkGroupSize[1] = 1024;
ctx->Const.MaxComputeWorkGroupSize[2] = 64;
ctx->Const.MaxComputeWorkGroupInvocations = 1024;
+ ctx->Const.MaxComputeSharedMemorySize = 32768;
ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxCombinedUniformComponents = 1024;
ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */
ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = 8;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = 8;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms = 8;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformBlocks = 12;
switch (ctx->Const.GLSLVersion) {
case 100:
@@ -77,12 +83,14 @@ initialize_context(struct gl_context *ctx, gl_api api)
ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 128 * 4;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
ctx->Const.MaxCombinedTextureImageUnits;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 16 * 4;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
@@ -103,12 +111,14 @@ initialize_context(struct gl_context *ctx, gl_api api)
ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 512;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
ctx->Const.MaxCombinedTextureImageUnits;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 64;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
@@ -129,11 +139,13 @@ initialize_context(struct gl_context *ctx, gl_api api)
ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
@@ -153,17 +165,20 @@ initialize_context(struct gl_context *ctx, gl_api api)
ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents = 1024;
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents =
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
@@ -191,11 +206,13 @@ initialize_context(struct gl_context *ctx, gl_api api)
ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 224;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
diff --git a/src/compiler/glsl/tests/sampler_types_test.cpp b/src/compiler/glsl/tests/sampler_types_test.cpp
index 04dd65e6e8d..ef03158bba9 100644
--- a/src/compiler/glsl/tests/sampler_types_test.cpp
+++ b/src/compiler/glsl/tests/sampler_types_test.cpp
@@ -43,7 +43,7 @@ TEST(sampler_types, TYPE) \
const glsl_type *type = glsl_type::TYPE##_type; \
EXPECT_EQ(GLSL_TYPE_SAMPLER, type->base_type); \
EXPECT_EQ(DIM, type->sampler_dimensionality); \
- EXPECT_EQ(DATA_TYPE, type->sampler_type); \
+ EXPECT_EQ(DATA_TYPE, type->sampled_type); \
ARR; \
SHAD; \
EXPECT_EQ(COMPS, type->coordinate_components()); \
diff --git a/src/compiler/glsl/tests/uniform_initializer_utils.cpp b/src/compiler/glsl/tests/uniform_initializer_utils.cpp
index 5006387036f..ec64be18cb3 100644
--- a/src/compiler/glsl/tests/uniform_initializer_utils.cpp
+++ b/src/compiler/glsl/tests/uniform_initializer_utils.cpp
@@ -103,6 +103,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_SUBROUTINE:
+ case GLSL_TYPE_FUNCTION:
ASSERT_TRUE(false);
break;
}
@@ -136,6 +137,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_SUBROUTINE:
+ case GLSL_TYPE_FUNCTION:
ASSERT_TRUE(false);
break;
}
@@ -241,6 +243,7 @@ verify_data(gl_constant_value *storage, unsigned storage_array_size,
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_SUBROUTINE:
+ case GLSL_TYPE_FUNCTION:
ASSERT_TRUE(false);
break;
}
diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp
index d2eaec173b3..c549230a83c 100644
--- a/src/compiler/glsl_types.cpp
+++ b/src/compiler/glsl_types.cpp
@@ -51,7 +51,7 @@ glsl_type::glsl_type(GLenum gl_type,
gl_type(gl_type),
base_type(base_type),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0), interface_packing(0),
+ sampled_type(0), interface_packing(0),
vector_elements(vector_elements), matrix_columns(matrix_columns),
length(0)
{
@@ -75,7 +75,7 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type,
gl_type(gl_type),
base_type(base_type),
sampler_dimensionality(dim), sampler_shadow(shadow),
- sampler_array(array), sampler_type(type), interface_packing(0),
+ sampler_array(array), sampled_type(type), interface_packing(0),
length(0)
{
mtx_lock(&glsl_type::mutex);
@@ -101,7 +101,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
gl_type(0),
base_type(GLSL_TYPE_STRUCT),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0), interface_packing(0),
+ sampled_type(0), interface_packing(0),
vector_elements(0), matrix_columns(0),
length(num_fields)
{
@@ -141,7 +141,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
gl_type(0),
base_type(GLSL_TYPE_INTERFACE),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0), interface_packing((unsigned) packing),
+ sampled_type(0), interface_packing((unsigned) packing),
vector_elements(0), matrix_columns(0),
length(num_fields)
{
@@ -180,7 +180,7 @@ glsl_type::glsl_type(const glsl_type *return_type,
gl_type(0),
base_type(GLSL_TYPE_FUNCTION),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0), interface_packing(0),
+ sampled_type(0), interface_packing(0),
vector_elements(0), matrix_columns(0),
length(num_params)
{
@@ -212,7 +212,7 @@ glsl_type::glsl_type(const char *subroutine_name) :
gl_type(0),
base_type(GLSL_TYPE_SUBROUTINE),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0), interface_packing(0),
+ sampled_type(0), interface_packing(0),
vector_elements(1), matrix_columns(1),
length(0)
{
@@ -428,7 +428,7 @@ _mesa_glsl_release_types(void)
glsl_type::glsl_type(const glsl_type *array, unsigned length) :
base_type(GLSL_TYPE_ARRAY),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0), interface_packing(0),
+ sampled_type(0), interface_packing(0),
vector_elements(0), matrix_columns(0),
length(length), name(NULL)
{
diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h
index 5965cb2eedb..2f612d8857d 100644
--- a/src/compiler/glsl_types.h
+++ b/src/compiler/glsl_types.h
@@ -56,11 +56,11 @@ enum glsl_base_type {
GLSL_TYPE_IMAGE,
GLSL_TYPE_ATOMIC_UINT,
GLSL_TYPE_STRUCT,
- GLSL_TYPE_FUNCTION,
GLSL_TYPE_INTERFACE,
GLSL_TYPE_ARRAY,
GLSL_TYPE_VOID,
GLSL_TYPE_SUBROUTINE,
+ GLSL_TYPE_FUNCTION,
GLSL_TYPE_ERROR
};
@@ -122,7 +122,7 @@ struct glsl_type {
unsigned sampler_dimensionality:3; /**< \see glsl_sampler_dim */
unsigned sampler_shadow:1;
unsigned sampler_array:1;
- unsigned sampler_type:2; /**< Type of data returned using this
+ unsigned sampled_type:2; /**< Type of data returned using this
* sampler or image. Only \c
* GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
* and \c GLSL_TYPE_UINT are valid.
diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp
index 00703fe6f52..70e9cd397fc 100644
--- a/src/compiler/nir_types.cpp
+++ b/src/compiler/nir_types.cpp
@@ -148,7 +148,7 @@ glsl_base_type
glsl_get_sampler_result_type(const struct glsl_type *type)
{
assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
- return (glsl_base_type)type->sampler_type;
+ return (glsl_base_type)type->sampled_type;
}
unsigned
@@ -315,6 +315,12 @@ glsl_sampler_type(enum glsl_sampler_dim dim, bool is_shadow, bool is_array,
}
const struct glsl_type *
+glsl_bare_sampler_type()
+{
+ return glsl_type::sampler_type;
+}
+
+const struct glsl_type *
glsl_image_type(enum glsl_sampler_dim dim, bool is_array,
enum glsl_base_type base_type)
{
@@ -331,6 +337,7 @@ glsl_function_type(const glsl_type *return_type,
const glsl_type *
glsl_transposed_type(const struct glsl_type *type)
{
+ assert(glsl_type_is_matrix(type));
return glsl_type::get_instance(type->base_type, type->matrix_columns,
type->vector_elements);
}
diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h
index 4ef0dcf9a31..d92605bf4fb 100644
--- a/src/compiler/nir_types.h
+++ b/src/compiler/nir_types.h
@@ -113,6 +113,7 @@ const struct glsl_type *glsl_struct_type(const struct glsl_struct_field *fields,
const struct glsl_type *glsl_sampler_type(enum glsl_sampler_dim dim,
bool is_shadow, bool is_array,
enum glsl_base_type base_type);
+const struct glsl_type *glsl_bare_sampler_type();
const struct glsl_type *glsl_image_type(enum glsl_sampler_dim dim,
bool is_array,
enum glsl_base_type base_type);