1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 19:24:12 +01:00

[dxvk] Implemented more query and query pool methods

This commit is contained in:
Philip Rebohle 2018-02-13 13:43:27 +01:00
parent 5beae25bdf
commit 54cfdbdc51
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
10 changed files with 263 additions and 31 deletions

View File

@ -47,24 +47,44 @@ namespace dxvk {
DxvkContextFlag::CpDirtyPipeline,
DxvkContextFlag::CpDirtyPipelineState,
DxvkContextFlag::CpDirtyResources);
// Restart queries that were active during
// the last command buffer submission.
this->beginActiveQueries();
}
Rc<DxvkCommandList> DxvkContext::endRecording() {
this->renderPassEnd();
this->endActiveQueries();
m_cmd->endRecording();
return std::exchange(m_cmd, nullptr);
}
void DxvkContext::beginQuery(const Rc<DxvkQuery>& query) {
// TODO implement
void DxvkContext::beginQuery(const DxvkQueryRevision& query) {
DxvkQueryHandle handle; // TODO = allocateQuery(...)
m_cmd->cmdBeginQuery(
handle.queryPool,
handle.queryId,
0);
query.query->beginRecording(query.revision);
this->insertActiveQuery(query);
}
void DxvkContext::endQuery(const Rc<DxvkQuery>& query) {
// TODO implement
void DxvkContext::endQuery(const DxvkQueryRevision& query) {
DxvkQueryHandle handle = query.query->getHandle();
m_cmd->cmdEndQuery(
handle.queryPool,
handle.queryId);
query.query->endRecording(query.revision);
this->eraseActiveQuery(query);
}
@ -1581,4 +1601,51 @@ namespace dxvk {
m_barriers.recordCommands(m_cmd);
}
void DxvkContext::resetQueryPool(const Rc<DxvkQueryPool>& pool) {
this->renderPassEnd();
m_cmd->cmdResetQueryPool(
pool->handle(), 0,
pool->queryCount());
}
void DxvkContext::beginActiveQueries() {
for (const DxvkQueryRevision& query : m_activeQueries) {
DxvkQueryHandle handle; // TODO = allocateQuery(...)
m_cmd->cmdBeginQuery(
handle.queryPool,
handle.queryId,
0);
}
}
void DxvkContext::endActiveQueries() {
for (const DxvkQueryRevision& query : m_activeQueries) {
DxvkQueryHandle handle = query.query->getHandle();
m_cmd->cmdEndQuery(
handle.queryPool,
handle.queryId);
}
}
void DxvkContext::insertActiveQuery(const DxvkQueryRevision& query) {
m_activeQueries.push_back(query);
}
void DxvkContext::eraseActiveQuery(const DxvkQueryRevision& query) {
for (auto i = m_activeQueries.begin(); i != m_activeQueries.end(); i++) {
if (i->query == query.query && i->revision == query.revision) {
m_activeQueries.erase(i);
return;
}
}
}
}

View File

@ -5,7 +5,7 @@
#include "dxvk_cmdlist.h"
#include "dxvk_context_state.h"
#include "dxvk_data.h"
#include "dxvk_query.h"
#include "dxvk_query_pool.h"
#include "dxvk_util.h"
namespace dxvk {
@ -49,19 +49,18 @@ namespace dxvk {
Rc<DxvkCommandList> endRecording();
/**
* \brief Begins gathering query data
* \brief Begins generating query data
* \param [in] query The query to end
*/
void beginQuery(
const Rc<DxvkQuery>& query);
const DxvkQueryRevision& query);
/**
* \brief Ends gathering query data
*
* \brief Ends generating query data
* \param [in] query The query to end
*/
void endQuery(
const Rc<DxvkQuery>& query);
const DxvkQueryRevision& query);
/**
* \brief Sets framebuffer
@ -555,6 +554,8 @@ namespace dxvk {
VkPipeline m_gpActivePipeline = VK_NULL_HANDLE;
VkPipeline m_cpActivePipeline = VK_NULL_HANDLE;
std::vector<DxvkQueryRevision> m_activeQueries;
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
std::array<DxvkDescriptorInfo, MaxNumActiveBindings> m_descInfos;
std::array<VkWriteDescriptorSet, MaxNumActiveBindings> m_descWrites;
@ -594,6 +595,19 @@ namespace dxvk {
void commitComputeBarriers();
void resetQueryPool(
const Rc<DxvkQueryPool>& pool);
void beginActiveQueries();
void endActiveQueries();
void insertActiveQuery(
const DxvkQueryRevision& query);
void eraseActiveQuery(
const DxvkQueryRevision& query);
};
}

View File

@ -145,6 +145,12 @@ namespace dxvk {
}
Rc<DxvkQueryPool> DxvkDevice::createQueryPool(
VkQueryType queryType) {
return new DxvkQueryPool(m_vkd, queryType);
}
Rc<DxvkSampler> DxvkDevice::createSampler(
const DxvkSamplerCreateInfo& createInfo) {
return new DxvkSampler(m_vkd, createInfo);

View File

@ -13,6 +13,7 @@
#include "dxvk_pipecache.h"
#include "dxvk_pipemanager.h"
#include "dxvk_queue.h"
#include "dxvk_query_pool.h"
#include "dxvk_recycler.h"
#include "dxvk_renderpass.h"
#include "dxvk_sampler.h"
@ -206,6 +207,13 @@ namespace dxvk {
const Rc<DxvkImage>& image,
const DxvkImageViewCreateInfo& createInfo);
/**
* \brief Creates a query pool
* \param [in] queryType Query type
*/
Rc<DxvkQueryPool> createQueryPool(
VkQueryType queryType);
/**
* \brief Creates a sampler object
*

View File

@ -13,7 +13,7 @@ namespace dxvk {
MaxNumResourceSlots = 1096,
MaxNumActiveBindings = 128,
MaxNumQueuedCommandBuffers = 8,
MaxNumQueryCountPerPool = 16,
MaxNumQueryCountPerPool = 128,
MaxVertexBindingStride = 2048,
MaxPushConstantSize = 128,
};

View File

@ -36,6 +36,11 @@ namespace dxvk {
}
DxvkQueryHandle DxvkQuery::getHandle() {
return m_handle;
}
void DxvkQuery::beginRecording(uint32_t revision) {
std::unique_lock<std::mutex> lock(m_mutex);
@ -47,16 +52,28 @@ namespace dxvk {
void DxvkQuery::endRecording(uint32_t revision) {
std::unique_lock<std::mutex> lock(m_mutex);
if (m_revision == revision)
m_status = DxvkQueryStatus::Pending;
if (m_revision == revision) {
if (m_queryIndex < m_queryCount) {
m_status = DxvkQueryStatus::Pending;
} else {
m_status = DxvkQueryStatus::Available;
m_signal.notify_all();
}
m_handle = DxvkQueryHandle();
}
}
void DxvkQuery::associateQuery(uint32_t revision) {
void DxvkQuery::associateQuery(uint32_t revision, DxvkQueryHandle handle) {
std::unique_lock<std::mutex> lock(m_mutex);
if (m_revision == revision)
m_queryCount += 1;
// Assign the handle either way as this
// will be used by the DXVK context.
m_handle = handle;
}

View File

@ -71,6 +71,17 @@ namespace dxvk {
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;
};
/**
* \brief Query object
*
@ -105,6 +116,12 @@ namespace dxvk {
DxvkQueryStatus getData(
DxvkQueryData& data);
/**
* \brief Gets current query handle
* \returns The current query handle
*/
DxvkQueryHandle getHandle();
/**
* \brief Begins recording the query
*
@ -127,8 +144,11 @@ namespace dxvk {
* 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);
void associateQuery(
uint32_t revision,
DxvkQueryHandle handle);
/**
* \brief Updates query data
@ -151,6 +171,7 @@ namespace dxvk {
DxvkQueryStatus m_status = DxvkQueryStatus::Reset;
DxvkQueryData m_data = {};
DxvkQueryHandle m_handle;
uint32_t m_queryIndex = 0;
uint32_t m_queryCount = 0;
@ -158,4 +179,15 @@ namespace dxvk {
};
/**
* \brief Query revision
*
* Stores the query object and the
* version ID for query operations.
*/
struct DxvkQueryRevision {
Rc<DxvkQuery> query;
uint32_t revision;
};
}

