summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2015-02-05 12:04:58 +0200
committerIlia Mirkin <[email protected]>2015-02-19 00:28:34 -0500
commitba3bab264d039926be391dcd6020dbf1c6313c41 (patch)
treef1784f9ee19daa60b57928df87ff6e7e9e250321
parent24626444c3a21b984d023feba1843776c7f5c7ea (diff)
glsl/ast: Support double floats
Signed-off-by: Dave Airlie <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]>
-rw-r--r--src/glsl/ast.h2
-rw-r--r--src/glsl/ast_function.cpp66
-rw-r--r--src/glsl/ast_to_hir.cpp33
-rw-r--r--src/glsl/glsl_parser_extras.cpp4
4 files changed, 90 insertions, 15 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 6995ae83b91..ef74e5137b2 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -189,6 +189,7 @@ enum ast_operators {
ast_uint_constant,
ast_float_constant,
ast_bool_constant,
+ ast_double_constant,
ast_sequence,
ast_aggregate
@@ -236,6 +237,7 @@ public:
float float_constant;
unsigned uint_constant;
int bool_constant;
+ double double_constant;
} primary_expression;
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 151b0825ea9..918be6966d5 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -573,6 +573,9 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
result = new(ctx) ir_expression(ir_unop_i2u,
new(ctx) ir_expression(ir_unop_b2i, src));
break;
+ case GLSL_TYPE_DOUBLE:
+ result = new(ctx) ir_expression(ir_unop_d2u, src);
+ break;
}
break;
case GLSL_TYPE_INT:
@@ -586,6 +589,9 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
case GLSL_TYPE_BOOL:
result = new(ctx) ir_expression(ir_unop_b2i, src);
break;
+ case GLSL_TYPE_DOUBLE:
+ result = new(ctx) ir_expression(ir_unop_d2i, src);
+ break;
}
break;
case GLSL_TYPE_FLOAT:
@@ -599,6 +605,9 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
case GLSL_TYPE_BOOL:
result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL);
break;
+ case GLSL_TYPE_DOUBLE:
+ result = new(ctx) ir_expression(ir_unop_d2f, desired_type, src, NULL);
+ break;
}
break;
case GLSL_TYPE_BOOL:
@@ -613,8 +622,27 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
case GLSL_TYPE_FLOAT:
result = new(ctx) ir_expression(ir_unop_f2b, desired_type, src, NULL);
break;
+ case GLSL_TYPE_DOUBLE:
+ result = new(ctx) ir_expression(ir_unop_d2b, desired_type, src, NULL);
+ break;
}
break;
+ case GLSL_TYPE_DOUBLE:
+ switch (b) {
+ case GLSL_TYPE_INT:
+ result = new(ctx) ir_expression(ir_unop_i2d, src);
+ break;
+ case GLSL_TYPE_UINT:
+ result = new(ctx) ir_expression(ir_unop_u2d, src);
+ break;
+ case GLSL_TYPE_BOOL:
+ result = new(ctx) ir_expression(ir_unop_f2d,
+ new(ctx) ir_expression(ir_unop_b2f, src));
+ break;
+ case GLSL_TYPE_FLOAT:
+ result = new(ctx) ir_expression(ir_unop_f2d, desired_type, src, NULL);
+ break;
+ }
}
assert(result != NULL);
@@ -711,9 +739,9 @@ process_vec_mat_constructor(exec_list *instructions,
/* Apply implicit conversions (not the scalar constructor rules!). See
* the spec quote above. */
- if (constructor_type->is_float()) {
+ if (constructor_type->base_type != result->type->base_type) {
const glsl_type *desired_type =
- glsl_type::get_instance(GLSL_TYPE_FLOAT,
+ glsl_type::get_instance(constructor_type->base_type,
ir->type->vector_elements,
ir->type->matrix_columns);
if (result->type->can_implicitly_convert_to(desired_type, state)) {
@@ -847,13 +875,17 @@ process_array_constructor(exec_list *instructions,
foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
ir_rvalue *result = ir;
+ const glsl_base_type element_base_type =
+ constructor_type->element_type()->base_type;
+
/* Apply implicit conversions (not the scalar constructor rules!). See
* the spec quote above. */
- if (constructor_type->element_type()->is_float()) {
- const glsl_type *desired_type =
- glsl_type::get_instance(GLSL_TYPE_FLOAT,
- ir->type->vector_elements,
- ir->type->matrix_columns);
+ if (element_base_type != result->type->base_type) {
+ const glsl_type *desired_type =
+ glsl_type::get_instance(element_base_type,
+ ir->type->vector_elements,
+ ir->type->matrix_columns);
+
if (result->type->can_implicitly_convert_to(desired_type, state)) {
/* Even though convert_component() implements the constructor
* conversion rules (not the implicit conversion rules), its safe
@@ -1012,6 +1044,9 @@ emit_inline_vector_constructor(const glsl_type *type,
case GLSL_TYPE_FLOAT:
data.f[i + base_component] = c->get_float_component(i);
break;
+ case GLSL_TYPE_DOUBLE:
+ data.d[i + base_component] = c->get_double_component(i);
+ break;
case GLSL_TYPE_BOOL:
data.b[i + base_component] = c->get_bool_component(i);
break;
@@ -1167,16 +1202,21 @@ emit_inline_matrix_constructor(const glsl_type *type,
/* Assign the scalar to the X component of a vec4, and fill the remaining
* components with zero.
*/
+ glsl_base_type param_base_type = first_param->type->base_type;
+ assert(param_base_type == GLSL_TYPE_FLOAT ||
+ param_base_type == GLSL_TYPE_DOUBLE);
ir_variable *rhs_var =
- new(ctx) ir_variable(glsl_type::vec4_type, "mat_ctor_vec",
- ir_var_temporary);
+ new(ctx) ir_variable(glsl_type::get_instance(param_base_type, 4, 1),
+ "mat_ctor_vec",
+ ir_var_temporary);
instructions->push_tail(rhs_var);
ir_constant_data zero;
- zero.f[0] = 0.0;
- zero.f[1] = 0.0;
- zero.f[2] = 0.0;
- zero.f[3] = 0.0;
+ for (unsigned i = 0; i < 4; i++)
+ if (param_base_type == GLSL_TYPE_FLOAT)
+ zero.f[i] = 0.0;
+ else
+ zero.d[i] = 0.0;
ir_instruction *inst =
new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var),
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index ed0eb0982dd..7034ff02fe6 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -172,6 +172,7 @@ get_conversion_operation(const glsl_type *to, const glsl_type *from,
switch (from->base_type) {
case GLSL_TYPE_INT: return ir_unop_i2f;
case GLSL_TYPE_UINT: return ir_unop_u2f;
+ case GLSL_TYPE_DOUBLE: return ir_unop_d2f;
default: return (ir_expression_operation)0;
}
@@ -183,6 +184,16 @@ get_conversion_operation(const glsl_type *to, const glsl_type *from,
default: return (ir_expression_operation)0;
}
+ case GLSL_TYPE_DOUBLE:
+ if (!state->has_double())
+ return (ir_expression_operation)0;
+ switch (from->base_type) {
+ case GLSL_TYPE_INT: return ir_unop_i2d;
+ case GLSL_TYPE_UINT: return ir_unop_u2d;
+ case GLSL_TYPE_FLOAT: return ir_unop_f2d;
+ default: return (ir_expression_operation)0;
+ }
+
default: return (ir_expression_operation)0;
}
}
@@ -340,8 +351,10 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
* type of both operands must be float.
*/
assert(type_a->is_matrix() || type_b->is_matrix());
- assert(type_a->base_type == GLSL_TYPE_FLOAT);
- assert(type_b->base_type == GLSL_TYPE_FLOAT);
+ assert(type_a->base_type == GLSL_TYPE_FLOAT ||
+ type_a->base_type == GLSL_TYPE_DOUBLE);
+ assert(type_b->base_type == GLSL_TYPE_FLOAT ||
+ type_b->base_type == GLSL_TYPE_DOUBLE);
/* "* The operator is add (+), subtract (-), or divide (/), and the
* operands are matrices with the same number of rows and the same
@@ -959,6 +972,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
case GLSL_TYPE_BOOL:
+ case GLSL_TYPE_DOUBLE:
return new(mem_ctx) ir_expression(operation, op0, op1);
case GLSL_TYPE_ARRAY: {
@@ -1746,6 +1760,10 @@ ast_expression::do_hir(exec_list *instructions,
result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
break;
+ case ast_double_constant:
+ result = new(ctx) ir_constant(this->primary_expression.double_constant);
+ break;
+
case ast_sequence: {
/* It should not be possible to generate a sequence in the AST without
* any expressions in it.
@@ -2560,6 +2578,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
_mesa_glsl_error(loc, state,
"varying variables may not be of type struct");
break;
+ case GLSL_TYPE_DOUBLE:
+ break;
default:
_mesa_glsl_error(loc, state, "illegal type for a varying variable");
break;
@@ -3645,6 +3665,15 @@ ast_declarator_list::hir(exec_list *instructions,
var_type);
}
+ /* Double fragment inputs must be qualified with 'flat'. */
+ if (var->type->contains_double() &&
+ var->data.interpolation != INTERP_QUALIFIER_FLAT &&
+ state->stage == MESA_SHADER_FRAGMENT &&
+ var->data.mode == ir_var_shader_in) {
+ _mesa_glsl_error(&loc, state, "if a fragment input is (or contains) "
+ "a double, then it must be qualified with 'flat'",
+ var_type);
+ }
/* Interpolation qualifiers cannot be applied to 'centroid' and
* 'centroid varying'.
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index cb19ce15cb0..29e6dd2ff7d 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -962,6 +962,10 @@ ast_expression::print(void) const
printf("%f ", primary_expression.float_constant);
break;
+ case ast_double_constant:
+ printf("%f ", primary_expression.double_constant);
+ break;
+
case ast_bool_constant:
printf("%s ",
primary_expression.bool_constant