KiCad PCB EDA Suite
Loading...
Searching...
No Matches
rhi_handle.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <cstdint>
23#include <mutex>
24#include <vector>
25
32template <typename Tag>
34{
35 uint32_t value = 0;
36
37 bool operator==( const RHI_HANDLE& other ) const = default;
38
39 explicit operator bool() const { return value != 0; }
40};
41
42
43constexpr uint32_t RHI_HANDLE_INDEX_BITS = 20;
44constexpr uint32_t RHI_HANDLE_GEN_BITS = 12;
45constexpr uint32_t RHI_HANDLE_INDEX_MASK = ( 1u << RHI_HANDLE_INDEX_BITS ) - 1;
46constexpr uint32_t RHI_HANDLE_GEN_MASK = ( 1u << RHI_HANDLE_GEN_BITS ) - 1;
47
48
49template <typename Tag>
51{
53}
54
55
56template <typename Tag>
61
62
63template <typename Tag>
64RHI_HANDLE<Tag> RhiMakeHandle( uint32_t index, uint32_t generation )
65{
66 return { ( index & RHI_HANDLE_INDEX_MASK )
67 | ( ( generation & RHI_HANDLE_GEN_MASK ) << RHI_HANDLE_INDEX_BITS ) };
68}
69
70
82
94
95
99template <typename Tag>
101{
102public:
103 RHI_HANDLE_POOL() { m_entries.reserve( 64 ); }
104
106 {
107 std::lock_guard<std::mutex> lock( m_mutex );
108 uint32_t index;
109
110 if( !m_freeList.empty() )
111 {
112 index = m_freeList.back();
113 m_freeList.pop_back();
114 }
115 else
116 {
117 index = static_cast<uint32_t>( m_entries.size() );
118
120 return {};
121
122 m_entries.push_back( { 1, true } );
123 }
124
125 m_entries[index].alive = true;
126 return RhiMakeHandle<Tag>( index, m_entries[index].generation );
127 }
128
139 {
140 std::lock_guard<std::mutex> lock( m_mutex );
141 Entry* entry = findLive( *this, handle );
142
143 if( !entry || entry->pendingDestroy )
144 return false;
145
146 entry->pendingDestroy = true;
147 return true;
148 }
149
151 {
152 std::lock_guard<std::mutex> lock( m_mutex );
153 Entry* entry = findLive( *this, handle );
154
155 if( !entry )
156 return;
157
158 entry->alive = false;
159 entry->pendingDestroy = false;
160
161 uint32_t nextGen = ( entry->generation + 1 ) & RHI_HANDLE_GEN_MASK;
162
167 if( nextGen == 0 )
168 return;
169
170 entry->generation = nextGen;
171 m_freeList.push_back( RhiHandleIndex( handle ) );
172 }
173
174 bool IsValid( RHI_HANDLE<Tag> handle ) const
175 {
176 std::lock_guard<std::mutex> lock( m_mutex );
177 const Entry* entry = findLive( *this, handle );
178
179 return entry && !entry->pendingDestroy;
180 }
181
182private:
183
184 struct Entry
185 {
186 uint32_t generation = 0;
187 bool alive = false;
188 bool pendingDestroy = false;
189 };
190
195 mutable std::mutex m_mutex;
196 std::vector<Entry> m_entries;
197 std::vector<uint32_t> m_freeList;
198
202 template <typename POOL>
203 static auto findLive( POOL& aPool, RHI_HANDLE<Tag> handle ) -> decltype( &aPool.m_entries[0] )
204 {
205 const uint32_t index = RhiHandleIndex( handle );
206
207 if( !handle || index >= aPool.m_entries.size() )
208 return nullptr;
209
210 auto& entry = aPool.m_entries[index];
211
212 return entry.alive && RhiHandleGeneration( handle ) == entry.generation ? &entry : nullptr;
213 }
214};
215
216
221template <typename MAP, typename Tag>
222void RhiReleasePooledResource( MAP& aMap, RHI_HANDLE_POOL<Tag>& aPool, uint32_t aHandleValue )
223{
224 aMap.erase( aHandleValue & RHI_HANDLE_INDEX_MASK );
225 aPool.Release( RHI_HANDLE<Tag>{ aHandleValue } );
226}
int index
Thread-safe pool that allocates and recycles generation-tracked handles for device implementations.
Definition rhi_handle.h:101
std::vector< uint32_t > m_freeList
Definition rhi_handle.h:197
void Release(RHI_HANDLE< Tag > handle)
Definition rhi_handle.h:150
std::vector< Entry > m_entries
Definition rhi_handle.h:196
static auto findLive(POOL &aPool, RHI_HANDLE< Tag > handle) -> decltype(&aPool.m_entries[0])
Return the entry of a handle that is alive at its generation, or nullptr.
Definition rhi_handle.h:203
bool IsValid(RHI_HANDLE< Tag > handle) const
Definition rhi_handle.h:174
RHI_HANDLE< Tag > Allocate()
Definition rhi_handle.h:105
bool MarkPendingDestroy(RHI_HANDLE< Tag > handle)
Make a handle invalid while keeping its slot out of the free list until Release().
Definition rhi_handle.h:138
std::mutex m_mutex
Handles are allocated and released from both the UI and render threads, and Allocate() can reallocate...
Definition rhi_handle.h:195
constexpr uint32_t RHI_HANDLE_GEN_MASK
Definition rhi_handle.h:46
RHI_HANDLE< RHI_TAG_FRAMEBUFFER > RHI_FramebufferHandle
Definition rhi_handle.h:93
void RhiReleasePooledResource(MAP &aMap, RHI_HANDLE_POOL< Tag > &aPool, uint32_t aHandleValue)
Release a deferred handle whose only teardown is dropping its table entry and recycling the pool slot...
Definition rhi_handle.h:222
RHI_HANDLE< RHI_TAG_TEXTURE > RHI_TextureHandle
Definition rhi_handle.h:84
RHI_HANDLE< RHI_TAG_BUFFER > RHI_BufferHandle
Definition rhi_handle.h:83
RHI_HANDLE< RHI_TAG_PIPELINE > RHI_PipelineHandle
Definition rhi_handle.h:86
RHI_HANDLE< RHI_TAG_BIND_GROUP > RHI_BindGroupHandle
Definition rhi_handle.h:90
RHI_HANDLE< RHI_TAG_COMPUTE_PIPELINE > RHI_ComputePipelineHandle
Definition rhi_handle.h:87
RHI_HANDLE< RHI_TAG_BIND_GROUP_LAYOUT > RHI_BindGroupLayoutHandle
Definition rhi_handle.h:89
uint32_t RhiHandleIndex(RHI_HANDLE< Tag > h)
Definition rhi_handle.h:50
RHI_HANDLE< RHI_TAG_SURFACE > RHI_SurfaceHandle
Definition rhi_handle.h:91
RHI_HANDLE< RHI_TAG_SHADER > RHI_ShaderHandle
Definition rhi_handle.h:85
RHI_HANDLE< RHI_TAG_RENDER_PASS > RHI_RenderPassHandle
Definition rhi_handle.h:88
constexpr uint32_t RHI_HANDLE_INDEX_BITS
Definition rhi_handle.h:43
RHI_HANDLE< Tag > RhiMakeHandle(uint32_t index, uint32_t generation)
Definition rhi_handle.h:64
RHI_HANDLE< RHI_TAG_SWAPCHAIN > RHI_SwapchainHandle
Definition rhi_handle.h:92
uint32_t RhiHandleGeneration(RHI_HANDLE< Tag > h)
Definition rhi_handle.h:57
constexpr uint32_t RHI_HANDLE_INDEX_MASK
Definition rhi_handle.h:45
constexpr uint32_t RHI_HANDLE_GEN_BITS
Definition rhi_handle.h:44
Opaque GPU resource handle, typed by a tag struct so handles of different kinds cannot be mixed.
Definition rhi_handle.h:34
bool operator==(const RHI_HANDLE &other) const =default