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

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;
	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<DescriptorSetLayout, VkDescriptorSetLayout>
{
	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_
