/* * Copyright (c) Contributors to the Open 3D Engine Project * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include #include #include "ShaderAssetTestUtils.h" namespace UnitTest { template void AddShaderInputToBindingInfo(AZ::RHI::ShaderResourceGroupBindingInfo& bindingInfo, const T& shaderInputs) { for (const auto& shaderInput : shaderInputs) { bindingInfo.m_resourcesRegisterMap.insert( { shaderInput.m_name.GetStringView(), AZ::RHI::ResourceBindingInfo{ AZ::RHI::ShaderStageMask::Vertex, shaderInput.m_registerId } }); } } static AZ::RHI::ShaderResourceGroupBindingInfo CreateShaderResourceGroupBindingInfo(const AZ::RHI::ShaderResourceGroupLayout* layout) { using namespace AZ; RHI::ShaderResourceGroupBindingInfo bindingInfo; if (!layout) { return bindingInfo; } if (layout->GetConstantDataSize()) { // All constant in the SRG use the same the register id. bindingInfo.m_constantDataBindingInfo.m_registerId = layout->GetShaderInputListForConstants()[0].m_registerId; } AddShaderInputToBindingInfo(bindingInfo, layout->GetShaderInputListForBuffers()); AddShaderInputToBindingInfo(bindingInfo, layout->GetShaderInputListForSamplers()); AddShaderInputToBindingInfo(bindingInfo, layout->GetShaderInputListForImages()); AddShaderInputToBindingInfo(bindingInfo, layout->GetStaticSamplers()); return bindingInfo; } static AZ::Data::Asset CreateTestShaderVariantAsset( AZ::RPI::ShaderVariantId id, AZ::RPI::ShaderVariantStableId stableId, const AZStd::vector& stagesToActivate = { AZ::RHI::ShaderStage::Vertex, AZ::RHI::ShaderStage::Fragment }) { using namespace AZ; RPI::ShaderVariantAssetCreator shaderVariantAssetCreator; shaderVariantAssetCreator.Begin(Uuid::CreateRandom(), id, stableId, false); shaderVariantAssetCreator.SetBuildTimestamp(AZStd::sys_time_t(1)); // Make non-zero. for (RHI::ShaderStage rhiStage : stagesToActivate) { RHI::Ptr shaderStageFunction = aznew StubRHI::ShaderStageFunction; shaderVariantAssetCreator.SetShaderFunction(rhiStage, shaderStageFunction); } Data::Asset shaderVariantAsset; shaderVariantAssetCreator.End(shaderVariantAsset); return shaderVariantAsset; } AZ::Data::Asset CreateTestShaderAsset( const AZ::Data::AssetId& shaderAssetId, AZ::RHI::Ptr optionalSrgLayout, AZ::RPI::Ptr optionalShaderOptions, const AZ::Name& shaderName, const AZ::Name& drawListName) { using namespace AZ; using namespace RPI; using namespace RHI; Data::Asset shaderAsset; RHI::Ptr pipelineLayoutDescriptor = RHI::PipelineLayoutDescriptor::Create(); if (optionalSrgLayout) { const RHI::ShaderResourceGroupLayout* layout = optionalSrgLayout.get(); RHI::ShaderResourceGroupBindingInfo bindingInfo = CreateShaderResourceGroupBindingInfo(layout); pipelineLayoutDescriptor->AddShaderResourceGroupLayoutInfo(*layout, bindingInfo); } pipelineLayoutDescriptor->Finalize(); if (!optionalShaderOptions) { optionalShaderOptions = RPI::ShaderOptionGroupLayout::Create(); optionalShaderOptions->Finalize(); } ShaderAssetCreator creator; creator.Begin(shaderAssetId); creator.SetName(shaderName); creator.SetDrawListName(drawListName); creator.SetDrawListName(drawListName); creator.SetShaderOptionGroupLayout(optionalShaderOptions); creator.BeginAPI(RHI::Factory::Get().GetType()); creator.BeginSupervariant(AZ::Name{}); // The default (first) supervariant MUST be nameless. if (optionalSrgLayout) { creator.SetSrgLayoutList({ optionalSrgLayout }); } creator.SetPipelineLayout(pipelineLayoutDescriptor); //creator.SetRenderStates(m_renderStates); //creator.SetInputContract(CreateSimpleShaderInputContract()); //creator.SetOutputContract(CreateSimpleShaderOutputContract()); RHI::ShaderStageAttributeMapList attributeMaps; attributeMaps.resize(RHI::ShaderStageCount); creator.SetShaderStageAttributeMapList(attributeMaps); Data::Asset shaderVariantAsset = CreateTestShaderVariantAsset(RPI::ShaderVariantId{}, RPI::ShaderVariantStableId{ 0 }); creator.SetRootShaderVariantAsset(shaderVariantAsset); creator.EndSupervariant(); creator.EndAPI(); creator.End(shaderAsset); return shaderAsset; } }