Diligent Engine  v.2.4.g
VAOCache.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019-2021 Diligent Graphics LLC
3  * Copyright 2015-2019 Egor Yusov
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * In no event and under no legal theory, whether in tort (including negligence),
18  * contract, or otherwise, unless required by applicable law (such as deliberate
19  * and grossly negligent acts) or agreed to in writing, shall any Contributor be
20  * liable for any damages, including any direct, indirect, special, incidental,
21  * or consequential damages of any character arising as a result of this License or
22  * out of the use or inability to use the software (including but not limited to damages
23  * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
24  * all other commercial damages or losses), even if such Contributor has been advised
25  * of the possibility of such damages.
26  */
27 
28 #pragma once
29 
30 #include <cstring>
31 #include <vector>
32 #include <unordered_map>
33 
34 #include "GraphicsTypes.h"
35 #include "Buffer.h"
36 #include "InputLayout.h"
37 #include "LockHelper.hpp"
38 #include "HashUtils.hpp"
39 #include "DeviceContextBase.hpp"
40 
41 namespace Diligent
42 {
43 
44 class PipelineStateGLImpl;
45 class BufferGLImpl;
46 
47 class VAOCache
48 {
49 public:
50  VAOCache();
51  ~VAOCache();
52 
53  // clang-format off
54  VAOCache (const VAOCache&) = delete;
55  VAOCache ( VAOCache&&) = delete;
56  VAOCache& operator = (const VAOCache&) = delete;
57  VAOCache& operator = ( VAOCache&&) = delete;
58  // clang-format on
59 
60  struct VAOAttribs
61  {
66  };
70 
71  void OnDestroyBuffer(const BufferGLImpl& Buffer);
72  void OnDestroyPSO(const PipelineStateGLImpl& PSO);
73 
74 private:
75  // This structure is used as the key to find VAO
76  struct VAOHashKey
77  {
78  VAOHashKey(const VAOAttribs& Attribs);
79 
80  // Note that using pointers is unsafe as they may (and will) be reused:
81  // pBuffer->Release();
82  // pDevice->CreateBuffer(&pBuffer); // Returns same pointer
83 
84  // VAO encapsulates both input layout and all bound buffers.
85  // PSO uniqly defines the layout (attrib pointers, divisors, etc.),
86  // so we do not need to add individual layout elements to the key.
87  // The key needs to contain all bound buffers.
88  const UniqueIdentifier PsoUId;
89  const UniqueIdentifier IndexBufferUId;
90 
91  Uint32 UsedSlotsMask = 0;
92  static_assert(MAX_BUFFER_SLOTS <= sizeof(UsedSlotsMask) * 8, "Use more bits for UsedSlotsMask");
93 
95  {
98  // Note that buffer stride is defined by the PSO, so no need to keep it here as
99  // it is already handled by the PsoUId
100 
101  bool operator!=(const StreamAttribs& rhs) const
102  {
103  return BufferUId != rhs.BufferUId || Offset != rhs.Offset;
104  }
105  } Streams[MAX_BUFFER_SLOTS]; // Do not zero-out
106 
107  size_t Hash = 0;
108 
109  bool operator==(const VAOHashKey& Key) const;
110 
111  struct Hasher
112  {
113  std::size_t operator()(const VAOHashKey& Key) const
114  {
115  return Key.Hash;
116  }
117  };
118  };
119 
120  // Clears stale entries from m_PSOToKey and m_BuffToKey when a VAO is removed from m_Cache
121  void ClearStaleKeys(const std::vector<VAOHashKey>& StaleKeys);
122 
123  ThreadingTools::LockFlag m_CacheLockFlag;
124  std::unordered_map<VAOHashKey, GLObjectWrappers::GLVertexArrayObj, VAOHashKey::Hasher> m_Cache;
125 
126  std::unordered_multimap<UniqueIdentifier, VAOHashKey> m_PSOToKey;
127  std::unordered_multimap<UniqueIdentifier, VAOHashKey> m_BuffToKey;
128 
129  // Any draw command fails if no VAO is bound. We will use this empty
130  // VAO for draw commands with null input layout, such as these that
131  // only use VertexID as input.
133 };
134 
135 } // namespace Diligent
Diligent::VAOCache::OnDestroyBuffer
void OnDestroyBuffer(const BufferGLImpl &Buffer)
Definition: VAOCache.cpp:62
ThreadingTools::LockFlag
Definition: LockHelper.hpp:36
Diligent::VAOCache::VAOAttribs
Definition: VAOCache.hpp:60
Diligent::VAOCache::VAOHashKey::StreamAttribs::Offset
Uint32 Offset
Definition: VAOCache.hpp:97
Diligent::VAOCache::VAOHashKey::StreamAttribs
Definition: VAOCache.hpp:94
Diligent::VAOCache::operator=
VAOCache & operator=(const VAOCache &)=delete
Diligent::operator==
bool operator==(const Plane3D &p1, const Plane3D &p2)
Definition: AdvancedMath.hpp:442
Diligent::VAOCache::VAOAttribs::NumVertexStreams
const Uint32 NumVertexStreams
Definition: VAOCache.hpp:65
Diligent::VAOCache::OnDestroyPSO
void OnDestroyPSO(const PipelineStateGLImpl &PSO)
Definition: VAOCache.cpp:82
Diligent::VAOCache::VAOHashKey::StreamAttribs::operator!=
bool operator!=(const StreamAttribs &rhs) const
Definition: VAOCache.hpp:101
DeviceContextBase.hpp
Diligent::VAOCache
Definition: VAOCache.hpp:47
Diligent::VAOCache::VAOCache
VAOCache()
Definition: VAOCache.cpp:47
Diligent::VAOCache::VAOAttribs::VertexStreams
VertexStreamInfo< BufferGLImpl > *const VertexStreams
Definition: VAOCache.hpp:64
InputLayout.h
Diligent::VAOCache::VAOHashKey::Hasher
Definition: VAOCache.hpp:111
Diligent::PipelineStateGLImpl
Pipeline state object implementation in OpenGL backend.
Definition: PipelineStateGLImpl.hpp:45
Diligent::Uint32
uint32_t Uint32
32-bit unsigned integer
Definition: BasicTypes.h:51
Buffer.h
Diligent::VAOCache::VAOHashKey::Hasher::operator()
std::size_t operator()(const VAOHashKey &Key) const
Definition: VAOCache.hpp:113
Diligent::BufferGLImpl
Buffer object implementation in OpenGL backend.
Definition: BufferGLImpl.hpp:41
Diligent::VertexStreamInfo
Describes input vertex stream.
Definition: DeviceContextBase.hpp:87
Diligent::VAOCache::VAOHashKey::StreamAttribs::BufferUId
UniqueIdentifier BufferUId
Definition: VAOCache.hpp:96
HashUtils.hpp
Diligent::VAOCache::GetVAO
const GLObjectWrappers::GLVertexArrayObj & GetVAO(const VAOAttribs &Attribs, class GLContextState &GLContextState)
Definition: VAOCache.cpp:213
GLObjectWrappers::GLObjWrapper
Definition: GLObjectWrapper.hpp:36
Diligent::VAOCache::~VAOCache
~VAOCache()
Definition: VAOCache.cpp:55
Diligent::GLContextState
Definition: GLContextState.hpp:39
GraphicsTypes.h
Diligent::VAOCache::GetEmptyVAO
const GLObjectWrappers::GLVertexArrayObj & GetEmptyVAO()
Definition: VAOCache.cpp:339
Diligent::UniqueIdentifier
Int32 UniqueIdentifier
Definition: UniqueIdentifier.hpp:36
LockHelper.hpp
Diligent
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37
Diligent::VAOCache::VAOAttribs::PSO
const PipelineStateGLImpl & PSO
Definition: VAOCache.hpp:62
Diligent::VAOCache::VAOAttribs::pIndexBuffer
BufferGLImpl *const pIndexBuffer
Definition: VAOCache.hpp:63