#pragma once

#include <psemek/wgpu/detail/object.hpp>
#include <psemek/wgpu/chained_struct.hpp>
#include <psemek/wgpu/pipeline_layout.hpp>
#include <psemek/wgpu/bind_group_layout.hpp>
#include <psemek/wgpu/shader_module.hpp>
#include <psemek/wgpu/constant_entry.hpp>

#include <string>
#include <cstdint>

namespace psemek::wgpu
{

	struct programmable_stage_descriptor
	{
		std::vector<chained_struct> chain = {};
		shader_module module;
		std::string entry_point;
		std::vector<constant_entry> constants = {};
	};

	struct compute_pipeline
		: detail::object<compute_pipeline>
	{
		using detail::object<compute_pipeline>::object;

		struct descriptor
		{
			std::vector<chained_struct> chain = {};
			std::string label = {};
			pipeline_layout layout;
			programmable_stage_descriptor compute;
		};

		bind_group_layout get_bind_group_layout(std::uint32_t index) const;
		void set_label(std::string const & label);

		static void reference(void * ptr);
		static void release(void * ptr);

	private:
		explicit compute_pipeline(void * ptr)
			: detail::object<compute_pipeline>(ptr)
		{}

		friend struct device;
	};

}
