summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-02-19 01:26:36 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-02-19 01:26:36 +0000
commita19d1631cf153cabd10ef7028cadde78385dfe25 (patch)
tree30f86b670709e2bb122de052c29a9581b86bbb48 /Graphics/GraphicsEngine
parentDisabled all Vulkan features by default (diff)
downloadDiligentCore-a19d1631cf153cabd10ef7028cadde78385dfe25.tar.gz
DiligentCore-a19d1631cf153cabd10ef7028cadde78385dfe25.zip
FIxed issue with automatic input layout element stride computation
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.h76
-rw-r--r--Graphics/GraphicsEngine/interface/InputLayout.h20
2 files changed, 56 insertions, 40 deletions
diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.h b/Graphics/GraphicsEngine/include/PipelineStateBase.h
index e9b21986..78aa55ec 100644
--- a/Graphics/GraphicsEngine/include/PipelineStateBase.h
+++ b/Graphics/GraphicsEngine/include/PipelineStateBase.h
@@ -61,8 +61,8 @@ public:
RenderDeviceImplType* pDevice,
const PipelineStateDesc& PSODesc,
bool bIsDeviceInternal = false ) :
- TDeviceObjectBase( pRefCounters, pDevice, PSODesc, bIsDeviceInternal ),
- m_LayoutElements( PSODesc.GraphicsPipeline.InputLayout.NumElements, LayoutElement{}, STD_ALLOCATOR_RAW_MEM(LayoutElement, GetRawAllocator(), "Allocator for vector<LayoutElement>" ) ),
+ TDeviceObjectBase (pRefCounters, pDevice, PSODesc, bIsDeviceInternal),
+ m_LayoutElements (PSODesc.GraphicsPipeline.InputLayout.NumElements, LayoutElement{}, STD_ALLOCATOR_RAW_MEM(LayoutElement, GetRawAllocator(), "Allocator for vector<LayoutElement>")),
m_NumShaders(0)
{
if (this->m_Desc.IsComputePipeline)
@@ -86,7 +86,7 @@ public:
}
else
{
- const auto &GraphicsPipeline = PSODesc.GraphicsPipeline;
+ const auto& GraphicsPipeline = PSODesc.GraphicsPipeline;
VALIDATE_SHADER_TYPE(GraphicsPipeline.pVS, SHADER_TYPE_VERTEX, "vertex")
VALIDATE_SHADER_TYPE(GraphicsPipeline.pPS, SHADER_TYPE_PIXEL, "pixel")
@@ -101,71 +101,85 @@ public:
m_pDS = GraphicsPipeline.pDS;
m_pHS = GraphicsPipeline.pHS;
- if( GraphicsPipeline.pVS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pVS;
- if( GraphicsPipeline.pPS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pPS;
- if( GraphicsPipeline.pGS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pGS;
- if( GraphicsPipeline.pHS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pHS;
- if( GraphicsPipeline.pDS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pDS;
+ if (GraphicsPipeline.pVS) m_ppShaders[m_NumShaders++] = GraphicsPipeline.pVS;
+ if (GraphicsPipeline.pPS) m_ppShaders[m_NumShaders++] = GraphicsPipeline.pPS;
+ if (GraphicsPipeline.pGS) m_ppShaders[m_NumShaders++] = GraphicsPipeline.pGS;
+ if (GraphicsPipeline.pHS) m_ppShaders[m_NumShaders++] = GraphicsPipeline.pHS;
+ if (GraphicsPipeline.pDS) m_ppShaders[m_NumShaders++] = GraphicsPipeline.pDS;
}
- const auto &InputLayout = PSODesc.GraphicsPipeline.InputLayout;
- for( size_t Elem = 0; Elem < InputLayout.NumElements; ++Elem )
+ const auto& InputLayout = PSODesc.GraphicsPipeline.InputLayout;
+ for (size_t Elem = 0; Elem < InputLayout.NumElements; ++Elem)
m_LayoutElements[Elem] = InputLayout.LayoutElements[Elem];
this->m_Desc.GraphicsPipeline.InputLayout.LayoutElements = m_LayoutElements.data();
+ // Set all strides to an invalid value because an application may want to use 0 stride
+ for (auto& Stride : m_Strides)
+ Stride = LayoutElement::AutoStride;
+
// Correct description and compute offsets and tight strides
decltype(m_Strides) TightStrides = {};
- for( auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It )
+ for (auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It)
{
if( It->ValueType == VT_FLOAT32 || It->ValueType == VT_FLOAT16 )
It->IsNormalized = false; // Floating point values cannot be normalized
auto BuffSlot = It->BufferSlot;
- if( BuffSlot >= m_Strides.size() )
+ if (BuffSlot >= m_Strides.size())
{
- UNEXPECTED("Buffer slot (", BuffSlot, ") exceeds the limit (", m_Strides.size(), ")");
+ UNEXPECTED("Buffer slot (", BuffSlot, ") exceeds maximum allowed value (", m_Strides.size()-1, ")");
continue;
}
m_BufferSlotsUsed = std::max(m_BufferSlotsUsed, BuffSlot + 1);
- auto &CurrStride = TightStrides[BuffSlot];
- if( It->RelativeOffset < CurrStride )
+ auto& CurrAutoStride = TightStrides[BuffSlot];
+ // If offset is not explicitly specified, use current auto stride value
+ if (It->RelativeOffset == LayoutElement::AutoOffset)
{
- if( It->RelativeOffset == 0 )
- It->RelativeOffset = CurrStride;
- else
- UNEXPECTED( "Overlapping layout elements" );
+ It->RelativeOffset = CurrAutoStride;
}
- if(It->Stride != 0)
+ // If stride is explicitly specified, use it for the current buffer slot
+ if (It->Stride != LayoutElement::AutoStride)
{
- if(m_Strides[BuffSlot] != 0)
+ // Verify that the value is consistent with the previously specified stride, if any
+ if (m_Strides[BuffSlot] != LayoutElement::AutoStride && m_Strides[BuffSlot] != It->Stride)
{
- if (m_Strides[BuffSlot] != It->Stride)
- LOG_ERROR_AND_THROW("Inconsistent strides specified for buffer slot ", BuffSlot,
- ". Current value: ", m_Strides[BuffSlot], ". New value: ", It->Stride);
+ LOG_ERROR_MESSAGE("Inconsistent strides are specified for buffer slot ", BuffSlot, ". "
+ "Input element at index ", It->InputIndex, " explicitly specifies stride ", It->Stride, ", "
+ "while current value is ", m_Strides[BuffSlot], ". Specify consistent strides or use "
+ "LayoutElement::AutoStride to allow the engine compute strides automatically.");
}
m_Strides[BuffSlot] = It->Stride;
}
- CurrStride += It->NumComponents * GetValueSize( It->ValueType );
+ CurrAutoStride = std::max(CurrAutoStride, It->RelativeOffset + It->NumComponents * GetValueSize(It->ValueType));
}
- for( auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It )
+ for (auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It)
{
auto BuffSlot = It->BufferSlot;
- if(m_Strides[BuffSlot] == 0)
+ // If no input elements explicitly specified stride for this buffer slot, use automatic stride
+ if (m_Strides[BuffSlot] == LayoutElement::AutoStride)
{
m_Strides[BuffSlot] = TightStrides[BuffSlot];
}
else
{
- VERIFY(m_Strides[BuffSlot] >= TightStrides[BuffSlot], "Stride (", m_Strides[BuffSlot], ") explicitly specified for slot ", BuffSlot, " is smaller than the total element size (", TightStrides[BuffSlot], ")");
+ if (m_Strides[BuffSlot] < TightStrides[BuffSlot])
+ {
+ LOG_ERROR_MESSAGE("Stride ", m_Strides[BuffSlot], " explicitly specified for slot ", BuffSlot, " is smaller than the "
+ "minimum stride ", TightStrides[BuffSlot], " required to accomodate all input elements.");
+ }
}
- if(It->Stride == 0)
+ if (It->Stride == LayoutElement::AutoStride)
It->Stride = m_Strides[BuffSlot];
- else
- VERIFY(m_Strides[BuffSlot] == It->Stride, "Incosistent stride");
+ }
+ // Set strides for unused slots to 0
+ for (Uint32 slot = 0; slot < m_BufferSlotsUsed; ++slot)
+ {
+ if (m_Strides[slot] == LayoutElement::AutoStride)
+ m_Strides[slot] = 0;
}
Uint64 DeviceQueuesMask = pDevice->GetCommandQueueMask();
diff --git a/Graphics/GraphicsEngine/interface/InputLayout.h b/Graphics/GraphicsEngine/interface/InputLayout.h
index 4490f91d..079d6a86 100644
--- a/Graphics/GraphicsEngine/interface/InputLayout.h
+++ b/Graphics/GraphicsEngine/interface/InputLayout.h
@@ -36,6 +36,9 @@ static constexpr Uint32 iMaxLayoutElements = 16;
/// Description of a single element of the input layout
struct LayoutElement
{
+ static constexpr Uint32 AutoOffset = static_cast<Uint32>(-1);
+ static constexpr Uint32 AutoStride = static_cast<Uint32>(-1);
+
/// Input index of the element, which is specified in the vertex shader.
Uint32 InputIndex = 0;
@@ -56,17 +59,16 @@ struct LayoutElement
Bool IsNormalized = True;
/// Relative offset, in bytes, to the element bits.
- /// If this value is zero, the offset will be computed automatically assuming
- /// that all previous elements in the same buffer slot are tightly packed.
- /// Overlapping elements are not allowed.
- Uint32 RelativeOffset = 0;
+ /// If this value is set to LayoutElement::AutoOffset (default value), the offset will
+ /// be computed automatically by placing the element right after the previous one.
+ Uint32 RelativeOffset = AutoOffset;
/// Stride, in bytes, between two elements, for this buffer slot.
- /// If this value is zero, stride will be computed automatically assuming
- /// that all elements in the same buffer slot are tightly packed.
- /// If buffer slot contains multiple layout elements, they all must use
- /// the same stride or zero.
- Uint32 Stride = 0;
+ /// If this value is set to LayoutElement::AutoStride, the stride will be
+ /// computed automatically assuming that all elements in the same buffer slot are
+ /// packed one after another. If the buffer slot contains multiple layout elements,
+ /// they all must specify the same stride or use AutoStride value.
+ Uint32 Stride = AutoOffset;
/// Input frequency
enum FREQUENCY : Int32