…
i++; // compile-time error, undefined behavior
}
The following example is similar:
bool p = … // non-uniform condition.
uniform a = …, b = …;
uniform c = p ? a : b; // compile-time error, undefined behavior
2.13.3
Uniform Control Flow
When a control flow conditional test is based on a uniform quantity, all program instances follow
the same path at that conditional test in a function. Code for control flow based on uniform
quantities should be more efficient than code for control flow based on non-uniform quantities.
2.14 Type Conversions and Re-interpreting Data
The
static_cast
operator is used to convert from a scalar or vector type to another scalar or
vector type with no saturation and with a default rounding mode (i.e., when converting to
floating-point, round to nearest even; when converting to integer, round toward zero). If the
source type is a scalar or vector boolean, the value
false
is converted to zero and the value
true
is converted to one.
Metal adds an
as_type
operator to allow any scalar or vector data type (that is not a
pointer) to be reinterpreted as another scalar or vector data type of the same size. The bits in
the operand are returned directly without modification as the new type. The usual type
promotion for function arguments is not performed.
For example,
as_type(0x3f800000)
returns
1.0f
, which is the value of the bit pattern
0x3f800000
if viewed as an IEEE-754 single precision value.
Using the
as_type
operator to reinterpret data to a type with a different number of
bytes results in an error.
Examples:
float f = 1.0f;
// Legal. Contains: 0x3f800000
uint u = as_type(f);
// Legal. Contains:
// (int4)(0x3f800000, 0x40000000, 0x40400000, 0x40800000)
float4 f = float4(1.0f, 2.0f, 3.0f, 4.0f);
int4 i = as_type(f);
2017-9-12 | Copyright © 2017 Apple Inc. All Rights Reserved.
Page of
44
174
int i;
// Legal.
short2 j = as_type (i);
half4 f;
// Error. Result and operand have different sizes
float4 g = as_type(f);
float4 f;
// Legal. g.xyz will have same values as f.xyz.
// g.w is undefined
float3 g = as_type(f);
2.15 Implicit Type Conversions
Implicit conversions between scalar built-in types (except void) are supported. When an implicit
conversion is done, it is not just a re-interpretation of the expression's value but a conversion of
that value to an equivalent value in the new type. For example, the integer value
5
is converted
to the floating-point value
5.0
.
All vector types are considered to have a higher conversion rank than scalar types. Implicit
conversions from a vector type to another vector or scalar type are not permitted and a
compilation error results. For example, the following attempt to convert from a 4-component
integer vector to a 4-component floating-point vector fails.
int4 i;
float4 f = i;
// compile error.
Implicit conversions from scalar-to-vector types are supported. The scalar value is replicated in
each element of the vector. The scalar may also be subject to the usual arithmetic conversion to
the element type used by the vector or matrix.
For example:
float4 f = 2.0f; // f = (2.0f, 2.0f, 2.0f, 2.0f)
Implicit conversions from scalar-to-matrix types and vector-to-matrix types are not supported
and a compilation error results. Implicit conversions from a matrix type to another matrix, vector
or scalar type are not permitted and a compilation error results.
Implicit conversions for pointer types follow the rules described in the C++14 Specification.
2017-9-12 | Copyright © 2017 Apple Inc. All Rights Reserved.
Page of
45
174
3 Operators
This chapter lists and describes the Metal operators.
3.1 Scalar and Vector Operators
1. The arithmetic operators, add (+), subtract (-), multiply (*) and divide (/), operate on
scalar and vector, integer and floating-point data types. All arithmetic operators return a
result of the same built-in type (integer or floating-point) as the type of the operands,
after operand type conversion. After conversion, the following cases are valid:
• The two operands are scalars. In this case, the operation is applied, and the result is a
scalar.
• One operand is a scalar, and the other is a vector. In this case, the scalar is converted to
the element type used by the vector operand. The scalar type is then widened to a vector
that has the same number of components as the vector operand. The operation is
performed component-wise, which results in a same size vector.
• The two operands are vectors of the same size. In this case, the operation is performed
component-wise, which results in a same size vector.
Division on integer types that results in a value that lies outside of the range bounded by the
maximum and minimum representable values of the integer type, such as TYPE_MIN/-1 for
signed integer types or division by zero does not cause an exception but results in an
unspecified value. Division by zero for floating-point types results in ±infinity or NaN, as
prescribed by the IEEE-754 standard. (For details about numerical accuracy of floating-
point operations, see section 7.)
2. The operator modulus (%) operates on scalar and vector integer data types. All
arithmetic operators return a result of the same built-in type as the type of the operands,
after operand type conversion. The following cases are valid:
• The two operands are scalars. In this case, the operation is applied, and the result is a
scalar.
• One operand is a scalar, and the other is a vector. In this case, the scalar is converted to
the element type used by the vector operand. The scalar type is then widened to a vector
that has the same number of components as the vector operand. The operation is
performed component-wise, which results in a same size vector.
• The two operands are vectors of the same size. In this case, the operation is performed
component-wise, which results in a same size vector.
The resulting value is undefined for any component computed with a second operand that is
zero, while results for other components with non-zero operands remain defined. If both
operands are non-negative, the remainder is non-negative. If one or both operands are
negative, results are undefined.
3. The arithmetic unary operators (+ and -) operate on scalar and vector, integer and
floating-point types.
2017-9-12 | Copyright © 2017 Apple Inc. All Rights Reserved.
Page of
46
174
Dostları ilə paylaş: |