aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/glsl_types.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/glsl_types.cpp')
-rw-r--r--mesalib/src/glsl/glsl_types.cpp241
1 files changed, 218 insertions, 23 deletions
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 0d2eb7cec..38b37a6a9 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -194,6 +194,22 @@ glsl_type::contains_integer() const
}
bool
+glsl_type::contains_double() const
+{
+ if (this->is_array()) {
+ return this->fields.array->contains_double();
+ } else if (this->is_record()) {
+ for (unsigned int i = 0; i < this->length; i++) {
+ if (this->fields.structure[i].type->contains_double())
+ return true;
+ }
+ return false;
+ } else {
+ return this->is_double();
+ }
+}
+
+bool
glsl_type::contains_opaque() const {
switch (base_type) {
case GLSL_TYPE_SAMPLER:
@@ -268,6 +284,8 @@ const glsl_type *glsl_type::get_base_type() const
return int_type;
case GLSL_TYPE_FLOAT:
return float_type;
+ case GLSL_TYPE_DOUBLE:
+ return double_type;
case GLSL_TYPE_BOOL:
return bool_type;
default:
@@ -292,6 +310,8 @@ const glsl_type *glsl_type::get_scalar_type() const
return int_type;
case GLSL_TYPE_FLOAT:
return float_type;
+ case GLSL_TYPE_DOUBLE:
+ return double_type;
case GLSL_TYPE_BOOL:
return bool_type;
default:
@@ -377,6 +397,17 @@ glsl_type::vec(unsigned components)
return ts[components - 1];
}
+const glsl_type *
+glsl_type::dvec(unsigned components)
+{
+ if (components == 0 || components > 4)
+ return error_type;
+
+ static const glsl_type *const ts[] = {
+ double_type, dvec2_type, dvec3_type, dvec4_type
+ };
+ return ts[components - 1];
+}
const glsl_type *
glsl_type::ivec(unsigned components)
@@ -436,13 +467,15 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
return ivec(rows);
case GLSL_TYPE_FLOAT:
return vec(rows);
+ case GLSL_TYPE_DOUBLE:
+ return dvec(rows);
case GLSL_TYPE_BOOL:
return bvec(rows);
default:
return error_type;
}
} else {
- if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
+ if ((base_type != GLSL_TYPE_FLOAT && base_type != GLSL_TYPE_DOUBLE) || (rows == 1))
return error_type;
/* GLSL matrix types are named mat{COLUMNS}x{ROWS}. Only the following
@@ -456,17 +489,32 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
*/
#define IDX(c,r) (((c-1)*3) + (r-1))
- switch (IDX(columns, rows)) {
- case IDX(2,2): return mat2_type;
- case IDX(2,3): return mat2x3_type;
- case IDX(2,4): return mat2x4_type;
- case IDX(3,2): return mat3x2_type;
- case IDX(3,3): return mat3_type;
- case IDX(3,4): return mat3x4_type;
- case IDX(4,2): return mat4x2_type;
- case IDX(4,3): return mat4x3_type;
- case IDX(4,4): return mat4_type;
- default: return error_type;
+ if (base_type == GLSL_TYPE_DOUBLE) {
+ switch (IDX(columns, rows)) {
+ case IDX(2,2): return dmat2_type;
+ case IDX(2,3): return dmat2x3_type;
+ case IDX(2,4): return dmat2x4_type;
+ case IDX(3,2): return dmat3x2_type;
+ case IDX(3,3): return dmat3_type;
+ case IDX(3,4): return dmat3x4_type;
+ case IDX(4,2): return dmat4x2_type;
+ case IDX(4,3): return dmat4x3_type;
+ case IDX(4,4): return dmat4_type;
+ default: return error_type;
+ }
+ } else {
+ switch (IDX(columns, rows)) {
+ case IDX(2,2): return mat2_type;
+ case IDX(2,3): return mat2x3_type;
+ case IDX(2,4): return mat2x4_type;
+ case IDX(3,2): return mat3x2_type;
+ case IDX(3,3): return mat3_type;
+ case IDX(3,4): return mat3x4_type;
+ case IDX(4,2): return mat4x2_type;
+ case IDX(4,3): return mat4x3_type;
+ case IDX(4,4): return mat4_type;
+ default: return error_type;
+ }
}
}
@@ -474,6 +522,117 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
return error_type;
}
+const glsl_type *
+glsl_type::get_sampler_instance(enum glsl_sampler_dim dim,
+ bool shadow,
+ bool array,
+ glsl_base_type type)
+{
+ switch (type) {
+ case GLSL_TYPE_FLOAT:
+ switch (dim) {
+ case GLSL_SAMPLER_DIM_1D:
+ if (shadow)
+ return (array ? sampler1DArrayShadow_type : sampler1DShadow_type);
+ else
+ return (array ? sampler1DArray_type : sampler1D_type);
+ case GLSL_SAMPLER_DIM_2D:
+ if (shadow)
+ return (array ? sampler2DArrayShadow_type : sampler2DShadow_type);
+ else
+ return (array ? sampler2DArray_type : sampler2D_type);
+ case GLSL_SAMPLER_DIM_3D:
+ if (shadow || array)
+ return error_type;
+ else
+ return sampler3D_type;
+ case GLSL_SAMPLER_DIM_CUBE:
+ if (shadow)
+ return (array ? samplerCubeArrayShadow_type : samplerCubeShadow_type);
+ else
+ return (array ? samplerCubeArray_type : samplerCube_type);
+ case GLSL_SAMPLER_DIM_RECT:
+ if (array)
+ return error_type;
+ if (shadow)
+ return sampler2DRectShadow_type;
+ else
+ return sampler2DRect_type;
+ case GLSL_SAMPLER_DIM_BUF:
+ if (shadow || array)
+ return error_type;
+ else
+ return samplerBuffer_type;
+ case GLSL_SAMPLER_DIM_MS:
+ if (shadow)
+ return error_type;
+ return (array ? sampler2DMSArray_type : sampler2DMS_type);
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ if (shadow || array)
+ return error_type;
+ else
+ return samplerExternalOES_type;
+ }
+ case GLSL_TYPE_INT:
+ if (shadow)
+ return error_type;
+ switch (dim) {
+ case GLSL_SAMPLER_DIM_1D:
+ return (array ? isampler1DArray_type : isampler1D_type);
+ case GLSL_SAMPLER_DIM_2D:
+ return (array ? isampler2DArray_type : isampler2D_type);
+ case GLSL_SAMPLER_DIM_3D:
+ if (array)
+ return error_type;
+ return isampler3D_type;
+ case GLSL_SAMPLER_DIM_CUBE:
+ return (array ? isamplerCubeArray_type : isamplerCube_type);
+ case GLSL_SAMPLER_DIM_RECT:
+ if (array)
+ return error_type;
+ return isampler2DRect_type;
+ case GLSL_SAMPLER_DIM_BUF:
+ if (array)
+ return error_type;
+ return isamplerBuffer_type;
+ case GLSL_SAMPLER_DIM_MS:
+ return (array ? isampler2DMSArray_type : isampler2DMS_type);
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ return error_type;
+ }
+ case GLSL_TYPE_UINT:
+ if (shadow)
+ return error_type;
+ switch (dim) {
+ case GLSL_SAMPLER_DIM_1D:
+ return (array ? usampler1DArray_type : usampler1D_type);
+ case GLSL_SAMPLER_DIM_2D:
+ return (array ? usampler2DArray_type : usampler2D_type);
+ case GLSL_SAMPLER_DIM_3D:
+ if (array)
+ return error_type;
+ return usampler3D_type;
+ case GLSL_SAMPLER_DIM_CUBE:
+ return (array ? usamplerCubeArray_type : usamplerCube_type);
+ case GLSL_SAMPLER_DIM_RECT:
+ if (array)
+ return error_type;
+ return usampler2DRect_type;
+ case GLSL_SAMPLER_DIM_BUF:
+ if (array)
+ return error_type;
+ return usamplerBuffer_type;
+ case GLSL_SAMPLER_DIM_MS:
+ return (array ? usampler2DMSArray_type : usampler2DMS_type);
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ return error_type;
+ }
+ default:
+ return error_type;
+ }
+
+ unreachable("switch statement above should be complete");
+}
const glsl_type *
glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
@@ -707,6 +866,9 @@ glsl_type::component_slots() const
case GLSL_TYPE_BOOL:
return this->components();
+ case GLSL_TYPE_DOUBLE:
+ return 2 * this->components();
+
case GLSL_TYPE_STRUCT:
case GLSL_TYPE_INTERFACE: {
unsigned size = 0;
@@ -742,6 +904,7 @@ glsl_type::uniform_locations() const
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_DOUBLE:
case GLSL_TYPE_BOOL:
case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_IMAGE:
@@ -786,12 +949,26 @@ glsl_type::can_implicitly_convert_to(const glsl_type *desired,
desired->base_type == GLSL_TYPE_UINT && this->base_type == GLSL_TYPE_INT)
return true;
+ /* No implicit conversions from double. */
+ if ((!state || state->has_double()) && this->is_double())
+ return false;
+
+ /* Conversions from different types to double. */
+ if ((!state || state->has_double()) && desired->is_double()) {
+ if (this->is_float())
+ return true;
+ if (this->is_integer())
+ return true;
+ }
+
return false;
}
unsigned
glsl_type::std140_base_alignment(bool row_major) const
{
+ unsigned N = is_double() ? 8 : 4;
+
/* (1) If the member is a scalar consuming <N> basic machine units, the
* base alignment is <N>.
*
@@ -805,12 +982,12 @@ glsl_type::std140_base_alignment(bool row_major) const
if (this->is_scalar() || this->is_vector()) {
switch (this->vector_elements) {
case 1:
- return 4;
+ return N;
case 2:
- return 8;
+ return 2 * N;
case 3:
case 4:
- return 16;
+ return 4 * N;
}
}
@@ -859,10 +1036,10 @@ glsl_type::std140_base_alignment(bool row_major) const
int r = this->vector_elements;
if (row_major) {
- vec_type = get_instance(GLSL_TYPE_FLOAT, c, 1);
+ vec_type = get_instance(base_type, c, 1);
array_type = glsl_type::get_array_instance(vec_type, r);
} else {
- vec_type = get_instance(GLSL_TYPE_FLOAT, r, 1);
+ vec_type = get_instance(base_type, r, 1);
array_type = glsl_type::get_array_instance(vec_type, c);
}
@@ -900,6 +1077,15 @@ glsl_type::std140_base_alignment(bool row_major) const
return base_alignment;
}
+ /* A sampler may never occur in a UBO (without bindless of some sort),
+ * however it is convenient to use this alignment function even with
+ * regular uniforms. This allows use of this function on uniform structs
+ * that contain samplers.
+ */
+ if (this->is_sampler()) {
+ return 0;
+ }
+
assert(!"not reached");
return -1;
}
@@ -907,6 +1093,8 @@ glsl_type::std140_base_alignment(bool row_major) const
unsigned
glsl_type::std140_size(bool row_major) const
{
+ unsigned N = is_double() ? 8 : 4;
+
/* (1) If the member is a scalar consuming <N> basic machine units, the
* base alignment is <N>.
*
@@ -918,7 +1106,7 @@ glsl_type::std140_size(bool row_major) const
* <N> basic machine units, the base alignment is 4<N>.
*/
if (this->is_scalar() || this->is_vector()) {
- return this->vector_elements * 4;
+ return this->vector_elements * N;
}
/* (5) If the member is a column-major matrix with <C> columns and
@@ -953,11 +1141,12 @@ glsl_type::std140_size(bool row_major) const
}
if (row_major) {
- vec_type = get_instance(GLSL_TYPE_FLOAT,
- element_type->matrix_columns, 1);
+ vec_type = get_instance(element_type->base_type,
+ element_type->matrix_columns, 1);
+
array_len *= element_type->vector_elements;
} else {
- vec_type = get_instance(GLSL_TYPE_FLOAT,
+ vec_type = get_instance(element_type->base_type,
element_type->vector_elements, 1);
array_len *= element_type->matrix_columns;
}
@@ -1060,6 +1249,7 @@ glsl_type::count_attribute_slots() const
case GLSL_TYPE_INT:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_BOOL:
+ case GLSL_TYPE_DOUBLE:
return this->matrix_columns;
case GLSL_TYPE_STRUCT:
@@ -1114,8 +1304,13 @@ glsl_type::coordinate_components() const
break;
}
- /* Array textures need an additional component for the array index. */
- if (sampler_array)
+ /* Array textures need an additional component for the array index, except
+ * for cubemap array images that behave like a 2D array of interleaved
+ * cubemap faces.
+ */
+ if (sampler_array &&
+ !(base_type == GLSL_TYPE_IMAGE &&
+ sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE))
size += 1;
return size;