mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-03 13:24:20 +01:00
[dxvk] Implemented more query and query pool methods
This commit is contained in:
parent
5beae25bdf
commit
54cfdbdc51
@ -47,24 +47,44 @@ namespace dxvk {
|
|||||||
DxvkContextFlag::CpDirtyPipeline,
|
DxvkContextFlag::CpDirtyPipeline,
|
||||||
DxvkContextFlag::CpDirtyPipelineState,
|
DxvkContextFlag::CpDirtyPipelineState,
|
||||||
DxvkContextFlag::CpDirtyResources);
|
DxvkContextFlag::CpDirtyResources);
|
||||||
|
|
||||||
|
// Restart queries that were active during
|
||||||
|
// the last command buffer submission.
|
||||||
|
this->beginActiveQueries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkCommandList> DxvkContext::endRecording() {
|
Rc<DxvkCommandList> DxvkContext::endRecording() {
|
||||||
this->renderPassEnd();
|
this->renderPassEnd();
|
||||||
|
this->endActiveQueries();
|
||||||
|
|
||||||
m_cmd->endRecording();
|
m_cmd->endRecording();
|
||||||
return std::exchange(m_cmd, nullptr);
|
return std::exchange(m_cmd, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::beginQuery(const Rc<DxvkQuery>& query) {
|
void DxvkContext::beginQuery(const DxvkQueryRevision& query) {
|
||||||
// TODO implement
|
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) {
|
void DxvkContext::endQuery(const DxvkQueryRevision& query) {
|
||||||
// TODO implement
|
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);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
#include "dxvk_cmdlist.h"
|
#include "dxvk_cmdlist.h"
|
||||||
#include "dxvk_context_state.h"
|
#include "dxvk_context_state.h"
|
||||||
#include "dxvk_data.h"
|
#include "dxvk_data.h"
|
||||||
#include "dxvk_query.h"
|
#include "dxvk_query_pool.h"
|
||||||
#include "dxvk_util.h"
|
#include "dxvk_util.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -49,19 +49,18 @@ namespace dxvk {
|
|||||||
Rc<DxvkCommandList> endRecording();
|
Rc<DxvkCommandList> endRecording();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Begins gathering query data
|
* \brief Begins generating query data
|
||||||
* \param [in] query The query to end
|
* \param [in] query The query to end
|
||||||
*/
|
*/
|
||||||
void beginQuery(
|
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
|
* \param [in] query The query to end
|
||||||
*/
|
*/
|
||||||
void endQuery(
|
void endQuery(
|
||||||
const Rc<DxvkQuery>& query);
|
const DxvkQueryRevision& query);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Sets framebuffer
|
* \brief Sets framebuffer
|
||||||
@ -555,6 +554,8 @@ namespace dxvk {
|
|||||||
VkPipeline m_gpActivePipeline = VK_NULL_HANDLE;
|
VkPipeline m_gpActivePipeline = VK_NULL_HANDLE;
|
||||||
VkPipeline m_cpActivePipeline = VK_NULL_HANDLE;
|
VkPipeline m_cpActivePipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
std::vector<DxvkQueryRevision> m_activeQueries;
|
||||||
|
|
||||||
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
||||||
std::array<DxvkDescriptorInfo, MaxNumActiveBindings> m_descInfos;
|
std::array<DxvkDescriptorInfo, MaxNumActiveBindings> m_descInfos;
|
||||||
std::array<VkWriteDescriptorSet, MaxNumActiveBindings> m_descWrites;
|
std::array<VkWriteDescriptorSet, MaxNumActiveBindings> m_descWrites;
|
||||||
@ -594,6 +595,19 @@ namespace dxvk {
|
|||||||
|
|
||||||
void commitComputeBarriers();
|
void commitComputeBarriers();
|
||||||
|
|
||||||
|
void resetQueryPool(
|
||||||
|
const Rc<DxvkQueryPool>& pool);
|
||||||
|
|
||||||
|
void beginActiveQueries();
|
||||||
|
|
||||||
|
void endActiveQueries();
|
||||||
|
|
||||||
|
void insertActiveQuery(
|
||||||
|
const DxvkQueryRevision& query);
|
||||||
|
|
||||||
|
void eraseActiveQuery(
|
||||||
|
const DxvkQueryRevision& query);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -145,6 +145,12 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkQueryPool> DxvkDevice::createQueryPool(
|
||||||
|
VkQueryType queryType) {
|
||||||
|
return new DxvkQueryPool(m_vkd, queryType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkSampler> DxvkDevice::createSampler(
|
Rc<DxvkSampler> DxvkDevice::createSampler(
|
||||||
const DxvkSamplerCreateInfo& createInfo) {
|
const DxvkSamplerCreateInfo& createInfo) {
|
||||||
return new DxvkSampler(m_vkd, createInfo);
|
return new DxvkSampler(m_vkd, createInfo);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "dxvk_pipecache.h"
|
#include "dxvk_pipecache.h"
|
||||||
#include "dxvk_pipemanager.h"
|
#include "dxvk_pipemanager.h"
|
||||||
#include "dxvk_queue.h"
|
#include "dxvk_queue.h"
|
||||||
|
#include "dxvk_query_pool.h"
|
||||||
#include "dxvk_recycler.h"
|
#include "dxvk_recycler.h"
|
||||||
#include "dxvk_renderpass.h"
|
#include "dxvk_renderpass.h"
|
||||||
#include "dxvk_sampler.h"
|
#include "dxvk_sampler.h"
|
||||||
@ -206,6 +207,13 @@ namespace dxvk {
|
|||||||
const Rc<DxvkImage>& image,
|
const Rc<DxvkImage>& image,
|
||||||
const DxvkImageViewCreateInfo& createInfo);
|
const DxvkImageViewCreateInfo& createInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates a query pool
|
||||||
|
* \param [in] queryType Query type
|
||||||
|
*/
|
||||||
|
Rc<DxvkQueryPool> createQueryPool(
|
||||||
|
VkQueryType queryType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates a sampler object
|
* \brief Creates a sampler object
|
||||||
*
|
*
|
||||||
|
@ -13,7 +13,7 @@ namespace dxvk {
|
|||||||
MaxNumResourceSlots = 1096,
|
MaxNumResourceSlots = 1096,
|
||||||
MaxNumActiveBindings = 128,
|
MaxNumActiveBindings = 128,
|
||||||
MaxNumQueuedCommandBuffers = 8,
|
MaxNumQueuedCommandBuffers = 8,
|
||||||
MaxNumQueryCountPerPool = 16,
|
MaxNumQueryCountPerPool = 128,
|
||||||
MaxVertexBindingStride = 2048,
|
MaxVertexBindingStride = 2048,
|
||||||
MaxPushConstantSize = 128,
|
MaxPushConstantSize = 128,
|
||||||
};
|
};
|
||||||
|
@ -36,6 +36,11 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkQueryHandle DxvkQuery::getHandle() {
|
||||||
|
return m_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkQuery::beginRecording(uint32_t revision) {
|
void DxvkQuery::beginRecording(uint32_t revision) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
@ -47,16 +52,28 @@ namespace dxvk {
|
|||||||
void DxvkQuery::endRecording(uint32_t revision) {
|
void DxvkQuery::endRecording(uint32_t revision) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
if (m_revision == revision)
|
if (m_revision == revision) {
|
||||||
m_status = DxvkQueryStatus::Pending;
|
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);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
if (m_revision == revision)
|
if (m_revision == revision)
|
||||||
m_queryCount += 1;
|
m_queryCount += 1;
|
||||||
|
|
||||||
|
// Assign the handle either way as this
|
||||||
|
// will be used by the DXVK context.
|
||||||
|
m_handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,6 +71,17 @@ namespace dxvk {
|
|||||||
DxvkQueryStatisticData statistic;
|
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
|
* \brief Query object
|
||||||
*
|
*
|
||||||
@ -105,6 +116,12 @@ namespace dxvk {
|
|||||||
DxvkQueryStatus getData(
|
DxvkQueryStatus getData(
|
||||||
DxvkQueryData& data);
|
DxvkQueryData& data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Gets current query handle
|
||||||
|
* \returns The current query handle
|
||||||
|
*/
|
||||||
|
DxvkQueryHandle getHandle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Begins recording the query
|
* \brief Begins recording the query
|
||||||
*
|
*
|
||||||
@ -127,8 +144,11 @@ namespace dxvk {
|
|||||||
* The internal query count is used to determine
|
* The internal query count is used to determine
|
||||||
* when the query data is actually available.
|
* when the query data is actually available.
|
||||||
* \param [in] revision Query version ID
|
* \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
|
* \brief Updates query data
|
||||||
@ -151,6 +171,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkQueryStatus m_status = DxvkQueryStatus::Reset;
|
DxvkQueryStatus m_status = DxvkQueryStatus::Reset;
|
||||||
DxvkQueryData m_data = {};
|
DxvkQueryData m_data = {};
|
||||||
|
DxvkQueryHandle m_handle;
|
||||||
|
|
||||||
uint32_t m_queryIndex = 0;
|
uint32_t m_queryIndex = 0;
|
||||||
uint32_t m_queryCount = 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;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -3,15 +3,73 @@
|
|||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkQueryPool::DxvkQueryPool(
|
DxvkQueryPool::DxvkQueryPool(
|
||||||
const Rc<vk::DeviceFn>& fn,
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
VkQueryType queryType,
|
VkQueryType queryType)
|
||||||
uint32_t queryCount) {
|
: 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() {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,18 +16,56 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkQueryPool(
|
DxvkQueryPool(
|
||||||
const Rc<vk::DeviceFn>& fn,
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
VkQueryType queryType,
|
VkQueryType queryType);
|
||||||
uint32_t queryCount);
|
|
||||||
|
|
||||||
~DxvkQueryPool();
|
~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:
|
private:
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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>
|
template<typename T>
|
||||||
|
Loading…
Reference in New Issue
Block a user