2019-07-28 00:40:10 +02:00
|
|
|
// Copyright 2019 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
#include <array>
|
|
|
|
#include <memory>
|
|
|
|
#include <optional>
|
2019-11-28 06:15:34 +01:00
|
|
|
#include <unordered_map>
|
2019-11-26 22:52:15 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2019-07-28 00:40:10 +02:00
|
|
|
#include <glad/glad.h>
|
|
|
|
|
|
|
|
#include "common/common_types.h"
|
2019-11-26 22:52:15 +01:00
|
|
|
#include "video_core/rasterizer_interface.h"
|
2019-07-28 00:40:10 +02:00
|
|
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
namespace Core {
|
|
|
|
class System;
|
|
|
|
}
|
|
|
|
|
2019-07-28 00:40:10 +02:00
|
|
|
namespace OpenGL {
|
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
class CachedQuery;
|
|
|
|
class HostCounter;
|
|
|
|
class RasterizerOpenGL;
|
|
|
|
class QueryCache;
|
|
|
|
|
|
|
|
class CounterStream final {
|
2019-07-28 00:40:10 +02:00
|
|
|
public:
|
2019-11-26 22:52:15 +01:00
|
|
|
explicit CounterStream(QueryCache& cache, VideoCore::QueryType type);
|
|
|
|
~CounterStream();
|
|
|
|
|
|
|
|
void Update(bool enabled, bool any_command_queued);
|
|
|
|
|
|
|
|
void Reset(bool any_command_queued);
|
|
|
|
|
|
|
|
std::shared_ptr<HostCounter> GetCurrent(bool any_command_queued);
|
|
|
|
|
|
|
|
bool IsEnabled() const {
|
|
|
|
return current != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2019-11-28 06:15:34 +01:00
|
|
|
void Enable();
|
|
|
|
|
|
|
|
void Disable(bool any_command_queued);
|
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
void EndQuery(bool any_command_queued);
|
|
|
|
|
|
|
|
QueryCache& cache;
|
|
|
|
|
|
|
|
std::shared_ptr<HostCounter> current;
|
|
|
|
std::shared_ptr<HostCounter> last;
|
|
|
|
VideoCore::QueryType type;
|
|
|
|
GLenum target;
|
|
|
|
};
|
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
class QueryCache final {
|
2019-11-26 22:52:15 +01:00
|
|
|
public:
|
|
|
|
explicit QueryCache(Core::System& system, RasterizerOpenGL& rasterizer);
|
|
|
|
~QueryCache();
|
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
void InvalidateRegion(CacheAddr addr, std::size_t size);
|
|
|
|
|
|
|
|
void FlushRegion(CacheAddr addr, std::size_t size);
|
|
|
|
|
|
|
|
void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp);
|
2019-11-26 22:52:15 +01:00
|
|
|
|
|
|
|
void UpdateCounters();
|
|
|
|
|
|
|
|
void ResetCounter(VideoCore::QueryType type);
|
2019-07-28 00:40:10 +02:00
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
void Reserve(VideoCore::QueryType type, OGLQuery&& query);
|
2019-07-28 00:40:10 +02:00
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
std::shared_ptr<HostCounter> GetHostCounter(std::shared_ptr<HostCounter> dependency,
|
|
|
|
VideoCore::QueryType type);
|
|
|
|
|
|
|
|
private:
|
2019-11-28 06:15:34 +01:00
|
|
|
CachedQuery& Register(CachedQuery&& cached_query);
|
|
|
|
|
|
|
|
CachedQuery* TryGet(CacheAddr addr);
|
|
|
|
|
|
|
|
void Flush(CachedQuery& cached_query);
|
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
CounterStream& GetStream(VideoCore::QueryType type);
|
|
|
|
|
|
|
|
Core::System& system;
|
|
|
|
RasterizerOpenGL& rasterizer;
|
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
std::unordered_map<u64, std::vector<CachedQuery>> cached_queries;
|
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
std::array<CounterStream, VideoCore::NumQueryTypes> streams;
|
|
|
|
std::array<std::vector<OGLQuery>, VideoCore::NumQueryTypes> reserved_queries;
|
|
|
|
};
|
|
|
|
|
|
|
|
class HostCounter final {
|
|
|
|
public:
|
|
|
|
explicit HostCounter(QueryCache& cache, std::shared_ptr<HostCounter> dependency,
|
|
|
|
VideoCore::QueryType type, OGLQuery&& query);
|
|
|
|
~HostCounter();
|
2019-07-28 00:40:10 +02:00
|
|
|
|
|
|
|
/// Returns the current value of the query.
|
|
|
|
u64 Query();
|
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
/// Returns true when querying this counter will potentially wait for OpenGL.
|
|
|
|
bool WaitPending() const noexcept;
|
|
|
|
|
2019-07-28 00:40:10 +02:00
|
|
|
private:
|
2019-11-26 22:52:15 +01:00
|
|
|
QueryCache& cache;
|
|
|
|
VideoCore::QueryType type;
|
2019-07-28 00:40:10 +02:00
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
std::shared_ptr<HostCounter> dependency; ///< Counter queued before this one.
|
|
|
|
OGLQuery query; ///< OpenGL query.
|
2019-11-28 06:15:34 +01:00
|
|
|
std::optional<u64> result; ///< Added values of the counter.
|
2019-11-26 22:52:15 +01:00
|
|
|
};
|
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
class CachedQuery final {
|
2019-11-26 22:52:15 +01:00
|
|
|
public:
|
|
|
|
explicit CachedQuery(VideoCore::QueryType type, VAddr cpu_addr, u8* host_ptr);
|
2019-11-28 06:15:34 +01:00
|
|
|
CachedQuery(CachedQuery&&) noexcept;
|
|
|
|
CachedQuery(const CachedQuery&) = delete;
|
2019-11-26 22:52:15 +01:00
|
|
|
~CachedQuery();
|
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
CachedQuery& operator=(CachedQuery&&) noexcept;
|
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
/// Writes the counter value to host memory.
|
|
|
|
void Flush();
|
|
|
|
|
|
|
|
/// Updates the counter this cached query registered in guest memory will write when requested.
|
2019-11-28 06:15:34 +01:00
|
|
|
void SetCounter(std::shared_ptr<HostCounter> counter, std::optional<u64> timestamp);
|
|
|
|
|
|
|
|
/// Returns true when a flushing this query will potentially wait for OpenGL.
|
|
|
|
bool WaitPending() const noexcept;
|
2019-07-28 00:40:10 +02:00
|
|
|
|
2019-11-26 22:52:15 +01:00
|
|
|
/// Returns the query type.
|
2019-11-28 06:15:34 +01:00
|
|
|
VideoCore::QueryType GetType() const noexcept;
|
2019-11-26 22:52:15 +01:00
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
/// Returns the guest CPU address for this query.
|
|
|
|
VAddr GetCpuAddr() const noexcept;
|
2019-11-26 22:52:15 +01:00
|
|
|
|
2019-11-28 06:15:34 +01:00
|
|
|
/// Returns the cache address for this query.
|
|
|
|
CacheAddr GetCacheAddr() const noexcept;
|
|
|
|
|
|
|
|
/// Returns the number of cached bytes.
|
|
|
|
u64 GetSizeInBytes() const noexcept;
|
2019-11-26 22:52:15 +01:00
|
|
|
|
|
|
|
private:
|
2019-11-28 06:15:34 +01:00
|
|
|
VideoCore::QueryType type; ///< Abstracted query type (e.g. samples passed).
|
2019-11-26 22:52:15 +01:00
|
|
|
VAddr cpu_addr; ///< Guest CPU address.
|
|
|
|
u8* host_ptr; ///< Writable host pointer.
|
|
|
|
std::shared_ptr<HostCounter> counter; ///< Host counter to query, owns the dependency tree.
|
2019-11-28 06:15:34 +01:00
|
|
|
std::optional<u64> timestamp; ///< Timestamp to flush to guest memory.
|
2019-07-28 00:40:10 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace OpenGL
|