• Unsigned integers shall obey the laws of arithmetic modulo
2
n
, where
n
is the
number of bits in the value representation of that particular size of integer. The
result of signed integer overflow is undefined.
• For integral operands the divide (/) operator yields the algebraic quotient with
any fractional part discarded. (This is often called truncation towards zero.) If the
quotient
a/b
is representable in the type of the result,
(a/b)*b + a%b
is equal to
a
.
3.2 Matrix Operators
The arithmetic operators add (+), subtract (-) operate on matrices. Both matrices must have the
same numbers of rows and columns. The operation is done component-wise resulting in the
same size matrix. The arithmetic operator multiply (*) operates on:
• a scalar and a matrix,
• a matrix and a scalar,
• a vector and a matrix,
• a matrix and a vector,
• or a matrix and a matrix.
If one operand is a scalar, the scalar value is multiplied to each component of the matrix
resulting in the same size matrix. A right vector operand is treated as a column vector and a left
vector operand as a row vector. For vector – matrix, matrix – vector and matrix – matrix
multiplication, the number of columns of the left operand is required to be equal to the number
of rows of the right operand. The multiply operation does a linear algebraic multiply, yielding a
vector or a matrix that has the same number of rows as the left operand and the same number
of columns as the right operand.
The examples below presume these vector, matrix, and scalar variables are initialized:
float3 v;
float3x3 m;
float a = 3.0f;
The following matrix-to-scalar multiplication
float3x3 m1 = m * a;
is equivalent to:
m1[0][0] = m[0][0] * a;
m1[0][1] = m[0][1] * a;
m1[0][2] = m[0][2] * a;
m1[1][0] = m[1][0] * a;
m1[1][1] = m[1][1] * a;
2017-9-12 | Copyright © 2017 Apple Inc. All Rights Reserved.
Page of
49
174
m1[1][2] = m[1][2] * a;
m1[2][0] = m[2][0] * a;
m1[2][1] = m[2][1] * a;
m1[2][2] = m[2][2] * a;
The following vector-to-matrix multiplication
float3 u = v * m;
is equivalent to:
u.x = dot(v, m[0]);
u.y = dot(v, m[1]);
u.z = dot(v, m[2]);
The following matrix-to-vector multiplication
float3 u = m * v;
is equivalent to:
u = v.x * m[0];
u += v.y * m[1];
u += v.z * m[2];
The following matrix-to-matrix multiplication
float3x3
m, n, r;
r = m * n;
is equivalent to:
r[0] = m[0] * n[0].x;
r[0] += m[1] * n[0].y;
r[0] += m[2] * n[0].z;
r[1] = m[0] * n[1].x;
r[1] += m[1] * n[1].y;
r[1] += m[2] * n[1].z;
r[2] = m[0] * n[2].x;
r[2] += m[1] * n[2].y;
r[2] += m[2] * n[2].z;
2017-9-12 | Copyright © 2017 Apple Inc. All Rights Reserved.
Page of
50
174
NOTE: The order of partial sums for the vector-to-matrix, matrix-to-vector and matrix-
to-matrix multiplication operations described above is undefined.
2017-9-12 | Copyright © 2017 Apple Inc. All Rights Reserved.
Page of
51
174
4 Function and Variable Declarations
This chapter describes how functions, arguments, and variables are declared. It also details how
attributes are often used with functions, arguments, and variables to specify restrictions.
4.1 Function Specifiers
Metal supports the following function specifiers that restrict how a function may be used:
•
kernel
- A data-parallel function that is executed over a 1-, 2- or 3-dimensional grid.
•
vertex
- A vertex function that is executed for each vertex in the vertex stream and
generates per-vertex output or a post-tessellation vertex function that is executed for
each surface sample on the patch produced by the fixed-function tessellator.
•
fragment
– A fragment function that is executed for each fragment in the fragment
stream and their associated data and generates per-fragment output.
A function specifier is used at the start of a function, before its return type. The following
example shows the syntax for a compute function.
kernel void
my_kernel(…)
{…}
For functions declared with the
kernel
specifier, the return type must be
void
.
Only a graphics function can be declared with one of the
vertex
or
fragment
specifiers. For
graphics functions, the return type identifies whether the output generated by the function is
either per-vertex or per-fragment. The return type for a graphics function may be
void
indicating that the function does not generate output.
Functions that use a
kernel
,
vertex
or
fragment
function specifier cannot call functions that
also use these specifiers, or a compilation error results.
Functions that use a
kernel
,
vertex
or
fragment
function specifier can be declared within a
namespace.
4.1.1
Post-Tessellation Vertex Functions
The post-tessellation vertex function calculates the vertex data for each surface sample on the
patch produced by the fixed-function tessellator. The inputs to the post-tessellation vertex
function are:
• the per-patch data,
• the patch control point data, and
• the tessellator stage output (the normalized vertex location on the patch).
2017-9-12 | Copyright © 2017 Apple Inc. All Rights Reserved.
Page of
52
174
Dostları ilə paylaş: |