/* * Copyright 2019-2021 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * In no event and under no legal theory, whether in tort (including negligence), * contract, or otherwise, unless required by applicable law (such as deliberate * and grossly negligent acts) or agreed to in writing, shall any Contributor be * liable for any damages, including any direct, indirect, special, incidental, * or consequential damages of any character arising as a result of this License or * out of the use or inability to use the software (including but not limited to damages * for loss of goodwill, work stoppage, computer failure or malfunction, or any and * all other commercial damages or losses), even if such Contributor has been advised * of the possibility of such damages. */ #pragma once // clang-format off /// \file /// Definition input layout #include #include "GraphicsTypes.h" DILIGENT_BEGIN_NAMESPACE(Diligent) static const Uint32 MAX_LAYOUT_ELEMENTS = 16; static const Uint32 LAYOUT_ELEMENT_AUTO_OFFSET = 0xFFFFFFFF; static const Uint32 LAYOUT_ELEMENT_AUTO_STRIDE = 0xFFFFFFFF; /// Input frequency enum INPUT_ELEMENT_FREQUENCY { /// Frequency is undefined. INPUT_ELEMENT_FREQUENCY_UNDEFINED = 0, /// Input data is per-vertex data. INPUT_ELEMENT_FREQUENCY_PER_VERTEX, /// Input data is per-instance data. INPUT_ELEMENT_FREQUENCY_PER_INSTANCE, /// Helper value that stores the total number of frequencies in the enumeration. INPUT_ELEMENT_FREQUENCY_NUM_FREQUENCIES }; /// Description of a single element of the input layout struct LayoutElement { /// HLSL semantic. Default value ("ATTRIB") allows HLSL shaders to be converted /// to GLSL and used in OpenGL backend as well as compiled to SPIRV and used /// in Vulkan backend. /// Any value other than default will only work in Direct3D11 and Direct3D12 backends. const char* HLSLSemantic DEFAULT_INITIALIZER("ATTRIB"); /// Input index of the element that is specified in the vertex shader. /// In Direct3D11 and Direct3D12 backends this is the semantic index. Uint32 InputIndex DEFAULT_INITIALIZER(0); /// Buffer slot index that this element is read from. Uint32 BufferSlot DEFAULT_INITIALIZER(0); /// Number of components in the element. Allowed values are 1, 2, 3, and 4. Uint32 NumComponents DEFAULT_INITIALIZER(0); /// Type of the element components, see Diligent::VALUE_TYPE for details. VALUE_TYPE ValueType DEFAULT_INITIALIZER(VT_FLOAT32); /// For signed and unsigned integer value types /// (VT_INT8, VT_INT16, VT_INT32, VT_UINT8, VT_UINT16, VT_UINT32) /// indicates if the value should be normalized to [-1,+1] or /// [0, 1] range respectively. For floating point types /// (VT_FLOAT16 and VT_FLOAT32), this member is ignored. Bool IsNormalized DEFAULT_INITIALIZER(True); /// Relative offset, in bytes, to the element bits. /// If this value is set to LAYOUT_ELEMENT_AUTO_OFFSET (default value), the offset will /// be computed automatically by placing the element right after the previous one. Uint32 RelativeOffset DEFAULT_INITIALIZER(LAYOUT_ELEMENT_AUTO_OFFSET); /// Stride, in bytes, between two elements, for this buffer slot. /// If this value is set to LAYOUT_ELEMENT_AUTO_STRIDE, 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 LAYOUT_ELEMENT_AUTO_STRIDE value. Uint32 Stride DEFAULT_INITIALIZER(LAYOUT_ELEMENT_AUTO_STRIDE); enum INPUT_ELEMENT_FREQUENCY Frequency DEFAULT_INITIALIZER(INPUT_ELEMENT_FREQUENCY_PER_VERTEX); /// The number of instances to draw using the same per-instance data before advancing /// in the buffer by one element. Uint32 InstanceDataStepRate DEFAULT_INITIALIZER(1); #if DILIGENT_CPP_INTERFACE LayoutElement()noexcept{} /// Initializes the structure LayoutElement(Uint32 _InputIndex, Uint32 _BufferSlot, Uint32 _NumComponents, VALUE_TYPE _ValueType, Bool _IsNormalized = LayoutElement{}.IsNormalized, Uint32 _RelativeOffset = LayoutElement{}.RelativeOffset, Uint32 _Stride = LayoutElement{}.Stride, INPUT_ELEMENT_FREQUENCY _Frequency = LayoutElement{}.Frequency, Uint32 _InstanceDataStepRate = LayoutElement{}.InstanceDataStepRate)noexcept : InputIndex {_InputIndex }, BufferSlot {_BufferSlot }, NumComponents {_NumComponents }, ValueType {_ValueType }, IsNormalized {_IsNormalized }, RelativeOffset {_RelativeOffset }, Stride {_Stride }, Frequency {_Frequency }, InstanceDataStepRate{_InstanceDataStepRate} {} /// Initializes the structure LayoutElement(const char* _HLSLSemantic, Uint32 _InputIndex, Uint32 _BufferSlot, Uint32 _NumComponents, VALUE_TYPE _ValueType, Bool _IsNormalized = LayoutElement{}.IsNormalized, Uint32 _RelativeOffset = LayoutElement{}.RelativeOffset, Uint32 _Stride = LayoutElement{}.Stride, INPUT_ELEMENT_FREQUENCY _Frequency = LayoutElement{}.Frequency, Uint32 _InstanceDataStepRate = LayoutElement{}.InstanceDataStepRate)noexcept : HLSLSemantic {_HLSLSemantic }, InputIndex {_InputIndex }, BufferSlot {_BufferSlot }, NumComponents {_NumComponents }, ValueType {_ValueType }, IsNormalized {_IsNormalized }, RelativeOffset {_RelativeOffset }, Stride {_Stride }, Frequency {_Frequency }, InstanceDataStepRate{_InstanceDataStepRate} {} /// Initializes the structure LayoutElement(Uint32 _InputIndex, Uint32 _BufferSlot, Uint32 _NumComponents, VALUE_TYPE _ValueType, Bool _IsNormalized, INPUT_ELEMENT_FREQUENCY _Frequency, Uint32 _InstanceDataStepRate = LayoutElement{}.InstanceDataStepRate)noexcept : InputIndex {_InputIndex }, BufferSlot {_BufferSlot }, NumComponents {_NumComponents }, ValueType {_ValueType }, IsNormalized {_IsNormalized }, RelativeOffset {LayoutElement{}.RelativeOffset}, Stride {LayoutElement{}.Stride }, Frequency {_Frequency }, InstanceDataStepRate{_InstanceDataStepRate } {} bool operator == (const LayoutElement& rhs) const { return strcmp(HLSLSemantic, rhs.HLSLSemantic) == 0 && InputIndex == rhs.InputIndex && BufferSlot == rhs.BufferSlot && NumComponents == rhs.NumComponents && ValueType == rhs.ValueType && IsNormalized == rhs.IsNormalized && RelativeOffset == rhs.RelativeOffset && Stride == rhs.Stride && Frequency == rhs.Frequency && InstanceDataStepRate == rhs.InstanceDataStepRate; } bool operator != (const LayoutElement& rhs) const { return !(*this == rhs); } #endif }; typedef struct LayoutElement LayoutElement; /// Layout description /// This structure is used by IRenderDevice::CreateGraphicsPipelineState(). struct InputLayoutDesc { /// Array of layout elements const LayoutElement* LayoutElements DEFAULT_INITIALIZER(nullptr); /// Number of layout elements Uint32 NumElements DEFAULT_INITIALIZER(0); #if DILIGENT_CPP_INTERFACE InputLayoutDesc()noexcept{} InputLayoutDesc(const LayoutElement* _LayoutElements, Uint32 _NumElements)noexcept : LayoutElements{_LayoutElements}, NumElements {_NumElements } {} bool operator == (const InputLayoutDesc& rhs) const { if (NumElements != rhs.NumElements) return false; for (Uint32 i=0; i < NumElements; ++i) { if (LayoutElements[i] != rhs.LayoutElements[i]) return false; } return true; } bool operator != (const InputLayoutDesc& rhs) const { return !(*this == rhs); } #endif }; typedef struct InputLayoutDesc InputLayoutDesc; DILIGENT_END_NAMESPACE