/* 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