/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include 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(m_bufferDescriptorBuilders.size() - 1); builder->m_bufferDescriptor.m_stepFunction = stepFunction; builder->m_bufferDescriptor.m_stepRate = stepRate; return builder; } } // namespace RHI } // namespace AZ