diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-02-19 01:26:36 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-02-19 01:26:36 +0000 |
| commit | a19d1631cf153cabd10ef7028cadde78385dfe25 (patch) | |
| tree | 30f86b670709e2bb122de052c29a9581b86bbb48 /Graphics/GraphicsEngine | |
| parent | Disabled all Vulkan features by default (diff) | |
| download | DiligentCore-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.h | 76 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/InputLayout.h | 20 |
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 |
