|
2 | 2 |
|
3 | 3 | Resources are built-in intangible types representing memory with an external interface. |
4 | 4 |
|
5 | | -These take the form of Typed Buffers, Raw Buffers, Textures, and Samplers. |
| 5 | +These take the form of Typed Buffers, Raw Buffers, Textures, Constant Buffers and Samplers. |
| 6 | + |
6 | 7 | Buffer and Texture types can be read-only or writable. |
7 | 8 |
|
8 | 9 | \Sec{Typed Buffers}{Resources.tybufs} |
|
11 | 12 | Its contents are indexed by typed access to each element |
12 | 13 | Types may have their formats converted upon load. |
13 | 14 |
|
14 | | -Template types can be any type that totals or can be padded to 16 bytes. |
| 15 | +The element type may be any type up to 16 bytes in size. Elements may be padded |
| 16 | +to 16 bytes if the element type is smaller than 16 bytes. |
15 | 17 |
|
16 | 18 | All typed buffers can be read through subscript operators or Load methods. |
17 | 19 | Writable typed buffers can be written through subscript operators. |
|
663 | 665 |
|
664 | 666 | \Sec{Constant Buffers}{Resources.cnbuf} |
665 | 667 |
|
| 668 | +Constant buffers represent resources that contain read-only constant data in a |
| 669 | +well-defined memory layout. |
| 670 | + |
| 671 | +\Sub{Constant Buffer Declaration Block}{Resources.cnbuf.cb} |
| 672 | + |
| 673 | +\p A constant buffer can be declared using the \texttt{cbuffer} specifier. |
| 674 | + |
| 675 | +\begin{grammar} |
| 676 | + \define{cbuffer-declaration-group}\br |
| 677 | + \terminal{cbuffer} name \opt{resource-binding} \terminal{\{} |
| 678 | + \opt{cbuffer-declaration-seq} \terminal {\}} |
| 679 | + |
| 680 | + \define{cbuffer-declaration-seq}\br |
| 681 | + \textit{cbuffer-declaration}\br |
| 682 | + \textit{cbuffer-declaration-seq cbuffer-declaration} |
| 683 | + |
| 684 | + \define{cbuffer-declaration}\br |
| 685 | + \textit{variable-declaration}\br |
| 686 | + \textit{empty-declaration} |
| 687 | +\end{grammar} |
| 688 | + |
| 689 | +\p The name of the \texttt{cbuffer} declaration group cannot be referenced from within the translation unit and is not required to be unique. |
| 690 | + |
| 691 | +\p Variable declarations in the \texttt{cbuffer} declaration group are called \textit{shader constants}. |
| 692 | + |
| 693 | +\p Shader constants can be referenced from anywhere in the translation unit after they are declared by directly using the declaration name. This implies that all shader constants declared in a translation unit must have unique names, even though they might be declared in different \texttt{cbuffer} declaration groups. |
| 694 | + |
| 695 | +\p Variable declarations in the \texttt{cbuffer} declaration group cannot have \texttt{groupshared} or \texttt{static} variable modifiers. |
| 696 | + |
| 697 | +\p Other declarations in the \texttt{cbuffer} declaration group such as |
| 698 | +\textit{namespace-declaration}, \textit{record-declaration} or |
| 699 | +\textit{function-declaration} are not allowed. |
| 700 | + |
| 701 | +\p Nesting of \texttt{cbuffer} declaration groups is not allowed. |
| 702 | + |
| 703 | +\p For example: |
| 704 | + |
| 705 | +\begin{HLSL} |
| 706 | + cbuffer MyConstants { |
| 707 | + float4 CameraPos; |
| 708 | + }; |
| 709 | + |
| 710 | + float4 getCameraPosition() { |
| 711 | + return CameraPos; |
| 712 | + } |
| 713 | +\end{HLSL} |
| 714 | + |
| 715 | +\Sub{Constant Buffer Class}{Resources.cnbuf.cbclass} |
| 716 | + |
| 717 | +\p Another way of declaring constant buffers is by using the |
| 718 | +\texttt{ConstantBuffer<T>} resource class. |
| 719 | + |
| 720 | +\p The template parameter \texttt{T} must be a class type (\ref{Classes}). |
| 721 | + |
| 722 | +\begin{HLSL} |
| 723 | + template <typename T> |
| 724 | + class ConstantBuffer { |
| 725 | + public: |
| 726 | + ConstantBuffer(); |
| 727 | + ConstantBuffer(const ConstantBuffer &buf); |
| 728 | + ConstantBuffer &operator=(ConstantBuffer &buf); |
| 729 | + }; |
| 730 | +\end{HLSL} |
| 731 | + |
| 732 | +\p The \textit{shader constants} are the fields of the class type \texttt{T}. |
| 733 | +They can be referenced from anywhere within the translation unit after the |
| 734 | +\texttt{ConstantBuffer<T>} declaration as if they were fields of the |
| 735 | +\texttt{ConstantBuffer<T>} class. |
| 736 | + |
| 737 | +\p For example: |
| 738 | + |
| 739 | +\begin{HLSL} |
| 740 | + struct MyConstants { |
| 741 | + float4 CameraPos; |
| 742 | + }; |
| 743 | + |
| 744 | + ConstantBuffer<MyConstants> CB; |
| 745 | + |
| 746 | + float4 getCameraPosition() { |
| 747 | + return CB.CameraPos; |
| 748 | + } |
| 749 | +\end{HLSL} |
| 750 | + |
| 751 | +\p The layout rules for constant buffer declared with the |
| 752 | +\texttt{ConstantBuffer<T>} syntax are the same as for named \texttt{cbuffer} |
| 753 | +declaration groups. |
| 754 | + |
| 755 | +\p \texttt{ConstantBuffer<T>} can be defined at local scope to represent a local |
| 756 | +reference to a constant buffer that can be associated with a global buffer when |
| 757 | +assigned. The reference must be resolvable to a unique global buffer declaration |
| 758 | +before use. |
| 759 | + |
| 760 | +\p Constant buffers cannot be implicitly nor explicitly cast from one type to |
| 761 | +another. This means that local \texttt{ConstantBuffer} can only be assigned from |
| 762 | +\texttt{ConstantBuffer} with the same template type \texttt{T}. |
| 763 | + |
| 764 | +\Sub{Constant Buffer Layout}{Resources.cnbuf.lay} |
| 765 | + |
| 766 | +\p Layout of the constant buffer is implementation dependent. This section |
| 767 | +describes the layout that is used by DirectX. |
| 768 | + |
| 769 | +\p A constant buffer is arranged like an array of 16-byte rows, or 4-component |
| 770 | +vectors of 32-bit elements. Shader constants are arranged into the buffer in the |
| 771 | +order they were declared based on following rules. |
| 772 | + |
| 773 | +\p Specific basic types are packed into the last used row of the buffer if they |
| 774 | +fit into the available space, starting at the next available aligned position. |
| 775 | +These types include: |
| 776 | +\begin{itemize} |
| 777 | +\item \textit{scalar types} |
| 778 | +\item \textit{vector types} |
| 779 | +\item \textit{matrix types} with only one row in \textit{column\_major} storage layout |
| 780 | +\end{itemize} |
| 781 | + |
| 782 | +\p If they do not fit the remaining space of the row, they will placed at the |
| 783 | +start a new 16-byte aligned row. |
| 784 | + |
| 785 | +\p Vectors are aligned by the size of a single vector element type unless that |
| 786 | +alignment results in crossing the 16-byte row boundary, in which case it is |
| 787 | +aligned to the next row. |
| 788 | + |
| 789 | +\p Aggregate types like arrays and structures are always 16-byte row-aligned. If |
| 790 | +the aggregate ends with an element that does not completely fill a row, the |
| 791 | +remaining space on the last row may be used by the next value. |
| 792 | + |
| 793 | +\p Individual array elements are always 16-byte row aligned. |
| 794 | + |
| 795 | +\p Matrix types with more than one row in \textit{column\_major} storage layout |
| 796 | +and matrix types in \textit{row\_major} storage layout in are aligned to the |
| 797 | +16-byte row. Each row in storage layout (each column for \textit{column\_major} |
| 798 | +matrix) is aligned to a 16-byte row. |
| 799 | + |
| 800 | +\p Members of structured types used in constant buffers follow these same rules. |
| 801 | +Because structures are always 16-byte row-aligned, the offset layout within the |
| 802 | +structure is independent of the particular structure instance location. |
| 803 | + |
| 804 | +\Sub{Packoffset annotations}{Resources.cnbuf.po} |
| 805 | + |
| 806 | +\p Shader constants declared in \texttt{cbuffer} declaration group can have an |
| 807 | +optional \texttt{packoffset} annotation added before their \texttt{;} terminal. |
| 808 | +If this annotation is added to one shader constant in a declaration group then |
| 809 | +it must be added to all shader constants in that group. |
| 810 | + |
| 811 | +\begin{grammar} |
| 812 | + \define{packoffset-annotation}\br |
| 813 | + \terminal{: packoffset(} packoffset-id packoffset-row \opt{packoffset-element} \terminal{)} |
| 814 | + |
| 815 | + \define{packoffset-id}\textnormal{one of}\br |
| 816 | + \terminal{c C} |
| 817 | + |
| 818 | + \define{packoffset-row}\br |
| 819 | + digit\br |
| 820 | + packoffset-row digit |
| 821 | + |
| 822 | + \define{packoffset-element}\br |
| 823 | + \terminal{.} \textit{packoffset-element-id} |
| 824 | + |
| 825 | + \define{packoffset-element-id}\textnormal{one of}\br |
| 826 | + \terminal{x y z w r g b a}\br |
| 827 | +\end{grammar} |
| 828 | + |
| 829 | +\p The \texttt{packoffset} annotation defines specific offset in the constant |
| 830 | +buffer where the shader constant is located. |
| 831 | + |
| 832 | +\p The \textit{packoffset-row} number is the index into the array of 16-byte |
| 833 | +rows of the constant buffer. Each row treated as a vector of four 32-bit |
| 834 | +elements. |
| 835 | + |
| 836 | +\p The \textit{packoffset-element} identifies specific location within the |
| 837 | +vector where \texttt{x} or \texttt{r} is the first element of the vector, |
| 838 | +\texttt{y} or \texttt{g} is the second one, \texttt{z} or \texttt{b} is the |
| 839 | +third one and \texttt{w} or \texttt{a} is the fourth, and last element of the |
| 840 | +vector. |
| 841 | + |
| 842 | +\p Shader constant that has a structure, array or matrix type must always be |
| 843 | +16-byte row-aligned. It means that if it specifies a |
| 844 | +\textit{packoffset-element}, it must have a value of \texttt{x} or \texttt{r}. |
| 845 | + |
| 846 | +\p For example |
| 847 | + |
| 848 | +\begin{HLSL} |
| 849 | + cbuffer MyConstants { |
| 850 | + float2 Pos : packoffset(c1.z); |
| 851 | + }; |
| 852 | +\end{HLSL} |
| 853 | + |
| 854 | +The \texttt{Pos} shader constant will be located at byte offset \texttt{24} in |
| 855 | +the constant buffer \texttt{MyConstants}. |
| 856 | + |
| 857 | +\Sub{Default Constant Buffer}{Resources.cnbuf.defcb} |
| 858 | + |
| 859 | +\p All variables declarations in the global scope are implicitly added to |
| 860 | +default constant buffer called \texttt{\$Globals}, unless they are marked |
| 861 | +\texttt{static}, \texttt{groupshared}, or declare a resource or array of |
| 862 | +resources. |
| 863 | + |
| 864 | +\p Layout rules for a default constant buffer are the same as for a named |
| 865 | +\texttt{cbuffer} declaration group. |
| 866 | + |
| 867 | +\p Default constant buffer declarations can have an optional |
| 868 | +\textit{resource-binding} annotation with a \textit{register-type} \texttt{c} or |
| 869 | +\texttt{C} added before their \texttt{;} terminal. This annotation does not |
| 870 | +define a virtual register binding but rather an index into an array of 16-byte |
| 871 | +rows that represents the default constant buffer, similar to the |
| 872 | +\texttt{packoffset} annotation. |
| 873 | + |
| 874 | +\p For example |
| 875 | +\begin{HLSL} |
| 876 | + float4 CameraPos : register(c2); |
| 877 | +\end{HLSL} |
| 878 | + |
| 879 | +is equivalent to |
| 880 | + |
| 881 | +\begin{HLSL} |
| 882 | + cbuffer CB { |
| 883 | + float4 CameraPos : packoffset(c2); |
| 884 | + } |
| 885 | +\end{HLSL} |
| 886 | + |
666 | 887 | \Sec{Samplers}{Resources.samp} |
667 | 888 |
|
668 | 889 | \Sec{CheckAccessFullyMapped}{Resources.mapcheck} |
669 | 890 |
|
670 | | -The mapped status value returned by certain texture and buffer methods can be intrepreted by a built-in function: |
| 891 | +The mapped status value returned by certain texture and buffer methods can be |
| 892 | +intrepreted by a built-in function: |
671 | 893 |
|
672 | 894 | \begin{HLSL} |
673 | 895 | bool CheckAccessFullyMapped(in uint status); |
674 | 896 | \end{HLSL} |
675 | 897 |
|
676 | | -This function returns true is the value was accessed from a fully committed resource, |
677 | | -or from fully mapped pages of a sparse resource. |
678 | | -If any part of the return value was from unmapped memory, false is returned. |
| 898 | +This function returns true if the value was accessed from a fully committed |
| 899 | +resource, or from fully mapped pages of a sparse resource. If any part of the |
| 900 | +return value was from unmapped memory, false is returned. |
679 | 901 |
|
680 | 902 | \Sec{Resource Binding}{Resources.binding} |
681 | 903 |
|
|
688 | 910 | \terminal{: register(} register-type bind-number \terminal{)}\br |
689 | 911 | \terminal{: register(} register-type bind-number , \terminal{space} bind-number \terminal{)}\br |
690 | 912 | \define{register-type} \textnormal{one of}\br |
691 | | - \terminal{t u b s}\br |
| 913 | + \terminal{t u b s c T U B S C}\br |
692 | 914 | \define{bind-number}\br |
693 | 915 | digit\br |
694 | 916 | bind-number digit\br |
695 | 917 | \end{grammar} |
696 | 918 |
|
697 | | -The register type indicates whether the binding is for a read-only (\texttt{t}), a writable (\texttt{u}), |
698 | | -a constant buffer (\texttt{b}), or a sampler (\texttt{s}). |
699 | | -The register bind number indicates the register number at which the resource variable begins. |
700 | | -The optional second parameter indicates the virtual register space that the register belongs to. |
| 919 | +The register type indicates whether the binding is for a read-only |
| 920 | +(\texttt{t}/\texttt{T}), a writable (\texttt{u}/\texttt{U}), a constant buffer |
| 921 | +(\texttt{b}/\texttt{B}), or a sampler (\texttt{s}/\texttt{S}). The register bind |
| 922 | +number indicates the register number at which the resource variable begins. The |
| 923 | +optional second parameter indicates the virtual register space that the register |
| 924 | +belongs to. |
| 925 | + |
| 926 | +Register type \texttt{c}/\texttt{C} defines layout information for the default |
| 927 | +constant buffer (\ref{Resources.cnbuf.defcb}). |
701 | 928 |
|
702 | 929 | Sample syntax of virtual register binding attributes: |
703 | 930 | \begin{HLSL} |
|
0 commit comments