summaryrefslogtreecommitdiffstats
path: root/tools/gfx/metal/metal-vertex-layout.cpp
blob: 722d5396de301e3031d29347762b66f555b8648d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// metal-vertex-layout.cpp
#include "metal-vertex-layout.h"

#include "metal-util.h"

namespace gfx
{

using namespace Slang;

namespace metal
{

Result InputLayoutImpl::init(const IInputLayout::Desc& desc)
{
    for (Index i = 0; i < desc.inputElementCount; i++)
    {
        if (MetalUtil::translateVertexFormat(desc.inputElements[i].format) ==
            MTL::VertexFormatInvalid)
        {
            return SLANG_E_INVALID_ARG;
        }
        m_inputElements.add(desc.inputElements[i]);
    }
    for (Index i = 0; i < desc.vertexStreamCount; i++)
    {
        m_vertexStreams.add(desc.vertexStreams[i]);
    }
    return SLANG_OK;
}

NS::SharedPtr<MTL::VertexDescriptor> InputLayoutImpl::createVertexDescriptor(
    NS::UInteger vertexBufferIndexOffset)
{
    NS::SharedPtr<MTL::VertexDescriptor> vertexDescriptor =
        NS::TransferPtr(MTL::VertexDescriptor::alloc()->init());

    for (Index i = 0; i < m_inputElements.getCount(); i++)
    {
        const auto& inputElement = m_inputElements[i];
        MTL::VertexAttributeDescriptor* desc = vertexDescriptor->attributes()->object(i);
        desc->setOffset(inputElement.offset);
        desc->setBufferIndex(inputElement.bufferSlotIndex + vertexBufferIndexOffset);
        MTL::VertexFormat metalFormat = MetalUtil::translateVertexFormat(inputElement.format);
        desc->setFormat(metalFormat);
    }

    for (Index i = 0; i < m_vertexStreams.getCount(); i++)
    {
        const auto& vertexStream = m_vertexStreams[i];
        MTL::VertexBufferLayoutDescriptor* desc =
            vertexDescriptor->layouts()->object(i + vertexBufferIndexOffset);
        desc->setStepFunction(MetalUtil::translateVertexStepFunction(vertexStream.slotClass));
        desc->setStepRate(
            vertexStream.slotClass == InputSlotClass::PerVertex
                ? 1
                : vertexStream.instanceDataStepRate);
        desc->setStride(vertexStream.stride);
    }

    return vertexDescriptor;
}

} // namespace metal
} // namespace gfx