mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
Fixes a lockup in World of Warships, which waits for an event query to be signaled without actually ever calling End() for that query.
214 lines
4.7 KiB
C++
214 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include <mutex>
|
|
|
|
#include "dxvk_limits.h"
|
|
|
|
namespace dxvk {
|
|
|
|
/**
|
|
* \brief Query status
|
|
*
|
|
* Allows the application to query
|
|
* the current status of the query.
|
|
*/
|
|
enum class DxvkQueryStatus : uint32_t {
|
|
Reset = 0, ///< Query is reset
|
|
Active = 1, ///< Query is being recorded
|
|
Pending = 2, ///< Query has been recorded
|
|
Available = 3, ///< Query results can be retrieved
|
|
};
|
|
|
|
/**
|
|
* \brief Occlusion query data
|
|
*
|
|
* Stores the number of samples
|
|
* that passes fragment tests.
|
|
*/
|
|
struct DxvkQueryOcclusionData {
|
|
uint64_t samplesPassed;
|
|
};
|
|
|
|
/**
|
|
* \brief Timestamp data
|
|
*
|
|
* Stores a GPU time stamp.
|
|
*/
|
|
struct DxvkQueryTimestampData {
|
|
uint64_t time;
|
|
};
|
|
|
|
/**
|
|
* \brief Pipeline statistics
|
|
*
|
|
* Stores the counters for
|
|
* pipeline statistics queries.
|
|
*/
|
|
struct DxvkQueryStatisticData {
|
|
uint64_t iaVertices;
|
|
uint64_t iaPrimitives;
|
|
uint64_t vsInvocations;
|
|
uint64_t gsInvocations;
|
|
uint64_t gsPrimitives;
|
|
uint64_t clipInvocations;
|
|
uint64_t clipPrimitives;
|
|
uint64_t fsInvocations;
|
|
uint64_t tcsPatches;
|
|
uint64_t tesInvocations;
|
|
uint64_t csInvocations;
|
|
};
|
|
|
|
/**
|
|
* \brief Query data
|
|
*
|
|
* A union that stores query data. Select an
|
|
* appropriate member based on the query type.
|
|
*/
|
|
union DxvkQueryData {
|
|
DxvkQueryOcclusionData occlusion;
|
|
DxvkQueryTimestampData timestamp;
|
|
DxvkQueryStatisticData statistic;
|
|
};
|
|
|
|
/**
|
|
* \brief Query entry
|
|
*
|
|
* Stores the pool handle and the
|
|
* index of a single Vulkan query.
|
|
*/
|
|
struct DxvkQueryHandle {
|
|
VkQueryPool queryPool = VK_NULL_HANDLE;
|
|
uint32_t queryId = 0;
|
|
VkQueryControlFlags flags = 0;
|
|
};
|
|
|
|
/**
|
|
* \brief Query object
|
|
*
|
|
* Represents a single virtual query. Since queries
|
|
* in Vulkan cannot be active across command buffer
|
|
* submissions, we need to
|
|
*/
|
|
class DxvkQuery : public RcObject {
|
|
|
|
public:
|
|
|
|
DxvkQuery(
|
|
VkQueryType type,
|
|
VkQueryControlFlags flags);
|
|
~DxvkQuery();
|
|
|
|
/**
|
|
* \brief Query type
|
|
* \returns Query type
|
|
*/
|
|
VkQueryType type() const {
|
|
return m_type;
|
|
}
|
|
|
|
/**
|
|
* \brief Query control flags
|
|
*
|
|
* Flags that will be applied when
|
|
* calling \c vkCmdBeginQuery.
|
|
* \returns Query control flags
|
|
*/
|
|
VkQueryControlFlags flags() const {
|
|
return m_flags;
|
|
}
|
|
|
|
/**
|
|
* \brief Resets the query object
|
|
*
|
|
* Increments the revision number which will
|
|
* be used to determine when query data becomes
|
|
* available. All asynchronous query operations
|
|
* will take the revision number as an argument.
|
|
* \returns The new query revision number
|
|
*/
|
|
uint32_t reset();
|
|
|
|
/**
|
|
* \brief Retrieves query data
|
|
*
|
|
* \param [out] data Query data
|
|
* \returns Query status
|
|
*/
|
|
DxvkQueryStatus getData(
|
|
DxvkQueryData& data);
|
|
|
|
/**
|
|
* \brief Gets current query handle
|
|
* \returns The current query handle
|
|
*/
|
|
DxvkQueryHandle getHandle();
|
|
|
|
/**
|
|
* \brief Begins recording the query
|
|
*
|
|
* Sets internal query state to 'active'.
|
|
* \param [in] revision Query version ID
|
|
*/
|
|
void beginRecording(uint32_t revision);
|
|
|
|
/**
|
|
* \brief Ends recording the query
|
|
*
|
|
* Sets internal query state to 'pending'.
|
|
* \param [in] revision Query version ID
|
|
*/
|
|
void endRecording(uint32_t revision);
|
|
|
|
/**
|
|
* \brief Increments internal query count
|
|
*
|
|
* The internal query count is used to determine
|
|
* when the query data is actually available.
|
|
* \param [in] revision Query version ID
|
|
* \param [in] handle The query handle
|
|
*/
|
|
void associateQuery(
|
|
uint32_t revision,
|
|
DxvkQueryHandle handle);
|
|
|
|
/**
|
|
* \brief Updates query data
|
|
*
|
|
* Called by the command submission thread after
|
|
* the Vulkan queries have been evaluated.
|
|
* \param [in] revision Query version ID
|
|
* \param [in] data Query data
|
|
*/
|
|
void updateData(
|
|
uint32_t revision,
|
|
const DxvkQueryData& data);
|
|
|
|
private:
|
|
|
|
const VkQueryType m_type;
|
|
const VkQueryControlFlags m_flags;
|
|
|
|
std::mutex m_mutex;
|
|
|
|
DxvkQueryStatus m_status = DxvkQueryStatus::Available;
|
|
DxvkQueryData m_data = {};
|
|
DxvkQueryHandle m_handle;
|
|
|
|
uint32_t m_queryIndex = 0;
|
|
uint32_t m_queryCount = 0;
|
|
uint64_t m_revision = 0;
|
|
|
|
};
|
|
|
|
/**
|
|
* \brief Query revision
|
|
*
|
|
* Stores the query object and the
|
|
* version ID for query operations.
|
|
*/
|
|
struct DxvkQueryRevision {
|
|
Rc<DxvkQuery> query;
|
|
uint32_t revision;
|
|
};
|
|
|
|
} |