summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-11-06 05:43:17 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-11-06 05:43:17 +0000
commitdb5cfe224b9ff00234b29ff097262bc7377b90c4 (patch)
treee903167999d17f714223d00466fb4e9ace05c811 /Graphics/GraphicsEngine
parentRenamed StringPool::Release to StringPool::Clear (diff)
downloadDiligentCore-db5cfe224b9ff00234b29ff097262bc7377b90c4.tar.gz
DiligentCore-db5cfe224b9ff00234b29ff097262bc7377b90c4.zip
Refactored BufferBase
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/include/BufferBase.hpp179
-rw-r--r--Graphics/GraphicsEngine/src/BufferBase.cpp51
2 files changed, 112 insertions, 118 deletions
diff --git a/Graphics/GraphicsEngine/include/BufferBase.hpp b/Graphics/GraphicsEngine/include/BufferBase.hpp
index 605bc2ed..0ccbc0aa 100644
--- a/Graphics/GraphicsEngine/include/BufferBase.hpp
+++ b/Graphics/GraphicsEngine/include/BufferBase.hpp
@@ -42,8 +42,15 @@
namespace Diligent
{
-void ValidateBufferInitData(const BufferDesc& Desc, const BufferData* pBuffData);
-void ValidateBufferDesc(const BufferDesc& Desc, const DeviceCaps& deviceCaps);
+/// Validates buffer description and throws an exception in case of an error.
+void ValidateBufferDesc(const BufferDesc& Desc, const DeviceCaps& deviceCaps) noexcept(false);
+
+/// Validates initial buffer data parameters and throws an exception in case of an error.
+void ValidateBufferInitData(const BufferDesc& Desc, const BufferData* pBuffData) noexcept(false);
+
+/// Validates and corrects buffer view description; throws an exception in case of an error.
+void ValidateAndCorrectBufferViewDesc(const BufferDesc& BuffDesc, BufferViewDesc& ViewDesc) noexcept(false);
+
/// Template class implementing base functionality for a buffer object
@@ -93,10 +100,31 @@ public:
/// Implementation of IBuffer::CreateView(); calls CreateViewInternal() virtual function
/// that creates buffer view for the specific engine implementation.
- virtual void DILIGENT_CALL_TYPE CreateView(const struct BufferViewDesc& ViewDesc, IBufferView** ppView) override;
+ virtual void DILIGENT_CALL_TYPE CreateView(const struct BufferViewDesc& ViewDesc, IBufferView** ppView) override
+ {
+ DEV_CHECK_ERR(ViewDesc.ViewType != BUFFER_VIEW_UNDEFINED, "Buffer view type is not specified");
+ if (ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE)
+ 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");
+ else if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS)
+ 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");
+ else
+ UNEXPECTED("Unexpected buffer view type");
+
+ CreateViewInternal(ViewDesc, ppView, false);
+ }
+
/// Implementation of IBuffer::GetDefaultView().
- virtual IBufferView* DILIGENT_CALL_TYPE GetDefaultView(BUFFER_VIEW_TYPE ViewType) override;
+ virtual IBufferView* DILIGENT_CALL_TYPE GetDefaultView(BUFFER_VIEW_TYPE ViewType) override
+ {
+ switch (ViewType)
+ {
+ case BUFFER_VIEW_SHADER_RESOURCE: return m_pDefaultSRV.get();
+ case BUFFER_VIEW_UNORDERED_ACCESS: return m_pDefaultUAV.get();
+ default: UNEXPECTED("Unknown view type"); return nullptr;
+ }
+ }
+
/// Creates default buffer views.
@@ -105,7 +133,37 @@ public:
/// - Creates default unordered access view addressing the entire buffer if Diligent::BIND_UNORDERED_ACCESS flag is set
///
/// The function calls CreateViewInternal().
- void CreateDefaultViews();
+ void CreateDefaultViews()
+ {
+ // Create default views for structured and raw buffers. For formatted buffers we do not know the view format, so
+ // cannot create views.
+
+ if (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
+ {
+ BufferViewDesc ViewDesc;
+ ViewDesc.ViewType = BUFFER_VIEW_UNORDERED_ACCESS;
+ auto UAVName = FormatString("Default UAV of buffer '", this->m_Desc.Name, '\'');
+ ViewDesc.Name = UAVName.c_str();
+
+ IBufferView* pUAV = nullptr;
+ CreateViewInternal(ViewDesc, &pUAV, true);
+ m_pDefaultUAV.reset(static_cast<BufferViewImplType*>(pUAV));
+ VERIFY(m_pDefaultUAV->GetDesc().ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected view type");
+ }
+
+ if (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
+ {
+ BufferViewDesc ViewDesc;
+ ViewDesc.ViewType = BUFFER_VIEW_SHADER_RESOURCE;
+ auto SRVName = FormatString("Default SRV of buffer '", this->m_Desc.Name, '\'');
+ ViewDesc.Name = SRVName.c_str();
+
+ IBufferView* pSRV = nullptr;
+ CreateViewInternal(ViewDesc, &pSRV, true);
+ m_pDefaultSRV.reset(static_cast<BufferViewImplType*>(pSRV));
+ VERIFY(m_pDefaultSRV->GetDesc().ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpected view type");
+ }
+ }
virtual void DILIGENT_CALL_TYPE SetState(RESOURCE_STATE State) override final
{
@@ -133,9 +191,6 @@ protected:
/// Pure virtual function that creates buffer view for the specific engine implementation.
virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView) = 0;
- /// Corrects buffer view description and validates view parameters.
- void CorrectBufferViewDesc(struct BufferViewDesc& ViewDesc);
-
#ifdef DILIGENT_DEBUG
TBuffViewObjAllocator& m_dbgBuffViewAllocator;
#endif
@@ -149,112 +204,4 @@ protected:
std::unique_ptr<BufferViewImplType, STDDeleter<BufferViewImplType, TBuffViewObjAllocator>> m_pDefaultSRV;
};
-
-
-
-template <class BaseInterface, class RenderDeviceImplType, class BufferViewImplType, class TBuffViewObjAllocator>
-void BufferBase<BaseInterface, RenderDeviceImplType, BufferViewImplType, TBuffViewObjAllocator>::CreateView(const struct BufferViewDesc& ViewDesc, IBufferView** ppView)
-{
- DEV_CHECK_ERR(ViewDesc.ViewType != BUFFER_VIEW_UNDEFINED, "Buffer view type is not specified");
- if (ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE)
- 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");
- else if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS)
- 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");
- else
- UNEXPECTED("Unexpected buffer view type");
-
- CreateViewInternal(ViewDesc, ppView, false);
-}
-
-
-template <class BaseInterface, class RenderDeviceImplType, class BufferViewImplType, class TBuffViewObjAllocator>
-void BufferBase<BaseInterface, RenderDeviceImplType, BufferViewImplType, TBuffViewObjAllocator>::CorrectBufferViewDesc(struct BufferViewDesc& ViewDesc)
-{
- if (ViewDesc.ByteWidth == 0)
- {
- DEV_CHECK_ERR(this->m_Desc.uiSizeInBytes > ViewDesc.ByteOffset, "Byte offset (", ViewDesc.ByteOffset, ") exceeds buffer size (", this->m_Desc.uiSizeInBytes, ")");
- ViewDesc.ByteWidth = this->m_Desc.uiSizeInBytes - ViewDesc.ByteOffset;
- }
- if (ViewDesc.ByteOffset + ViewDesc.ByteWidth > this->m_Desc.uiSizeInBytes)
- LOG_ERROR_AND_THROW("Buffer view range [", ViewDesc.ByteOffset, ", ", ViewDesc.ByteOffset + ViewDesc.ByteWidth, ") is out of the buffer boundaries [0, ", this->m_Desc.uiSizeInBytes, ").");
- if ((this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS) ||
- (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE))
- {
- if (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_FORMATTED)
- {
- VERIFY(this->m_Desc.ElementByteStride != 0, "Element byte stride is zero");
- if ((ViewDesc.ByteOffset % this->m_Desc.ElementByteStride) != 0)
- LOG_ERROR_AND_THROW("Buffer view byte offset (", ViewDesc.ByteOffset, ") is not multiple of element byte stride (", this->m_Desc.ElementByteStride, ").");
- if ((ViewDesc.ByteWidth % this->m_Desc.ElementByteStride) != 0)
- LOG_ERROR_AND_THROW("Buffer view byte width (", ViewDesc.ByteWidth, ") is not multiple of element byte stride (", this->m_Desc.ElementByteStride, ").");
- }
-
- if (this->m_Desc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType == VT_UNDEFINED)
- LOG_ERROR_AND_THROW("Format must be specified when creating a view of a formatted buffer");
-
- if (this->m_Desc.Mode == BUFFER_MODE_FORMATTED || (this->m_Desc.Mode == BUFFER_MODE_RAW && ViewDesc.Format.ValueType != VT_UNDEFINED))
- {
- if (ViewDesc.Format.NumComponents <= 0 || ViewDesc.Format.NumComponents > 4)
- LOG_ERROR_AND_THROW("Incorrect number of components (", Uint32{ViewDesc.Format.NumComponents}, "). 1, 2, 3, or 4 are allowed values");
- if (ViewDesc.Format.ValueType == VT_FLOAT32 || ViewDesc.Format.ValueType == VT_FLOAT16)
- ViewDesc.Format.IsNormalized = false;
- auto ViewElementStride = GetValueSize(ViewDesc.Format.ValueType) * Uint32{ViewDesc.Format.NumComponents};
- if (this->m_Desc.Mode == BUFFER_MODE_RAW && this->m_Desc.ElementByteStride == 0)
- LOG_ERROR_AND_THROW("To enable formatted views of a raw buffer, element byte must be specified during buffer initialization");
- if (ViewElementStride != this->m_Desc.ElementByteStride)
- LOG_ERROR_AND_THROW("Buffer element byte stride (", this->m_Desc.ElementByteStride, ") is not consistent with the size (", ViewElementStride, ") defined by the format of the view (", GetBufferFormatString(ViewDesc.Format), ')');
- }
-
- if (this->m_Desc.Mode == BUFFER_MODE_RAW && ViewDesc.Format.ValueType == VT_UNDEFINED)
- {
- if ((ViewDesc.ByteOffset % 16) != 0)
- LOG_ERROR_AND_THROW("When creating a RAW view, the offset of the first element from the start of the buffer (", ViewDesc.ByteOffset, ") must be a multiple of 16 bytes");
- }
- }
-}
-
-template <class BaseInterface, class RenderDeviceImplType, class BufferViewImplType, class TBuffViewObjAllocator>
-IBufferView* BufferBase<BaseInterface, RenderDeviceImplType, BufferViewImplType, TBuffViewObjAllocator>::GetDefaultView(BUFFER_VIEW_TYPE ViewType)
-{
- switch (ViewType)
- {
- case BUFFER_VIEW_SHADER_RESOURCE: return m_pDefaultSRV.get();
- case BUFFER_VIEW_UNORDERED_ACCESS: return m_pDefaultUAV.get();
- default: UNEXPECTED("Unknown view type"); return nullptr;
- }
-}
-
-template <class BaseInterface, class RenderDeviceImplType, class BufferViewImplType, class TBuffViewObjAllocator>
-void BufferBase<BaseInterface, RenderDeviceImplType, BufferViewImplType, TBuffViewObjAllocator>::CreateDefaultViews()
-{
- // Create default views for structured and raw buffers. For formatted buffers we do not know the view format, so
- // cannot create views.
-
- if (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
- {
- BufferViewDesc ViewDesc;
- ViewDesc.ViewType = BUFFER_VIEW_UNORDERED_ACCESS;
- auto UAVName = FormatString("Default UAV of buffer '", this->m_Desc.Name, '\'');
- ViewDesc.Name = UAVName.c_str();
-
- IBufferView* pUAV = nullptr;
- CreateViewInternal(ViewDesc, &pUAV, true);
- m_pDefaultUAV.reset(static_cast<BufferViewImplType*>(pUAV));
- VERIFY(m_pDefaultUAV->GetDesc().ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected view type");
- }
-
- if (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
- {
- BufferViewDesc ViewDesc;
- ViewDesc.ViewType = BUFFER_VIEW_SHADER_RESOURCE;
- auto SRVName = FormatString("Default SRV of buffer '", this->m_Desc.Name, '\'');
- ViewDesc.Name = SRVName.c_str();
-
- IBufferView* pSRV = nullptr;
- CreateViewInternal(ViewDesc, &pSRV, true);
- m_pDefaultSRV.reset(static_cast<BufferViewImplType*>(pSRV));
- VERIFY(m_pDefaultSRV->GetDesc().ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpected view type");
- }
-}
-
} // namespace Diligent
diff --git a/Graphics/GraphicsEngine/src/BufferBase.cpp b/Graphics/GraphicsEngine/src/BufferBase.cpp
index 88ed62d9..5156764b 100644
--- a/Graphics/GraphicsEngine/src/BufferBase.cpp
+++ b/Graphics/GraphicsEngine/src/BufferBase.cpp
@@ -42,7 +42,7 @@ namespace Diligent
} while (false)
-void ValidateBufferDesc(const BufferDesc& Desc, const DeviceCaps& deviceCaps)
+void ValidateBufferDesc(const BufferDesc& Desc, const DeviceCaps& deviceCaps) noexcept(false)
{
static_assert(BIND_FLAGS_LAST == 0x400L, "Please update this function to handle the new bind flags");
@@ -114,7 +114,7 @@ void ValidateBufferDesc(const BufferDesc& Desc, const DeviceCaps& deviceCaps)
}
}
-void ValidateBufferInitData(const BufferDesc& Desc, const BufferData* pBuffData)
+void ValidateBufferInitData(const BufferDesc& Desc, const BufferData* pBuffData) noexcept(false)
{
if (Desc.Usage == USAGE_IMMUTABLE && (pBuffData == nullptr || pBuffData->pData == nullptr))
LOG_BUFFER_ERROR_AND_THROW("initial data must not be null as immutable buffers must be initialized at creation time.");
@@ -142,4 +142,51 @@ void ValidateBufferInitData(const BufferDesc& Desc, const BufferData* pBuffData)
#undef VERIFY_BUFFER
#undef LOG_BUFFER_ERROR_AND_THROW
+void ValidateAndCorrectBufferViewDesc(const BufferDesc& BuffDesc, BufferViewDesc& ViewDesc) noexcept(false)
+{
+ if (ViewDesc.ByteWidth == 0)
+ {
+ DEV_CHECK_ERR(BuffDesc.uiSizeInBytes > ViewDesc.ByteOffset, "Byte offset (", ViewDesc.ByteOffset, ") exceeds buffer size (", BuffDesc.uiSizeInBytes, ")");
+ ViewDesc.ByteWidth = BuffDesc.uiSizeInBytes - ViewDesc.ByteOffset;
+ }
+
+ if (ViewDesc.ByteOffset + ViewDesc.ByteWidth > BuffDesc.uiSizeInBytes)
+ LOG_ERROR_AND_THROW("Buffer view range [", ViewDesc.ByteOffset, ", ", ViewDesc.ByteOffset + ViewDesc.ByteWidth, ") is out of the buffer boundaries [0, ", BuffDesc.uiSizeInBytes, ").");
+
+ if ((BuffDesc.BindFlags & BIND_UNORDERED_ACCESS) ||
+ (BuffDesc.BindFlags & BIND_SHADER_RESOURCE))
+ {
+ if (BuffDesc.Mode == BUFFER_MODE_STRUCTURED || BuffDesc.Mode == BUFFER_MODE_FORMATTED)
+ {
+ VERIFY(BuffDesc.ElementByteStride != 0, "Element byte stride is zero");
+ if ((ViewDesc.ByteOffset % BuffDesc.ElementByteStride) != 0)
+ LOG_ERROR_AND_THROW("Buffer view byte offset (", ViewDesc.ByteOffset, ") is not a multiple of element byte stride (", BuffDesc.ElementByteStride, ").");
+ if ((ViewDesc.ByteWidth % BuffDesc.ElementByteStride) != 0)
+ LOG_ERROR_AND_THROW("Buffer view byte width (", ViewDesc.ByteWidth, ") is not a multiple of element byte stride (", BuffDesc.ElementByteStride, ").");
+ }
+
+ if (BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType == VT_UNDEFINED)
+ LOG_ERROR_AND_THROW("Format must be specified when creating a view of a formatted buffer");
+
+ if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || (BuffDesc.Mode == BUFFER_MODE_RAW && ViewDesc.Format.ValueType != VT_UNDEFINED))
+ {
+ if (ViewDesc.Format.NumComponents <= 0 || ViewDesc.Format.NumComponents > 4)
+ LOG_ERROR_AND_THROW("Incorrect number of components (", Uint32{ViewDesc.Format.NumComponents}, "). 1, 2, 3, or 4 are allowed values");
+ if (ViewDesc.Format.ValueType == VT_FLOAT32 || ViewDesc.Format.ValueType == VT_FLOAT16)
+ ViewDesc.Format.IsNormalized = false;
+ auto ViewElementStride = GetValueSize(ViewDesc.Format.ValueType) * Uint32{ViewDesc.Format.NumComponents};
+ if (BuffDesc.Mode == BUFFER_MODE_RAW && BuffDesc.ElementByteStride == 0)
+ LOG_ERROR_AND_THROW("To enable formatted views of a raw buffer, element byte must be specified during buffer initialization");
+ if (ViewElementStride != BuffDesc.ElementByteStride)
+ LOG_ERROR_AND_THROW("Buffer element byte stride (", BuffDesc.ElementByteStride, ") is not consistent with the size (", ViewElementStride, ") defined by the format of the view (", GetBufferFormatString(ViewDesc.Format), ')');
+ }
+
+ if (BuffDesc.Mode == BUFFER_MODE_RAW && ViewDesc.Format.ValueType == VT_UNDEFINED)
+ {
+ if ((ViewDesc.ByteOffset % 16) != 0)
+ LOG_ERROR_AND_THROW("When creating a RAW view, the offset of the first element from the start of the buffer (", ViewDesc.ByteOffset, ") must be a multiple of 16 bytes");
+ }
+ }
+}
+
} // namespace Diligent