/*
 * Copyright (c) 2019 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef THIRD_PARTY_GITHUB_COM_ARM_SOFTWARE_HWCPIPE_VENDOR_ARM_MALI_MALI_PROFILER_MAGMA_H_
#define THIRD_PARTY_GITHUB_COM_ARM_SOFTWARE_HWCPIPE_VENDOR_ARM_MALI_MALI_PROFILER_MAGMA_H_

#include "gpu_profiler.h"

#include "hwc.hpp"

#include <functional>
#include <vector>

#include "magma.h"

namespace hwcpipe
{
/** A Gpu profiler that uses Mali counter data. */
class MaliProfilerMagma : public GpuProfiler
{
  public:
	explicit MaliProfilerMagma(const GpuCounterSet &enabled_counters);
	virtual ~MaliProfilerMagma();

	virtual const GpuCounterSet &enabled_counters() const override
	{
		return enabled_counters_;
	}

	virtual const GpuCounterSet &supported_counters() const override
	{
		return supported_counters_;
	};

	virtual void set_enabled_counters(GpuCounterSet counters) override
	{
		enabled_counters_ = std::move(counters);
	};

	virtual void                   run() override;
	virtual const GpuMeasurements &sample() override;
	virtual void                   stop() override;

  private:
	GpuCounterSet enabled_counters_{};

	const GpuCounterSet supported_counters_{
	    GpuCounter::GpuCycles,
	    GpuCounter::VertexComputeCycles,
	    GpuCounter::FragmentCycles,
	    GpuCounter::TilerCycles,
	    GpuCounter::VertexComputeJobs,
	    GpuCounter::Tiles,
	    GpuCounter::TransactionEliminations,
	    GpuCounter::FragmentJobs,
	    GpuCounter::Pixels,
	    GpuCounter::EarlyZTests,
	    GpuCounter::EarlyZKilled,
	    GpuCounter::LateZTests,
	    GpuCounter::LateZKilled,
	    GpuCounter::Instructions,
	    GpuCounter::DivergedInstructions,
	    GpuCounter::ShaderCycles,
	    GpuCounter::ShaderArithmeticCycles,
	    GpuCounter::ShaderLoadStoreCycles,
	    GpuCounter::ShaderTextureCycles,
	    GpuCounter::CacheReadLookups,
	    GpuCounter::CacheWriteLookups,
	    GpuCounter::ExternalMemoryReadAccesses,
	    GpuCounter::ExternalMemoryWriteAccesses,
	    GpuCounter::ExternalMemoryReadStalls,
	    GpuCounter::ExternalMemoryWriteStalls,
	    GpuCounter::ExternalMemoryReadBytes,
	    GpuCounter::ExternalMemoryWriteBytes,
	};

	typedef std::function<double(void)>                             MaliValueGetter;
	std::unordered_map<GpuCounter, MaliValueGetter, GpuCounterHash> mappings_{};

	int                num_cores_{0};
	int                num_l2_slices_{0};
	int                gpu_id_{0};
	size_t             buffer_size_{0};
	magma_buffer_t     buffer_ = 0;
	uint64_t           timestamp_{0};
	const char *const *names_lut_{
	    nullptr};
	std::vector<uint32_t>     raw_counter_buffer_{};
	std::vector<unsigned int> core_index_remap_{};
	magma_device_t            device_ = 0;
	magma_connection_t        connection_{};
	magma_perf_count_pool_t   pool_{};
	magma_handle_t            notification_handle_ = 0;

	GpuMeasurements measurements_{};

	void            init();
	void            sample_counters();
	void            wait_next_event();
	const uint32_t *get_counters(mali_userspace::MaliCounterBlockName block, int index = 0) const;
	uint64_t        get_counter_value(mali_userspace::MaliCounterBlockName block, const char *name) const;
	int             find_counter_index_by_name(mali_userspace::MaliCounterBlockName block, const char *name) const;
};

}        // namespace hwcpipe

#endif        // THIRD_PARTY_GITHUB_COM_ARM_SOFTWARE_HWCPIPE_VENDOR_ARM_MALI_MALI_PROFILER_MAGMA_H_
