Resource Types[Resources]

11 Resource Types[Resources]

Resource types are intangible types representing memory or configuration with an external interface.

These take the form of typed buffers, raw buffers, textures, constant buffers and samplers.

Typed buffer, raw buffer, and Texture resources may be read-only or read-write as denoted by the type of the resource, where the names of read-write resource types are prefixed with RW.

Global resource declarations are bound to device memory managed by an application through a runtime implementation. A resource declaration that is not bound is said to be unbound. Operations on unbound resources are evaluated as no-ops.

An implementation may impose restrictions on how local resource objects may be used ([AnnexB.LocalResources]).

11.1 Optional Features[Resources.Optional]

Dynamic resources is an optional feature which allows resource objects to be initialized by indexing directly into a heap of descriptors. A conforming implementation must either support all interfaces related to dynamic resources or none, but may not partially support them.

The __DynamicResourceHandle type in the code examples in this clause is a placeholder for the implementation-specific type returned by subscript indexing into the ResourceDescriptorHeap ([Resources.Binding.Dynamic]).

11.2 Special Semantics[Resources.Special]

11.2.1 Resource Initialization[Resources.Special.Initialization]

A resource declaration in a global scope is called a global resource declaration and represents a binding for external data into a program. Global resource declarations are implicitly initialized in an implementation-defined way.

Use of an uninitialized resource is undefined.

11.3 Typed Buffers[Resources.TypedBuffers]

The typed buffer class template represents a one-dimensional resource containing an array of a single given type. Its contents are indexed by typed access to each element. The memory backing a resource need not be formatted in the same type as the resource’s element type. If required, typed buffer elements are converted upon load in an implementation-defined way.

There are two typed buffer class templates Buffer and RWBuffer, which respectively represent read-only and read-write typed buffer objects.

template <typename T = float4> requires hlsl::is_vector<T>::value || hlsl::is_arithmetic<T>::value class Buffer

Buffer(); Buffer(const Buffer &buf); Buffer &operator=(Buffer &buf); Buffer(const __DynamicResourceHandle &handle);

void GetDimensions(out uint width) const;

// Element access. T operator[](int index) const; T Load(int index) const; T Load(int index, out uint status) const;

;

template <typename T> requires hlsl::is_vector<T>::value || hlsl::is_arithmetic<T>::value class RWBuffer

RWBuffer(); RWBuffer(RWBuffer buf); RWBuffer &operator=(RWBuffer &buf); Buffer(const __DynamicResourceHandle &handle);

void GetDimensions(out uint width) const;

// Element access. T operator[](int index) const; device T &operator[](int n) const; T Load(int index) const; T Load(int index, out uint status) const;

;

The element type of a typed buffer, T, must be an arithmetic type (6.9.1) or vector of arithmetic type containing no more than 4 elements, and the total size of the element (sizeof(T)) must not exceed 16-bytes in size.

The Buffer type’s template argument T has a default value of float4.

11.3.1 Typed Buffer Constructors[Resources.TypedBuffers.Ctrs]

Buffer(); RWBuffer();

  • Effects: Constructs an uninitialized resource handle.

Buffer(const Buffer &buf); RWBuffer(const RWBuffer &buf);

  • Effects: Initializes a resource to refer to the same resource as the input argument buf.

Buffer(const __DynamicResourceHandle &handle);

  • Feature: Dependent on dynamic resources ([Resources.Binding.Dynamic]).

  • Effects: Initializes a resource to refer to the dynamic resource handle provided as the input argument handle.

11.3.2 Typed Buffer Copying and Assignment[Resources.TypedBuffers.Copy]

Buffer &operator=(Buffer &buf); RWBuffer &operator=(RWBuffer &buf);

  • Effects: Initializes a resource to refer to the same resource as the input argument buf.

  • Returns: this.

11.3.3 Typed Buffer Inspecting Functions[Resources.TypedBuffers.Inspect]

void GetDimensions(out uint width) const;

  • Effects: Writes the total number of elements contained in the typed buffer to the width argument.

T Load(uint index) const;

  • Requires: index <the number of elements in the typed buffer.

  • Returns: The element in the typed buffer at the index specified by index.

T Load(int index, out uint status) const;

  • Requires: index <the number of elements in the typed buffer.

  • Returns: The element in the typed buffer at the index specified by index.

  • Effects: Initializes the status argument to an implementation-defined status signal (11.4).

  • Remarks: The status parameter returns an implementation-defined value that indicates if the loaded value came from fully mapped parts of the resource. This parameter must be passed to the built-in function CheckAccessFullyMapped (11.4) in order to interpret it.

