// 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_SET_LAYOUT_HPP_ #define VK_DESCRIPTOR_SET_LAYOUT_HPP_ #include "VkObject.hpp" #include "Device/Sampler.hpp" #include "Vulkan/VkImageView.hpp" #include "Vulkan/VkSampler.hpp" #include namespace vk { class DescriptorSet; class Device; // TODO(b/129523279): Move to the Device or Pipeline layer. struct alignas(16) SampledImageDescriptor { ~SampledImageDescriptor() = delete; void updateSampler(const vk::Sampler *sampler); // TODO(b/129523279): Minimize to the data actually needed. vk::Sampler sampler; vk::Device *device; uint32_t imageViewId; VkImageViewType type; VkFormat format; VkComponentMapping swizzle; alignas(16) sw::Texture texture; int width; // Of base mip-level. int height; int depth; // Layer/cube count for arrayed images int mipLevels; int sampleCount; ImageView *memoryOwner; // Pointer to the view which owns the memory used by the descriptor set }; struct alignas(16) StorageImageDescriptor { ~StorageImageDescriptor() = delete; void *ptr; int width; int height; int depth; // Layer/cube count for arrayed images int rowPitchBytes; int slicePitchBytes; // Layer pitch in case of array image int samplePitchBytes; int sampleCount; int sizeInBytes; void *stencilPtr; int stencilRowPitchBytes; int stencilSlicePitchBytes; // Layer pitch in case of array image int stencilSamplePitchBytes; ImageView *memoryOwner; // Pointer to the view which owns the memory used by the descriptor set }; struct alignas(16) BufferDescriptor { ~BufferDescriptor() = delete; void *ptr; int sizeInBytes; // intended size of the bound region -- slides along with dynamic offsets int robustnessSize; // total accessible size from static offset -- does not move with dynamic offset }; class DescriptorSetLayout : public Object { struct Binding { VkDescriptorType descriptorType; uint32_t descriptorCount; const vk::Sampler **immutableSamplers; uint32_t offset; // Offset in bytes in the descriptor set data. }; public: DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *pCreateInfo, void *mem); void destroy(const VkAllocationCallbacks *pAllocator); static size_t ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo *pCreateInfo); static uint32_t GetDescriptorSize(VkDescriptorType type); static bool IsDescriptorDynamic(VkDescriptorType type); static void WriteDescriptorSet(Device *device, const VkWriteDescriptorSet &descriptorWrites); static void CopyDescriptorSet(const VkCopyDescriptorSet &descriptorCopies); static void WriteDescriptorSet(Device *device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src); static void WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP, int samplePitchP, int sampleMax); void initialize(DescriptorSet *descriptorSet); // Returns the total size of the descriptor set in bytes. size_t getDescriptorSetAllocationSize() const; // Returns the byte offset from the base address of the descriptor set for // the given binding number. uint32_t getBindingOffset(uint32_t bindingNumber) const; // Returns the number of descriptors for the given binding number. uint32_t getDescriptorCount(uint32_t bindingNumber) const; // Returns the number of descriptors across all bindings that are dynamic. uint32_t getDynamicDescriptorCount() const; // Returns the relative index into the pipeline's dynamic offsets array for // the given binding number. This index should be added to the base index // returned by PipelineLayout::getDynamicOffsetBase() to produce the // starting index for dynamic descriptors. uint32_t getDynamicOffsetIndex(uint32_t bindingNumber) const; // Returns the descriptor type for the given binding number. VkDescriptorType getDescriptorType(uint32_t bindingNumber) const; // Returns the number of entries in the direct-indexed array of bindings. // It equals the highest binding number + 1. uint32_t getBindingsArraySize() const { return bindingsArraySize; } private: uint8_t *getDescriptorPointer(DescriptorSet *descriptorSet, uint32_t bindingNumber, uint32_t arrayElement, uint32_t count, size_t *typeSize) const; size_t getDescriptorSetDataSize() const; static bool isDynamic(VkDescriptorType type); const VkDescriptorSetLayoutCreateFlags flags; uint32_t bindingsArraySize = 0; Binding *const bindings; // Direct-indexed array of bindings. }; static inline DescriptorSetLayout *Cast(VkDescriptorSetLayout object) { return DescriptorSetLayout::Cast(object); } } // namespace vk #endif // VK_DESCRIPTOR_SET_LAYOUT_HPP_