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:
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:
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:
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);
/* 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)) {
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
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;
/* 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),
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;
}
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;
}
}
* 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
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: {
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.
_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;
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'.