11.3.4 Typed Buffer Operators[Resources.TypedBuffers.Operators]

T operator[](uint index) const;

  • Requires: index <the number of elements in the typed buffer.

  • Returns: The element in the typed buffer at the index specified by index.

device T &operator[](int index);

  • Requires: index <the number of elements in the typed buffer.

  • Returns: An lvalue-reference to the element in the typed buffer at the index specified by index.

  • Remarks: Writing to typed buffer elements overwrite the entire element, even if only part of the data is written. A partial write to a typed buffer is a load-insert-store operation.

NOTE Accurately modeling the memory operations for writable typed buffers would require a proxy-object interface since the address written to isn’t actually the device memory since it may be converted or otherwise normalized by the implementation.

11.4 CheckAccessFullyMapped[Resources.Mapcheck]

The implementation-defined status value returned by texture and buffer load methods is interpreted by a built-in function:

bool CheckAccessFullyMapped(uint status);

  • Requires: status is an initialized value from a resource Load function’s status output parameter.

  • Returns: true if the value was accessed from memory that was fully mapped by the runtime implementation; otherwise returns false.

Annex
(informative)
Grammar Summary[AnnexA]

Annex
(informative)
Implementation Documentation[AnnexB]

11.5 Pre-standard Language Versions[AnnexB.Versions]

HLSL has evolved over time, with various versions of the language being released alongside different versions of DirectX. Beginning with the DirectX Shader Compiler (DXC), the compiler began supporting language modes corresponding to specific historical versions of HLSL. These historical versions are useful for understanding the evolution of the language and for documenting observed behaviors in specific implementations, and they are named for the years in which they were released. The following historical versions of HLSL are relevant to this specification:

  • HLSL 2015: Roughly equivalent to the version of HLSL supported by the Effects Compiler (FXC).

  • HLSL 2016: The initial version of HLSL supported by the DirectX Shader Compiler (DXC).

  • HLSL 2017: Added enumerations similar to C++11.

  • HLSL 2018: Added support for 16-bit data types and intrinsic templates.

  • HLSL 2021: Added user-defined templates, operator overloading, short-circuiting boolean operators, and stricter implicit casting rules for user-defined structures.

NOTE Both the DirectX Shader Compiler (DXC) and Clang support a language mode called "HLSL 202x" which refers to this draft specification.

11.6 Known Implementations[AnnexB.Implementations]

This section provides a list of known implementations of HLSL, including both conforming and non-conforming implementations. This is not meant to be comprehensive, but is provided to supplement later sections in this annex which discuss details of specific implementations.

  • Clang: The open-source C/C++ compiler developed by the LLVM project. Clang contains a partial implementation of HLSL this specification and is actively being developed. It is available at https://clang.llvm.org/.

  • DirectX Shader Compiler (DXC): The open-source reference implementation of HLSL, developed by Microsoft and based on the LLVM/Clang infrastructure. It is available at https://github.com/microsoft/DirectXShaderCompiler.

  • Effects Compiler (FXC): The legacy implementation of HLSL, developed by Microsoft. It is included with the Windows SDK and is available at https://learn.microsoft.com/en-us/windows/apps/windows-sdk/.

  • GLSLang: An open-source implementation of the OpenGL Shading Language (GLSL), developed by The Khronos Group. GLSLang contains a (now deprecated) partial implementation of HLSL 2018. It is available at https://github.com/KhronosGroup/glslang.

  • Slang: An open-source shader language and compiler framework developed by The Khronos Group. Slang contains a partial implementation of HLSL 2018. It is available at https://github.com/shader-slang/slang.

11.7 Implementation Limits[AnnexB.Limits]

This section describes reasonable implementation limits that may be assumed by a conforming implementation. These limits specify minimum required or maximum allowed values for various implementation-defined parameters.

6.9 declares a vector type as having required supported sizes of 1 to 4 components. Implementations may support larger vector sizes but are not required to do so. An implementation that supports larger vector sizes must define its vector size limit.

11.8 Observed Deviations[AnnexB.Documentation]

This section provides documentation around implementation behaviors that are known to differ between specific implementations. This includes breaking changes between historical HLSL and standard HLSL where some compilers or versions of compilers may not conform to standard HLSL, as well as observed non-conformant behaviors in such compilers. This is not meant to be a comprehensive list of bugs.

11.8.1 Resource Objects[AnnexB.Resources]

In violation of 6.9.3, DXC supports storing objects that contain resources in cbuffer declarations. In this use case the resource objects are not actually stored in the cbuffer, but instead the resource is treated as a global resource declaration and name lookup resolves the value inside the structure declaration to the implied global resource declaration.