mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 22:24:15 +01:00
[dxvk] Make query pools more usable as query allocators
This commit is contained in:
parent
563d4582ab
commit
dd237d866d
@ -7,6 +7,7 @@
|
||||
#include "dxvk_lifetime.h"
|
||||
#include "dxvk_limits.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
#include "dxvk_query_pool.h"
|
||||
#include "dxvk_staging.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -72,6 +73,18 @@ namespace dxvk {
|
||||
m_resources.trackResource(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a query range to track
|
||||
*
|
||||
* Query data will be retrieved and written back to
|
||||
* the query objects after the command buffer has
|
||||
* finished executing on the GPU.
|
||||
* \param [in] queries The query range
|
||||
*/
|
||||
void trackQueryRange(const DxvkQueryRange& queries) {
|
||||
m_queryRanges.push_back(queries);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resets the command list
|
||||
*
|
||||
@ -436,12 +449,14 @@ namespace dxvk {
|
||||
DxvkStagingBufferSlice stagedAlloc(
|
||||
VkDeviceSize size);
|
||||
|
||||
|
||||
void stagedBufferCopy(
|
||||
VkBuffer dstBuffer,
|
||||
VkDeviceSize dstOffset,
|
||||
VkDeviceSize dataSize,
|
||||
const DxvkStagingBufferSlice& dataSlice);
|
||||
|
||||
|
||||
void stagedBufferImageCopy(
|
||||
VkImage dstImage,
|
||||
VkImageLayout dstImageLayout,
|
||||
@ -459,6 +474,8 @@ namespace dxvk {
|
||||
DxvkDescriptorAlloc m_descAlloc;
|
||||
DxvkStagingAlloc m_stagingAlloc;
|
||||
|
||||
std::vector<DxvkQueryRange> m_queryRanges;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1197,6 +1197,17 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::writeTimestamp(const DxvkQueryRevision& query) {
|
||||
DxvkQueryHandle handle = this->allocateQuery(query);
|
||||
|
||||
m_cmd->cmdWriteTimestamp(
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
handle.queryPool, handle.queryId);
|
||||
|
||||
query.query->endRecording(query.revision);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::renderPassBegin() {
|
||||
if (!m_flags.test(DxvkContextFlag::GpRenderPassBound)
|
||||
&& (m_state.om.framebuffer != nullptr)) {
|
||||
@ -1615,16 +1626,14 @@ namespace dxvk {
|
||||
|
||||
DxvkQueryHandle DxvkContext::allocateQuery(const DxvkQueryRevision& query) {
|
||||
// TODO implement
|
||||
return DxvkQueryHandle { };
|
||||
return DxvkQueryHandle();
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::resetQueryPool(const Rc<DxvkQueryPool>& pool) {
|
||||
this->renderPassEnd();
|
||||
|
||||
m_cmd->cmdResetQueryPool(
|
||||
pool->handle(), 0,
|
||||
pool->queryCount());
|
||||
pool->reset(m_cmd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,6 +542,13 @@ namespace dxvk {
|
||||
uint32_t attachment,
|
||||
const DxvkBlendMode& blendMode);
|
||||
|
||||
/**
|
||||
* \brief Writes to a timestamp query
|
||||
* \param [in] query The timestamp query
|
||||
*/
|
||||
void writeTimestamp(
|
||||
const DxvkQueryRevision& query);
|
||||
|
||||
private:
|
||||
|
||||
const Rc<DxvkDevice> m_device;
|
||||
@ -551,6 +558,10 @@ namespace dxvk {
|
||||
DxvkContextState m_state;
|
||||
DxvkBarrierSet m_barriers;
|
||||
|
||||
Rc<DxvkQueryPool> m_occlusionQueries;
|
||||
Rc<DxvkQueryPool> m_statisticQueries;
|
||||
Rc<DxvkQueryPool> m_timestampQueries;
|
||||
|
||||
VkPipeline m_gpActivePipeline = VK_NULL_HANDLE;
|
||||
VkPipeline m_cpActivePipeline = VK_NULL_HANDLE;
|
||||
|
||||
|
@ -146,8 +146,9 @@ namespace dxvk {
|
||||
|
||||
|
||||
Rc<DxvkQueryPool> DxvkDevice::createQueryPool(
|
||||
VkQueryType queryType) {
|
||||
return new DxvkQueryPool(m_vkd, queryType);
|
||||
VkQueryType queryType,
|
||||
uint32_t queryCount) {
|
||||
return new DxvkQueryPool(m_vkd, queryType, queryCount);
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,7 +212,8 @@ namespace dxvk {
|
||||
* \param [in] queryType Query type
|
||||
*/
|
||||
Rc<DxvkQueryPool> createQueryPool(
|
||||
VkQueryType queryType);
|
||||
VkQueryType queryType,
|
||||
uint32_t queryCount);
|
||||
|
||||
/**
|
||||
* \brief Creates a sampler object
|
||||
|
@ -96,6 +96,14 @@ namespace dxvk {
|
||||
DxvkQuery(VkQueryType type);
|
||||
~DxvkQuery();
|
||||
|
||||
/**
|
||||
* \brief Query type
|
||||
* \returns Query type
|
||||
*/
|
||||
VkQueryType type() const {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resets the query object
|
||||
*
|
||||
|
@ -1,11 +1,15 @@
|
||||
#include "dxvk_cmdlist.h"
|
||||
#include "dxvk_query_pool.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxvkQueryPool::DxvkQueryPool(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkQueryType queryType)
|
||||
: m_vkd(vkd), m_queryType(queryType) {
|
||||
VkQueryType queryType,
|
||||
uint32_t queryCount)
|
||||
: m_vkd(vkd), m_queryCount(queryCount), m_queryType(queryType) {
|
||||
m_queries.resize(queryCount);
|
||||
|
||||
VkQueryPoolCreateInfo info;
|
||||
info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
@ -41,12 +45,19 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkQueryHandle DxvkQueryPool::allocQuery(const DxvkQueryRevision& query) {
|
||||
const DxvkQueryHandle result = { m_queryPool, m_queryId };
|
||||
const uint32_t queryIndex = m_queryRangeOffset + m_queryRangeLength;
|
||||
|
||||
if (queryIndex < m_queryCount) {
|
||||
const DxvkQueryHandle result = { m_queryPool, queryIndex };
|
||||
|
||||
query.query->associateQuery(query.revision, result);
|
||||
m_queries.at(m_queryId) = query;
|
||||
m_queryId += 1;
|
||||
m_queries.at(queryIndex) = query;
|
||||
|
||||
m_queryRangeLength += 1;
|
||||
return result;
|
||||
} else {
|
||||
return DxvkQueryHandle { VK_NULL_HANDLE, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,4 +83,12 @@ namespace dxvk {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void DxvkQueryPool::reset(const Rc<DxvkCommandList>& cmd) {
|
||||
cmd->cmdResetQueryPool(m_queryPool, 0, m_queryCount);
|
||||
|
||||
m_queryRangeOffset = 0;
|
||||
m_queryRangeLength = 0;
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,21 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class DxvkCommandList;
|
||||
class DxvkQueryPool;
|
||||
|
||||
/**
|
||||
* \brief Query range
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct DxvkQueryRange {
|
||||
Rc<DxvkQueryPool> queryPool;
|
||||
|
||||
uint32_t queryIndex = 0;
|
||||
uint32_t queryCount = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Query pool
|
||||
*
|
||||
@ -17,7 +32,8 @@ namespace dxvk {
|
||||
|
||||
DxvkQueryPool(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkQueryType queryType);
|
||||
VkQueryType queryType,
|
||||
uint32_t queryCount);
|
||||
|
||||
~DxvkQueryPool();
|
||||
|
||||
@ -29,14 +45,6 @@ namespace dxvk {
|
||||
return m_queryPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Query count
|
||||
* \returns Query count
|
||||
*/
|
||||
uint32_t queryCount() const {
|
||||
return MaxNumQueryCountPerPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates a Vulkan query
|
||||
*
|
||||
@ -57,15 +65,28 @@ namespace dxvk {
|
||||
uint32_t queryIndex,
|
||||
uint32_t queryCount);
|
||||
|
||||
/**
|
||||
* \brief Resets query pool
|
||||
*
|
||||
* Resets the Vulkan query pool itself, as
|
||||
* well as the the internal query allocator.
|
||||
* \param [in] cmd Command list
|
||||
*/
|
||||
void reset(
|
||||
const Rc<DxvkCommandList>& cmd);
|
||||
|
||||
private:
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
|
||||
uint32_t m_queryCount;
|
||||
VkQueryType m_queryType;
|
||||
VkQueryPool m_queryPool = VK_NULL_HANDLE;
|
||||
|
||||
std::array<DxvkQueryRevision, MaxNumQueryCountPerPool> m_queries;
|
||||
uint32_t m_queryId = 0;
|
||||
std::vector<DxvkQueryRevision> m_queries;
|
||||
|
||||
uint32_t m_queryRangeOffset = 0;
|
||||
uint32_t m_queryRangeLength = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,7 @@ dxvk_src = files([
|
||||
'dxvk_descriptor.cpp',
|
||||
'dxvk_device.cpp',
|
||||
'dxvk_extensions.cpp',
|
||||
'dxvk_event.cpp',
|
||||
'dxvk_format.cpp',
|
||||
'dxvk_framebuffer.cpp',
|
||||
'dxvk_graphics.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user