chromium/third_party/vulkan-validation-layers/src/layers/state_tracker/descriptor_sets.h

/* Copyright (c) 2015-2024 The Khronos Group Inc.
 * Copyright (c) 2015-2024 Valve Corporation
 * Copyright (c) 2015-2024 LunarG, Inc.
 * Copyright (C) 2015-2024 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "state_tracker/state_object.h"
#include "utils/hash_util.h"
#include "utils/vk_layer_utils.h"
#include "state_tracker/shader_stage_state.h"
#include "generated/vk_object_types.h"
#include <vulkan/utility/vk_safe_struct.hpp>
#include <map>
#include <set>
#include <vector>

class CoreChecks;
class ValidationObject;
class ValidationStateTracker;
struct DeviceExtensions;

namespace vvl {
class Sampler;
class DescriptorSet;
class CommandBuffer;
class ImageView;
class Buffer;
class BufferView;
class Pipeline;
class AccelerationStructureNV;
class AccelerationStructureKHR;
struct AllocateDescriptorSetsData;

// "bindless" does not have a concrete definition, but we use it as means to know:
// "is GPU-AV going to have to validate this or not"
// (see docs/gpu_av_bindless.md for more details)
static inline bool IsBindless(VkDescriptorBindingFlags flags) {}

class DescriptorPool : public StateObject {};

class DescriptorUpdateTemplate : public StateObject {};

// Utility structs/classes/types
// Index range for global indices below, end is exclusive, i.e. [start,end)
struct IndexRange {};

/*
 * DescriptorSetLayoutDef/DescriptorSetLayout classes
 *
 * Overview - These two classes encapsulate the Vulkan VkDescriptorSetLayout data (layout).
 *   A layout consists of some number of bindings, each of which has a binding#, a
 *   type, descriptor count, stage flags, and pImmutableSamplers.

 *   The DescriptorSetLayoutDef represents a canonicalization of the input data and contains
 *   neither per handle or per device state.  It is possible for different handles on
 *   different devices to share a common def.  This is used and useful for quick compatibiltiy
 *   validation.  The DescriptorSetLayout refers to a DescriptorSetLayoutDef and contains
 *   all per handle state.
 *
 * Index vs Binding - A layout is created with an array of VkDescriptorSetLayoutBinding
 *  where each array index will have a corresponding binding# that is defined in that struct.
 *  The binding#, then, is decoupled from VkDescriptorSetLayoutBinding index, which allows
 *  bindings to be defined out-of-order. This DescriptorSetLayout class, however, stores
 *  the bindings internally in-order. This is useful for operations which may "roll over"
 *  from a single binding to the next consecutive binding.
 *
 *  Note that although the bindings are stored in-order, there still may be "gaps" in the
 *  binding#. For example, if the binding creation order is 8, 7, 10, 3, 4, then the
 *  internal binding array will have five entries stored in binding order 3, 4, 7, 8, 10.
 *  To process all of the bindings in a layout you can iterate from 0 to GetBindingCount()
 *  and use the Get*FromIndex() functions for each index. To just process a single binding,
 *  use the Get*FromBinding() functions.
 *
 * Global Index - The binding vector index has as many indices as there are bindings.
 *  This class also has the concept of a Global Index. For the global index functions,
 *  there are as many global indices as there are descriptors in the layout.
 *  For the global index, consider all of the bindings to be a flat array where
 *  descriptor 0 of of the lowest binding# is index 0 and each descriptor in the layout
 *  increments from there. So if the lowest binding# in this example had descriptorCount of
 *  10, then the GlobalStartIndex of the 2nd lowest binding# will be 10 where 0-9 are the
 *  global indices for the lowest binding#.
 */
class DescriptorSetLayoutDef {};

// Canonical dictionary of DSL definitions -- independent of device or handle
DescriptorSetLayoutDict;
DescriptorSetLayoutId;

static inline bool operator==(const DescriptorSetLayoutDef &lhs, const DescriptorSetLayoutDef &rhs) {}

class DescriptorSetLayout : public StateObject {};

/*
 * Descriptor classes
 *  Descriptor is an abstract base class from which 5 separate descriptor types are derived.
 *   This allows the WriteUpdate() and CopyUpdate() operations to be specialized per
 *   descriptor type, but all descriptors in a set can be accessed via the common Descriptor*.
 */

// Slightly broader than type, each c++ "class" will has a corresponding "DescriptorClass"
enum class DescriptorClass {};

DescriptorClass DescriptorTypeToClass(VkDescriptorType type);

class DescriptorSet;

class Descriptor {};

// All Dynamic descriptor types
inline bool IsDynamicDescriptor(VkDescriptorType type) {}

inline bool IsBufferDescriptor(VkDescriptorType type) {}

class SamplerDescriptor : public Descriptor {};

class ImageDescriptor : public Descriptor {};

class ImageSamplerDescriptor : public ImageDescriptor {};

class TexelDescriptor : public Descriptor {};

class BufferDescriptor : public Descriptor {};

class InlineUniformDescriptor : public Descriptor {};

class AccelerationStructureDescriptor : public Descriptor {};

class MutableDescriptor : public Descriptor {};

// Structs to contain common elements that need to be shared between Validate* and Perform* calls below
struct AllocateDescriptorSetsData {};
// "Perform" does the update with the assumption that ValidateUpdateDescriptorSets() has passed for the given update
void PerformUpdateDescriptorSets(ValidationStateTracker &, uint32_t, const VkWriteDescriptorSet *, uint32_t,
                                 const VkCopyDescriptorSet *);

class DescriptorBinding {};

template <typename T>
class DescriptorBindingImpl : public DescriptorBinding {};

SamplerBinding;
ImageBinding;
ImageSamplerBinding;
TexelBinding;
BufferBinding;
InlineUniformBinding;
AccelerationStructureBinding;
MutableBinding;

// Helper class to encapsulate the descriptor update template decoding logic
struct DecodedTemplateUpdate {};

/*
 * DescriptorSet class
 *
 * Overview - This class encapsulates the Vulkan VkDescriptorSet data (set).
 *   A set has an underlying layout which defines the bindings in the set and the
 *   types and numbers of descriptors in each descriptor slot. Most of the layout
 *   interfaces are exposed through identically-named functions in the set class.
 *   Please refer to the DescriptorSetLayout comment above for a description of
 *   index, binding, and global index.
 *
 * At construction a vector of Descriptor* is created with types corresponding to the
 *   layout. The primary operation performed on the descriptors is to update them
 *   via write or copy updates, and validate that the update contents are correct.
 *   In order to validate update contents, the DescriptorSet stores a bunch of ptrs
 *   to data maps where various Vulkan objects can be looked up. The management of
 *   those maps is performed externally. The set class relies on their contents to
 *   be correct at the time of update.
 */
class DescriptorSet : public StateObject {};

}  // namespace vvl