| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #include <AnKi/Gr/Vulkan/VkQueryFactory.h>
- namespace anki {
- QueryFactory::~QueryFactory()
- {
- if(!m_chunks.isEmpty())
- {
- ANKI_VK_LOGW("Forgot the delete some queries");
- }
- }
- Error QueryFactory::newQuery(MicroQuery& handle)
- {
- ANKI_ASSERT(!handle);
- LockGuard<Mutex> lock(m_mtx);
- // Find a not-full chunk
- Chunk* chunk = nullptr;
- for(Chunk& c : m_chunks)
- {
- if(c.m_subAllocationCount < kMaxQueriesPerQueryChunk)
- {
- // Found one
- if(chunk == nullptr)
- {
- chunk = &c;
- }
- else if(c.m_subAllocationCount > chunk->m_subAllocationCount)
- {
- // To decrease fragmentation use the most full chunk
- chunk = &c;
- }
- }
- }
- if(chunk == nullptr)
- {
- // Create new chunk
- chunk = newInstance<Chunk>(GrMemoryPool::getSingleton());
- VkQueryPoolCreateInfo ci = {};
- ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
- ci.queryType = m_poolType;
- ci.queryCount = kMaxQueriesPerQueryChunk;
- ci.pipelineStatistics = m_pplineStatisticsFlags;
- ANKI_VK_CHECK(vkCreateQueryPool(getVkDevice(), &ci, nullptr, &chunk->m_pool));
- m_chunks.pushBack(chunk);
- }
- ANKI_ASSERT(chunk);
- // Allocate from chunk
- for(U32 i = 0; i < kMaxQueriesPerQueryChunk; ++i)
- {
- if(chunk->m_allocatedMask.get(i) == 0)
- {
- chunk->m_allocatedMask.set(i);
- ++chunk->m_subAllocationCount;
- handle.m_pool = chunk->m_pool;
- handle.m_queryIndex = i;
- handle.m_chunk = chunk;
- vkResetQueryPool(getVkDevice(), chunk->m_pool, handle.m_queryIndex, 1);
- break;
- }
- }
- ANKI_ASSERT(!!handle);
- return Error::kNone;
- }
- void QueryFactory::deleteQuery(MicroQuery& handle)
- {
- ANKI_ASSERT(handle.m_pool && handle.m_queryIndex != kMaxU32 && handle.m_chunk);
- LockGuard<Mutex> lock(m_mtx);
- Chunk* chunk = handle.m_chunk;
- ANKI_ASSERT(chunk->m_subAllocationCount > 0);
- --chunk->m_subAllocationCount;
- if(chunk->m_subAllocationCount == 0)
- {
- // Delete the chunk
- ANKI_ASSERT(chunk->m_allocatedMask.getAnySet());
- vkDestroyQueryPool(getVkDevice(), chunk->m_pool, nullptr);
- m_chunks.erase(chunk);
- deleteInstance(GrMemoryPool::getSingleton(), chunk);
- }
- else
- {
- ANKI_ASSERT(chunk->m_allocatedMask.get(handle.m_queryIndex));
- chunk->m_allocatedMask.unset(handle.m_queryIndex);
- }
- handle = {};
- }
- } // end namespace anki
|