Basic DescriptorPool and DescriptorSetLayout implementation
This cl is a minimal implementation of DescriptorPool and
DescriptorSetLayout.
A DescriptorSet itself is just a straight memory pointer.
A DescriptorPool is a memory pool where DescriptorSets are
allocated. The DescriptorPool object itself is little more
than a memory allocator.
A few minor optimizations were made to speed up the default
case:
- The Descriptor pool starts looking for a large enough
memory block at the end of the pool, which should be optimal
if the DescriptorSets are allocated linearly
- When allocating multiple DescriptorSets at once, the pool
first attempts to allocated all of them contiguously. This
prevents looking for free memory blocks multiple times and
once again should be optimal if the DescriptorSets are
allocated linearly
Note: For now, DescriptorSetLayout::GetDescriptorSize() is a
dummy function which always returns the same size for
every Descriptor type. This will be implemented properly
case by case as we add support for new Descriptor types.
Passes all tests in:
dEQP-VK.api.*descriptor*
Bug b/123244275
Change-Id: I2a2e73396e38dae28b59b77243cd8a366b35c12c
Reviewed-on: https://swiftshader-review.googlesource.com/c/24028
Tested-by: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkDescriptorPool.hpp b/src/Vulkan/VkDescriptorPool.hpp
new file mode 100644
index 0000000..baa64f9
--- /dev/null
+++ b/src/Vulkan/VkDescriptorPool.hpp
@@ -0,0 +1,64 @@
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
+//
+// 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.
+
+#ifndef VK_DESCRIPTOR_POOL_HPP_
+#define VK_DESCRIPTOR_POOL_HPP_
+
+#include "VkObject.hpp"
+#include <set>
+
+namespace vk
+{
+ class DescriptorPool : public Object<DescriptorPool, VkDescriptorPool>
+ {
+ public:
+ DescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, void* mem);
+ ~DescriptorPool() = delete;
+ void destroy(const VkAllocationCallbacks* pAllocator);
+
+ static size_t ComputeRequiredAllocationSize(const VkDescriptorPoolCreateInfo* pCreateInfo);
+
+ VkResult allocateSets(uint32_t descriptorSetCount, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets);
+ void freeSets(uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets);
+ VkResult reset();
+
+ private:
+ VkResult allocateSets(size_t* sizes, uint32_t numAllocs, VkDescriptorSet* pDescriptorSets);
+ VkDescriptorSet findAvailableMemory(size_t size);
+ void freeSet(const VkDescriptorSet descriptorSet);
+ size_t computeTotalFreeSize() const;
+
+ struct Node
+ {
+ Node(VkDescriptorSet set, size_t size) : set(set), size(size) {}
+ bool operator<(const Node& node) const { return this->set < node.set; }
+ bool operator==(VkDescriptorSet set) const { return this->set == set; }
+
+ VkDescriptorSet set;
+ size_t size;
+ };
+ std::set<Node> nodes;
+
+ VkDescriptorSet pool = nullptr;
+ size_t poolSize = 0;
+ };
+
+ static inline DescriptorPool* Cast(VkDescriptorPool object)
+ {
+ return reinterpret_cast<DescriptorPool*>(object);
+ }
+
+} // namespace vk
+
+#endif // VK_DESCRIPTOR_POOL_HPP_