# Chapter 13. Resource Descriptors

Shaders access buffer and image resources by using special shader variables which are indirectly bound to buffer and image views via the API. These variables are organized into sets, where each set of bindings is represented by a descriptor set object in the API and a descriptor set is bound all at once. A descriptor is an opaque data structure representing a shader resource such as a buffer view, image view, sampler, or combined image sampler. The content of each set is determined by its descriptor set layout and the sequence of set layouts that can be used by resource variables in shaders within a pipeline is specified in a pipeline layout.

Each shader can use up to `maxBoundDescriptorSets` (see Limits) descriptor sets, and each descriptor set can include bindings for descriptors of all descriptor types. Each shader resource variable is assigned a tuple of (set number, binding number, array element) that defines its location within a descriptor set layout. In GLSL, the set number and binding number are assigned via layout qualifiers, and the array element is implicitly assigned consecutively starting with index equal to zero for the first element of an array (and array element is zero for non-array variables):

GLSL example.

    // Assign set number = M, binding number = N, array element = 0
    layout (set=M, binding=N) uniform sampler2D variableName;

    // Assign set number = M, binding number = N for all array elements, and
    // array element = I for the I'th member of the array.
    layout (set=M, binding=N) uniform sampler2D variableNameArray[I];

SPIR-V example.

    // Assign set number = M, binding number = N, array element = 0
                   ...
              %1 = OpExtInstImport "GLSL.std.450"
                   ...
                   OpName %10 "variableName"
                   OpDecorate %10 DescriptorSet M
                   OpDecorate %10 Binding N
              %2 = OpTypeVoid
              %3 = OpTypeFunction %2
              %6 = OpTypeFloat 32
              %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
              %8 = OpTypeSampledImage %7
              %9 = OpTypePointer UniformConstant %8
             %10 = OpVariable %9 UniformConstant
                   ...

    // Assign set number = M, binding number = N for all array elements, and
    // array element = I for the I'th member of the array.
                   ...
              %1 = OpExtInstImport "GLSL.std.450"
                   ...
                   OpName %13 "variableNameArray"
                   OpDecorate %13 DescriptorSet M
                   OpDecorate %13 Binding N
              %2 = OpTypeVoid
              %3 = OpTypeFunction %2
              %6 = OpTypeFloat 32
              %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
              %8 = OpTypeSampledImage %7
              %9 = OpTypeInt 32 0
             %10 = OpConstant %9 I
             %11 = OpTypeArray %8 %10
             %12 = OpTypePointer UniformConstant %11
             %13 = OpVariable %12 UniformConstant
                   ...