View File

@ -3,15 +3,73 @@
namespace dxvk {
DxvkQueryPool::DxvkQueryPool(
const Rc<vk::DeviceFn>& fn,
VkQueryType queryType,
uint32_t queryCount) {
const Rc<vk::DeviceFn>& vkd,
VkQueryType queryType)
: m_vkd(vkd), m_queryType(queryType) {
VkQueryPoolCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
info.queryType = queryType;
info.queryCount = MaxNumQueryCountPerPool;
info.pipelineStatistics = 0;
if (queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
info.pipelineStatistics
= VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT
| VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT
| VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT
| VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT
| VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT
| VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT
| VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT
| VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT
| VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT
| VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT
| VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT;
}
if (m_vkd->vkCreateQueryPool(m_vkd->device(), &info, nullptr, &m_queryPool) != VK_SUCCESS)
Logger::err("DxvkQueryPool: Failed to create query pool");
}
DxvkQueryPool::~DxvkQueryPool() {
m_vkd->vkDestroyQueryPool(
m_vkd->device(), m_queryPool, nullptr);
}
DxvkQueryHandle DxvkQueryPool::allocQuery(const DxvkQueryRevision& query) {
const DxvkQueryHandle result = { m_queryPool, m_queryId };
query.query->associateQuery(query.revision, result);
m_queries.at(m_queryId) = query;
m_queryId += 1;
return result;
}
VkResult DxvkQueryPool::getData(
uint32_t queryIndex,
uint32_t queryCount) {
std::array<DxvkQueryData, MaxNumQueryCountPerPool> results;
const VkResult status = m_vkd->vkGetQueryPoolResults(
m_vkd->device(), m_queryPool, queryIndex, queryCount,
sizeof(DxvkQueryData) * MaxNumQueryCountPerPool,
results.data(), sizeof(DxvkQueryData),
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
if (status != VK_SUCCESS)
return status;
for (uint32_t i = 0; i < queryCount; i++) {
const DxvkQueryRevision& query = m_queries.at(queryIndex + i);
query.query->updateData(query.revision, results.at(i));
}
return VK_SUCCESS;
}
}

View File

@ -16,18 +16,56 @@ namespace dxvk {
public:
DxvkQueryPool(
const Rc<vk::DeviceFn>& fn,
VkQueryType queryType,
uint32_t queryCount);
const Rc<vk::DeviceFn>& vkd,
VkQueryType queryType);
~DxvkQueryPool();
/**
* \brief Query pool handle
* \returns Query pool handle
*/
VkQueryPool handle() const {
return m_queryPool;
}
/**
* \brief Query count
* \returns Query count
*/
uint32_t queryCount() const {
return MaxNumQueryCountPerPool;
}
/**
* \brief Allocates a Vulkan query
*
* \param [in] revision Query revision
* \returns The query ID and pool handle
*/
DxvkQueryHandle allocQuery(
const DxvkQueryRevision& revision);
/**
* \brief Writes back data for a range of queries
*
* \param [in] queryIndex First query in the range
* \param [in] queryCount Number of queries
* \returns Query result status
*/
VkResult getData(
uint32_t queryIndex,
uint32_t queryCount);
private:
Rc<vk::DeviceFn> m_vkd;
VkQueryPool m_queryPool = VK_NULL_HANDLE;
std::vector<Rc<DxvkQuery>> m_queries;
VkQueryType m_queryType;
VkQueryPool m_queryPool = VK_NULL_HANDLE;
std::array<DxvkQueryRevision, MaxNumQueryCountPerPool> m_queries;
uint32_t m_queryId = 0;
};

View File

@ -115,14 +115,6 @@ namespace dxvk {
};
template<typename T>
struct RcHash {
size_t operator () (const Rc<T>& rc) const {
return std::hash<T*>()(rc.ptr());
}
};
}
template<typename T>