'Why convert to XMFLOAT instead of using XMVECTOR directly?
While studying DirectX 12, it says that I should use XMFLOAT instead of XMVECTOR for class data members. I do not understand why.
Is it wrong that defining the XMVECTOR variables in my class? or using XMVECTOR directly in my class?
Solution 1:[1]
This is covered in the DirectXMath Programmer's Guide on Docs.Microsoft which you should take the time to read. In particular, read the Getting Started section titled Type Usage Guidelines.
The XMVECTOR and XMMATRIX types are the work horses for the DirectXMath Library. Every operation consumes or produces data of these types. Working with them is key to using the library. However, since DirectXMath makes use of the SIMD instruction sets, these data types are subject to a number of restrictions. It is critical that you understand these restrictions if you want to make good use of the DirectXMath functions.
You should think of XMVECTOR as a proxy for a SIMD hardware register, and XMMATRIX as a proxy for a logical grouping of four SIMD hardware registers. These types are annotated to indicate they require 16-byte alignment to work correctly. The compiler will automatically place them correctly on the stack when they are used as a local variable, or place them in the data segment when they are used as a global variable. With proper conventions, they can also be passed safely as parameters to a function (see Calling Conventions for details).
Allocations from the heap, however, are more complicated. As such, you need to be careful whenever you use either XMVECTOR or XMMATRIX as a member of a class or structure to be allocated from the heap. On Windows x64, all heap allocations are 16-byte aligned, but for Windows x86, they are only 8-byte aligned. There are options for allocating structures from the heap with 16-byte alignment (see Properly Align Allocations). For C++ programs, you can use operator new/delete/new[]/delete[] overloads (either globally or class-specific) to enforce optimal alignment if desired.
Note As an alternative to enforcing alignment in your C++ class directly by overloading new/delete, you can use the pImpl idiom. If you ensure your Impl class is aligned via __aligned_malloc internally, you can then freely use aligned types within the internal implementation. This is a good option when the 'public' class is a Windows Runtime ref class or intended for use with std::shared_ptr<>, which can otherwise disrupt careful alignment.
However, often it is easier and more compact to avoid using XMVECTOR or XMMATRIX directly in a class or structure. Instead, make use of the XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4, and so on, as members of your structure. Further, you can use the Vector Loading and Vector Storage functions to move the data efficiently into XMVECTOR or XMMATRIX local variables, perform computations, and store the results. There are also streaming functions (XMVector3TransformStream, XMVector4TransformStream, and so on) that efficiently operate directly on arrays of these data types.
This strict alignment requirement and the verbosity is by design as it makes it clear to the programmer when load/store overhead is being incurred. If, however, you find it a bit tedious, consider making use of the SimpleMath wrapper in the DirectX Tool Kit for DirectX 11 / DirectX 12
Keep in mind that DirectX has nothing particularly to do with DirectXMath. DirectXMath can work just as well with any version of Direct3D or even OpenGL as it just does CPU-side vector and matrix computations. DirectXMath doesn't really depend on the Windows OS at all; it's just a collection of C/C++ code using intrinsics so the compiler is all that really matters.
In fact, since you are apparently new enough to DirectX generally to not already know how to use DirectXMath, you should consider using DirectX 11 and not trying to jump into DirectX 12 cold. DirectX 12 is a very unforgiving API designed for graphics experts, and largely assumes you are already an expert in Direct3D 11 programming.
See DirectX Tool Kit for DirectX 12 tutorials and Getting Started with Direct3D 12.
Solution 2:[2]
You are in your right to store one or more XMVECTOR
as object members.
When you do so, you need to be sure you respect the alignment constraint of XMVECTOR
: 128bits. This is why they introduce the XMFLOATx
to deal with storage without the alignment requirements.
Failure to do so may give you crashes at best and incorrect computation at worst. This is more likely to happen with a 32bits executable when new
is not required to returned a memory align on at least 16 bytes.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Varaquilex |
Solution 2 | galop1n |