Diligent Engine  v.2.4.g
BufferBase.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 
32 
33 #include <memory>
34 
35 #include "Buffer.h"
36 #include "GraphicsTypes.h"
37 #include "DeviceObjectBase.hpp"
38 #include "GraphicsAccessories.hpp"
39 #include "STDAllocator.hpp"
40 #include "FormatString.hpp"
41 
42 namespace Diligent
43 {
44 
46 void ValidateBufferDesc(const BufferDesc& Desc, const DeviceCaps& deviceCaps) noexcept(false);
47 
49 void ValidateBufferInitData(const BufferDesc& Desc, const BufferData* pBuffData) noexcept(false);
50 
52 void ValidateAndCorrectBufferViewDesc(const BufferDesc& BuffDesc, BufferViewDesc& ViewDesc) noexcept(false);
53 
54 
56 
58 template <typename EngineImplTraits>
59 class BufferBase : public DeviceObjectBase<typename EngineImplTraits::BufferInterface, typename EngineImplTraits::RenderDeviceImplType, BufferDesc>
60 {
61 public:
62  // Base interface that this class inherits (IBufferD3D12, IBufferVk, etc.).
63  using BaseInterface = typename EngineImplTraits::BufferInterface;
64 
65  // Render device implementation type (RenderDeviceD3D12Impl, RenderDeviceVkImpl, etc.).
66  using RenderDeviceImplType = typename EngineImplTraits::RenderDeviceImplType;
67 
68  // Buffer view implementation type (BufferViewD3D12Impl, BufferViewVkImpl, etc.).
69  using BufferViewImplType = typename EngineImplTraits::BufferViewImplType;
70 
71  // The type of the allocator that is used to allocate memory for the buffer view object instances.
72  using TBuffViewObjAllocator = typename EngineImplTraits::BuffViewObjAllocatorType;
73 
75 
84  TBuffViewObjAllocator& BuffViewObjAllocator,
85  RenderDeviceImplType* pDevice,
86  const BufferDesc& BuffDesc,
87  bool bIsDeviceInternal) :
88  TDeviceObjectBase{pRefCounters, pDevice, BuffDesc, bIsDeviceInternal},
89 #ifdef DILIGENT_DEBUG
90  m_dbgBuffViewAllocator{BuffViewObjAllocator},
91 #endif
92  m_pDefaultUAV{nullptr, STDDeleter<BufferViewImplType, TBuffViewObjAllocator>(BuffViewObjAllocator)},
93  m_pDefaultSRV{nullptr, STDDeleter<BufferViewImplType, TBuffViewObjAllocator>(BuffViewObjAllocator)}
94  {
95  ValidateBufferDesc(this->m_Desc, pDevice->GetDeviceCaps());
96 
97  Uint64 DeviceQueuesMask = pDevice->GetCommandQueueMask();
98  DEV_CHECK_ERR((this->m_Desc.CommandQueueMask & DeviceQueuesMask) != 0, "No bits in the command queue mask (0x", std::hex, this->m_Desc.CommandQueueMask, ") correspond to one of ", pDevice->GetCommandQueueCount(), " available device command queues");
99  this->m_Desc.CommandQueueMask &= DeviceQueuesMask;
100  }
101 
103 
104 
105  virtual void DILIGENT_CALL_TYPE CreateView(const struct BufferViewDesc& ViewDesc, IBufferView** ppView) override
107  {
108  DEV_CHECK_ERR(ViewDesc.ViewType != BUFFER_VIEW_UNDEFINED, "Buffer view type is not specified");
109  if (ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE)
110  DEV_CHECK_ERR(this->m_Desc.BindFlags & BIND_SHADER_RESOURCE, "Attempting to create SRV for buffer '", this->m_Desc.Name, "' that was not created with BIND_SHADER_RESOURCE flag");
111  else if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS)
112  DEV_CHECK_ERR(this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS, "Attempting to create UAV for buffer '", this->m_Desc.Name, "' that was not created with BIND_UNORDERED_ACCESS flag");
113  else
114  UNEXPECTED("Unexpected buffer view type");
115 
116  CreateViewInternal(ViewDesc, ppView, false);
117  }
118 
119 
122  {
123  switch (ViewType)
124  {
125  case BUFFER_VIEW_SHADER_RESOURCE: return m_pDefaultSRV.get();
126  case BUFFER_VIEW_UNORDERED_ACCESS: return m_pDefaultUAV.get();
127  default: UNEXPECTED("Unknown view type"); return nullptr;
128  }
129  }
130 
131 
133 
140  {
141  // Create default views for structured and raw buffers. For formatted buffers we do not know the view format, so
142  // cannot create views.
143 
144  auto CreateDefaultView = [&](BUFFER_VIEW_TYPE ViewType) //
145  {
146  BufferViewDesc ViewDesc;
147  ViewDesc.ViewType = ViewType;
148 
149  std::string ViewName;
150  switch (ViewType)
151  {
153  ViewName = "Default UAV of buffer '";
154  break;
155 
157  ViewName = "Default SRV of buffer '";
158  break;
159 
160  default:
161  UNEXPECTED("Unexpected buffer view type");
162  }
163 
164  ViewName += this->m_Desc.Name;
165  ViewName += '\'';
166  ViewDesc.Name = ViewName.c_str();
167 
168  IBufferView* pView = nullptr;
169  CreateViewInternal(ViewDesc, &pView, true);
170  VERIFY(pView != nullptr, "Failed to create default view for buffer '", this->m_Desc.Name, "'");
171  VERIFY(pView->GetDesc().ViewType == ViewType, "Unexpected view type");
172 
173  return static_cast<BufferViewImplType*>(pView);
174  };
175 
176  if (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
177  {
178  m_pDefaultUAV.reset(CreateDefaultView(BUFFER_VIEW_UNORDERED_ACCESS));
179  }
180 
181  if (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
182  {
183  m_pDefaultSRV.reset(CreateDefaultView(BUFFER_VIEW_SHADER_RESOURCE));
184  }
185  }
186 
187  virtual void DILIGENT_CALL_TYPE SetState(RESOURCE_STATE State) override final
188  {
189  this->m_State = State;
190  }
191 
192  virtual RESOURCE_STATE DILIGENT_CALL_TYPE GetState() const override final
193  {
194  return this->m_State;
195  }
196 
197  bool IsInKnownState() const
198  {
199  return this->m_State != RESOURCE_STATE_UNKNOWN;
200  }
201 
202  bool CheckState(RESOURCE_STATE State) const
203  {
204  DEV_CHECK_ERR((State & (State - 1)) == 0, "Single state is expected");
205  DEV_CHECK_ERR(IsInKnownState(), "Buffer state is unknown");
206  return (this->m_State & State) == State;
207  }
208 
209 protected:
211  virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView) = 0;
212 
213 #ifdef DILIGENT_DEBUG
214  TBuffViewObjAllocator& m_dbgBuffViewAllocator;
215 #endif
216 
218 
220  std::unique_ptr<BufferViewImplType, STDDeleter<BufferViewImplType, TBuffViewObjAllocator>> m_pDefaultUAV;
221 
223  std::unique_ptr<BufferViewImplType, STDDeleter<BufferViewImplType, TBuffViewObjAllocator>> m_pDefaultSRV;
224 };
225 
226 } // namespace Diligent
Diligent::BufferViewDesc
Buffer view description.
Definition: BufferView.h:88
Diligent::BufferBase::CreateView
virtual void CreateView(const struct BufferViewDesc &ViewDesc, IBufferView **ppView) override
Implementation of IBuffer::CreateView(); calls CreateViewInternal() virtual function that creates buf...
Definition: BufferBase.hpp:106
Diligent::IReferenceCounters
Base interface for a reference counter object that stores the number of strong and weak references an...
Definition: ReferenceCounters.h:44
Diligent::BufferBase::CreateViewInternal
virtual void CreateViewInternal(const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView)=0
Pure virtual function that creates buffer view for the specific engine implementation.
Diligent::BufferBase::IsInKnownState
bool IsInKnownState() const
Definition: BufferBase.hpp:197
GraphicsAccessories.hpp
Diligent::BIND_UNORDERED_ACCESS
@ BIND_UNORDERED_ACCESS
A buffer or a texture can be bound as an unordered access view.
Definition: GraphicsTypes.h:127
DeviceObjectBase.hpp
Diligent::ValidateAndCorrectBufferViewDesc
void ValidateAndCorrectBufferViewDesc(const BufferDesc &BuffDesc, BufferViewDesc &ViewDesc) noexcept(false)
Validates and corrects buffer view description; throws an exception in case of an error.
Definition: BufferBase.cpp:145
Diligent::BufferBase< EngineGLImplTraits >::TBuffViewObjAllocator
typename EngineGLImplTraits ::BuffViewObjAllocatorType TBuffViewObjAllocator
Definition: BufferBase.hpp:72
STDAllocator.hpp
Diligent::Uint64
uint64_t Uint64
64-bit unsigned integer
Definition: BasicTypes.h:50
Diligent::DeviceCaps
struct DeviceCaps DeviceCaps
Definition: GraphicsTypes.h:1925
Diligent::BufferBase< EngineGLImplTraits >::BaseInterface
typename EngineGLImplTraits ::BufferInterface BaseInterface
Definition: BufferBase.hpp:63
UNEXPECTED
#define UNEXPECTED(...)
Definition: DebugUtilities.hpp:77
Diligent::ValidateBufferInitData
void ValidateBufferInitData(const BufferDesc &Desc, const BufferData *pBuffData) noexcept(false)
Validates initial buffer data parameters and throws an exception in case of an error.
Definition: BufferBase.cpp:117
Diligent::BufferDesc::BindFlags
BIND_FLAGS BindFlags
Buffer bind flags, see Diligent::BIND_FLAGS for details.
Definition: Buffer.h:85
Diligent::DeviceObjectBase< EngineImplTraits::BufferInterface, EngineImplTraits::RenderDeviceImplType, BufferDesc >::m_Desc
BufferDesc m_Desc
Object description.
Definition: DeviceObjectBase.hpp:182
Diligent::BufferBase::SetState
virtual void SetState(RESOURCE_STATE State) override final
Definition: BufferBase.hpp:187
DEV_CHECK_ERR
#define DEV_CHECK_ERR(...)
Definition: DebugUtilities.hpp:90
Diligent::BufferBase
Template class implementing base functionality of the buffer object.
Definition: BufferBase.hpp:59
Diligent::BufferBase::CreateDefaultViews
void CreateDefaultViews()
Creates default buffer views.
Definition: BufferBase.hpp:139
Diligent::BufferBase::BufferBase
BufferBase(IReferenceCounters *pRefCounters, TBuffViewObjAllocator &BuffViewObjAllocator, RenderDeviceImplType *pDevice, const BufferDesc &BuffDesc, bool bIsDeviceInternal)
Definition: BufferBase.hpp:83
Diligent::IBufferView::GetDesc
virtual const BufferViewDesc &METHOD() GetDesc() const override=0
Returns the buffer view description used to create the object.
Diligent::BufferBase::m_pDefaultUAV
std::unique_ptr< BufferViewImplType, STDDeleter< BufferViewImplType, TBuffViewObjAllocator > > m_pDefaultUAV
Default UAV addressing the entire buffer.
Definition: BufferBase.hpp:220
Diligent::BufferBase::GetDefaultView
virtual IBufferView * GetDefaultView(BUFFER_VIEW_TYPE ViewType) override
Implementation of IBuffer::GetDefaultView().
Definition: BufferBase.hpp:121
Diligent::BufferDesc
struct BufferDesc BufferDesc
Definition: Buffer.h:152
IMPLEMENT_QUERY_INTERFACE_IN_PLACE
#define IMPLEMENT_QUERY_INTERFACE_IN_PLACE(InterfaceID, ParentClassName)
Definition: ObjectBase.hpp:59
DILIGENT_CALL_TYPE
#define DILIGENT_CALL_TYPE
Definition: CommonDefinitions.h:45
Diligent::BufferBase< EngineGLImplTraits >::BufferViewImplType
typename EngineGLImplTraits ::BufferViewImplType BufferViewImplType
Definition: BufferBase.hpp:69
Diligent::ValidateBufferDesc
void ValidateBufferDesc(const BufferDesc &Desc, const DeviceCaps &deviceCaps) noexcept(false)
Validates buffer description and throws an exception in case of an error.
Definition: BufferBase.cpp:45
Buffer.h
FormatString.hpp
Diligent::BufferBase::TDeviceObjectBase
DeviceObjectBase< BaseInterface, RenderDeviceImplType, BufferDesc > TDeviceObjectBase
Definition: BufferBase.hpp:74
Diligent::RESOURCE_STATE_UNKNOWN
@ RESOURCE_STATE_UNKNOWN
The resource state is not known to the engine and is managed by the application.
Definition: GraphicsTypes.h:2817
Diligent::BufferData
struct BufferData BufferData
Definition: Buffer.h:175
Diligent::BUFFER_VIEW_SHADER_RESOURCE
@ BUFFER_VIEW_SHADER_RESOURCE
A buffer view will define a shader resource view that will be used as the source for the shader read ...
Definition: GraphicsTypes.h:310
Diligent::BufferDesc
Buffer description.
Definition: Buffer.h:74
Diligent::BUFFER_VIEW_UNORDERED_ACCESS
@ BUFFER_VIEW_UNORDERED_ACCESS
A buffer view will define an unordered access view that will be used for unordered read/write operati...
Definition: GraphicsTypes.h:314
Diligent::BufferBase::m_pDefaultSRV
std::unique_ptr< BufferViewImplType, STDDeleter< BufferViewImplType, TBuffViewObjAllocator > > m_pDefaultSRV
Default SRV addressing the entire buffer.
Definition: BufferBase.hpp:223
Diligent::BufferBase::CheckState
bool CheckState(RESOURCE_STATE State) const
Definition: BufferBase.hpp:202
Diligent::BufferBase::GetState
virtual RESOURCE_STATE GetState() const override final
Definition: BufferBase.hpp:192
Diligent::BufferViewDesc
struct BufferViewDesc BufferViewDesc
Definition: BufferView.h:140
Diligent::BufferDesc::CommandQueueMask
Uint64 CommandQueueMask
Defines which command queues this buffer can be used with.
Definition: Buffer.h:107
Diligent::BUFFER_VIEW_UNDEFINED
@ BUFFER_VIEW_UNDEFINED
Undefined view type.
Definition: GraphicsTypes.h:306
Diligent::BufferViewDesc::ViewType
BUFFER_VIEW_TYPE ViewType
View type. See Diligent::BUFFER_VIEW_TYPE for details.
Definition: BufferView.h:91
Diligent::BUFFER_MODE_STRUCTURED
@ BUFFER_MODE_STRUCTURED
Structured buffer. In this mode, ElementByteStride member of BufferDesc defines the structure stride.
Definition: Buffer.h:60
GraphicsTypes.h
VERIFY
#define VERIFY(...)
Definition: DebugUtilities.hpp:76
Diligent::BUFFER_MODE_RAW
@ BUFFER_MODE_RAW
Raw buffer. In this mode, the buffer is accessed as raw bytes. Formatted views of a raw buffer can al...
Definition: Buffer.h:67
Diligent::RESOURCE_STATE
RESOURCE_STATE
Resource usage state.
Definition: GraphicsTypes.h:2814
Diligent::IBufferView
Buffer view interface.
Definition: BufferView.h:155
Diligent::BUFFER_VIEW_TYPE
BUFFER_VIEW_TYPE
Buffer view type.
Definition: GraphicsTypes.h:303
Diligent::BufferBase::m_State
RESOURCE_STATE m_State
Definition: BufferBase.hpp:217
Diligent::BufferBase< EngineGLImplTraits >::RenderDeviceImplType
typename EngineGLImplTraits ::RenderDeviceImplType RenderDeviceImplType
Definition: BufferBase.hpp:66
Diligent::DeviceObjectAttribs::Name
const Char * Name
Object name.
Definition: GraphicsTypes.h:1199
Diligent::DeviceObjectBase
Template class implementing base functionality of the device object.
Definition: DeviceObjectBase.hpp:45
Diligent
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37
Diligent::BIND_SHADER_RESOURCE
@ BIND_SHADER_RESOURCE
A buffer or a texture can be bound as a shader resource.
Definition: GraphicsTypes.h:122