Files
o3de/Gems/Atom/RHI/Code/Source/RHI.Reflect/InputStreamLayoutBuilder.cpp
T
2021-04-23 09:43:40 -07:00

112 lines
4.0 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Atom/RHI.Reflect/InputStreamLayoutBuilder.h>
namespace AZ
{
namespace RHI
{
InputStreamLayoutBuilder::InputStreamLayoutBuilder()
{
Begin();
}
void InputStreamLayoutBuilder::Begin()
{
m_topology = PrimitiveTopology::TriangleList;
m_bufferDescriptorBuilders.clear();
}
InputStreamLayout InputStreamLayoutBuilder::End()
{
InputStreamLayout layout;
layout.SetTopology(m_topology);
for (BufferDescriptorBuilder& builder : m_bufferDescriptorBuilders)
{
builder.m_bufferDescriptor.m_byteStride = builder.m_byteOffset;
layout.AddStreamBuffer(builder.m_bufferDescriptor);
for (StreamChannelDescriptor& channelDescriptor : builder.m_channelDescriptors)
{
layout.AddStreamChannel(channelDescriptor);
}
}
layout.Finalize();
return layout;
}
void InputStreamLayoutBuilder::SetTopology(PrimitiveTopology topology)
{
m_topology = topology;
}
InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::BufferDescriptorBuilder::Channel(const ShaderSemantic& semantic, Format format)
{
if (m_channelDescriptors.size() == m_channelDescriptors.capacity())
{
AZ_Error("InputStreamLayoutBuilder", false, "No space to add stream channel.");
}
else
{
m_channelDescriptors.push_back();
StreamChannelDescriptor& channel = m_channelDescriptors.back();
channel.m_bufferIndex = m_bufferIndex;
channel.m_byteOffset = m_byteOffset;
channel.m_format = format;
channel.m_semantic = semantic;
m_byteOffset += GetFormatSize(format);
}
return this;
}
InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::BufferDescriptorBuilder::Channel(AZStd::string_view semantic, Format format)
{
return Channel(ShaderSemantic::Parse(semantic), format);
}
InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::BufferDescriptorBuilder::Padding(uint32_t byteCount)
{
m_byteOffset += byteCount;
return this;
}
InputStreamLayoutBuilder::BufferDescriptorBuilder* InputStreamLayoutBuilder::AddBuffer(StreamStepFunction stepFunction, uint32_t stepRate)
{
if (m_bufferDescriptorBuilders.size() == m_bufferDescriptorBuilders.capacity())
{
AZ_Error("InputStreamLayoutBuilder", false, "No space to add stream buffer.");
// Return a dummy so that subsequent calls to register channels won't crash and don't require null check clutter.
return &m_dummyBufferDescriptorBuilder;
}
m_bufferDescriptorBuilders.push_back();
BufferDescriptorBuilder* builder = &m_bufferDescriptorBuilders.back();
builder->m_bufferIndex = static_cast<uint32_t>(m_bufferDescriptorBuilders.size() - 1);
builder->m_bufferDescriptor.m_stepFunction = stepFunction;
builder->m_bufferDescriptor.m_stepRate = stepRate;
return builder;
}
} // namespace RHI
} // namespace AZ