1// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef VK_DESCRIPTOR_SET_LAYOUT_HPP_
16#define VK_DESCRIPTOR_SET_LAYOUT_HPP_
17
18#include "VkObject.hpp"
19
20#include "Vulkan/VkSampler.hpp"
21#include "Vulkan/VkImageView.hpp"
22#include "Device/Sampler.hpp"
23
24namespace vk
25{
26
27class DescriptorSet;
28class Device;
29
30// TODO(b/129523279): Move to the Device or Pipeline layer.
31struct alignas(16) SampledImageDescriptor
32{
33 ~SampledImageDescriptor() = delete;
34
35 void updateSampler(VkSampler sampler);
36
37 // TODO(b/129523279): Minimize to the data actually needed.
38 vk::Sampler sampler;
39 vk::Device* device;
40
41 uint32_t imageViewId;
42 VkImageViewType type;
43 VkFormat format;
44 VkComponentMapping swizzle;
45 alignas(16) sw::Texture texture;
46 VkExtent3D extent; // Of base mip-level.
47 int arrayLayers;
48 int mipLevels;
49 int sampleCount;
50};
51
52struct alignas(16) StorageImageDescriptor
53{
54 ~StorageImageDescriptor() = delete;
55
56 void *ptr;
57 VkExtent3D extent;
58 int rowPitchBytes;
59 int slicePitchBytes;
60 int samplePitchBytes;
61 int arrayLayers;
62 int sampleCount;
63 int sizeInBytes;
64
65 void *stencilPtr;
66 int stencilRowPitchBytes;
67 int stencilSlicePitchBytes;
68 int stencilSamplePitchBytes;
69};
70
71struct alignas(16) BufferDescriptor
72{
73 ~BufferDescriptor() = delete;
74
75 void *ptr;
76 int sizeInBytes; // intended size of the bound region -- slides along with dynamic offsets
77 int robustnessSize; // total accessible size from static offset -- does not move with dynamic offset
78};
79
80class DescriptorSetLayout : public Object<DescriptorSetLayout, VkDescriptorSetLayout>
81{
82public:
83 DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo* pCreateInfo, void* mem);
84 void destroy(const VkAllocationCallbacks* pAllocator);
85
86 static size_t ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo* pCreateInfo);
87
88 static size_t GetDescriptorSize(VkDescriptorType type);
89 static void WriteDescriptorSet(Device* device, const VkWriteDescriptorSet& descriptorWrites);
90 static void CopyDescriptorSet(const VkCopyDescriptorSet& descriptorCopies);
91
92 static void WriteDescriptorSet(Device* device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src);
93 static void WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP);
94
95 void initialize(DescriptorSet* descriptorSet);
96
97 // Returns the total size of the descriptor set in bytes.
98 size_t getDescriptorSetAllocationSize() const;
99
100 // Returns the number of bindings in the descriptor set.
101 size_t getBindingCount() const;
102
103 // Returns true iff the given binding exists.
104 bool hasBinding(uint32_t binding) const;
105
106 // Returns the byte offset from the base address of the descriptor set for
107 // the given binding and array element within that binding.
108 size_t getBindingOffset(uint32_t binding, size_t arrayElement) const;
109
110 // Returns the stride of an array of descriptors
111 size_t getBindingStride(uint32_t binding) const;
112
113 // Returns the number of descriptors across all bindings that are dynamic
114 // (see isBindingDynamic).
115 uint32_t getDynamicDescriptorCount() const;
116
117 // Returns the relative offset into the pipeline's dynamic offsets array for
118 // the given binding. This offset should be added to the base offset
119 // returned by PipelineLayout::getDynamicOffsetBase() to produce the
120 // starting index for dynamic descriptors.
121 uint32_t getDynamicDescriptorOffset(uint32_t binding) const;
122
123 // Returns true if the given binding is of type:
124 // VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or
125 // VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
126 bool isBindingDynamic(uint32_t binding) const;
127
128 // Returns the VkDescriptorSetLayoutBinding for the given binding.
129 VkDescriptorSetLayoutBinding const & getBindingLayout(uint32_t binding) const;
130
131 uint8_t* getOffsetPointer(DescriptorSet *descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t* typeSize) const;
132
133private:
134 size_t getDescriptorSetDataSize() const;
135 uint32_t getBindingIndex(uint32_t binding) const;
136 static bool isDynamic(VkDescriptorType type);
137
138 VkDescriptorSetLayoutCreateFlags flags;
139 uint32_t bindingCount;
140 VkDescriptorSetLayoutBinding* bindings;
141 size_t* bindingOffsets;
142};
143
144static inline DescriptorSetLayout* Cast(VkDescriptorSetLayout object)
145{
146 return DescriptorSetLayout::Cast(object);
147}
148
149} // namespace vk
150
151#endif // VK_DESCRIPTOR_SET_LAYOUT_HPP_
152