/* * 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 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