diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp index 9f70310174..d50e5ff719 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp @@ -102,7 +102,8 @@ namespace AZ // Register Shader Resource Group Layout Builder AssetBuilderSDK::AssetBuilderDesc srgLayoutBuilderDescriptor; srgLayoutBuilderDescriptor.m_name = "Shader Resource Group Layout Builder"; - srgLayoutBuilderDescriptor.m_version = 52; // ATOM-14780 + srgLayoutBuilderDescriptor.m_version = 53; // ATOM-15196 + srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.azsl", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.azsli", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", SrgLayoutBuilder::MergedPartialSrgsExtension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); @@ -117,7 +118,7 @@ namespace AZ // Register Shader Asset Builder AssetBuilderSDK::AssetBuilderDesc shaderAssetBuilderDescriptor; shaderAssetBuilderDescriptor.m_name = "Shader Asset Builder"; - shaderAssetBuilderDescriptor.m_version = 96; // SPEC-6065 + shaderAssetBuilderDescriptor.m_version = 97; // ATOM-15196 // .shader file changes trigger rebuilds shaderAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern( AZStd::string::format("*.%s", RPI::ShaderSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); shaderAssetBuilderDescriptor.m_busId = azrtti_typeid(); @@ -132,7 +133,7 @@ namespace AZ shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder"; // Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update // ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder". - shaderVariantAssetBuilderDescriptor.m_version = 17; // SPEC-6065 + shaderVariantAssetBuilderDescriptor.m_version = 18; // ATOM-15196 shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid(); shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); diff --git a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp index e576c9486b..8c86169d5c 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp @@ -646,8 +646,8 @@ namespace AZ return 0; // Nothing to draw. } - auto vertexBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(totalVtxBufferSize); - auto indexBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(totalIdxBufferSize); + auto vertexBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(totalVtxBufferSize, RHI::Alignment::InputAssembly); + auto indexBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(totalIdxBufferSize, RHI::Alignment::InputAssembly); if (!vertexBuffer || !indexBuffer) { diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h index 4c0a490b70..d12d30284e 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h @@ -30,38 +30,42 @@ namespace AZ { None = 0, - /// Supports input assembly access through a IndexBufferView or StreamBufferView. + /// Supports input assembly access through a IndexBufferView or StreamBufferView. This flag is for buffers that are not updated often InputAssembly = AZ_BIT(0), - + + /// Supports input assembly access through a IndexBufferView or StreamBufferView. This flag is for buffers that are updated frequently + DynamicInputAssembly = AZ_BIT(1), + /// Supports constant access through a ShaderResourceGroup. - Constant = AZ_BIT(1), + Constant = AZ_BIT(2), /// Supports read access through a ShaderResourceGroup. - ShaderRead = AZ_BIT(2), + ShaderRead = AZ_BIT(3), /// Supports write access through ShaderResourceGroup. - ShaderWrite = AZ_BIT(3), + ShaderWrite = AZ_BIT(4), /// Supports read-write access through a ShaderResourceGroup. ShaderReadWrite = ShaderRead | ShaderWrite, /// Supports read access for GPU copy operations. - CopyRead = AZ_BIT(4), + CopyRead = AZ_BIT(5), /// Supports write access for GPU copy operations. - CopyWrite = AZ_BIT(5), + CopyWrite = AZ_BIT(6), /// Supports predication access for conditional rendering. - Predication = AZ_BIT(6), + Predication = AZ_BIT(7), /// Supports indirect buffer access for indirect draw/dispatch. - Indirect = AZ_BIT(7), + Indirect = AZ_BIT(8), /// Supports ray tracing acceleration structure usage. - RayTracingAccelerationStructure = AZ_BIT(8), + RayTracingAccelerationStructure = AZ_BIT(9), /// Supports ray tracing shader table usage. - RayTracingShaderTable = AZ_BIT(9) + RayTracingShaderTable = AZ_BIT(10) + }; AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::RHI::BufferBindFlags); diff --git a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ReflectSystemComponent.cpp b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ReflectSystemComponent.cpp index 336793a8e3..cb6981f7f8 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ReflectSystemComponent.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ReflectSystemComponent.cpp @@ -54,7 +54,7 @@ namespace AZ if (SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(2); + ->Version(3); } ReflectNamedEnums(context); @@ -266,6 +266,7 @@ namespace AZ serializeContext->Enum() ->Value("None", BufferBindFlags::None) ->Value("InputAssembly", BufferBindFlags::InputAssembly) + ->Value("DynamicInputAssembly", BufferBindFlags::DynamicInputAssembly) ->Value("Constant", BufferBindFlags::Constant) ->Value("CopyRead", BufferBindFlags::CopyRead) ->Value("CopyWrite", BufferBindFlags::CopyWrite) diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferMemoryAllocator.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferMemoryAllocator.cpp index 50f4f736cc..b2c1a5fcaf 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferMemoryAllocator.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferMemoryAllocator.cpp @@ -39,7 +39,7 @@ namespace AZ // needs to be a multiple of elementsize as well as divisible by DX12::Alignment types. m_usePageAllocator = false; - if (!RHI::CheckBitsAny(descriptor.m_bindFlags, RHI::BufferBindFlags::ShaderWrite | RHI::BufferBindFlags::CopyWrite | RHI::BufferBindFlags::InputAssembly)) + if (!RHI::CheckBitsAny(descriptor.m_bindFlags, RHI::BufferBindFlags::ShaderWrite | RHI::BufferBindFlags::CopyWrite | RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly)) { m_usePageAllocator = true; diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferPool.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferPool.cpp index 4966b7c444..9eb5638186 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferPool.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/BufferPool.cpp @@ -39,7 +39,7 @@ namespace AZ { m_device = &device; - if (RHI::CheckBitsAll(descriptor.m_bindFlags, RHI::BufferBindFlags::InputAssembly)) + if(RHI::CheckBitsAny(descriptor.m_bindFlags, RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly)) { m_readOnlyState |= D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER | D3D12_RESOURCE_STATE_INDEX_BUFFER; } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.cpp index b2219754aa..841c71126a 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.cpp @@ -670,7 +670,13 @@ namespace AZ } else { - result &= AddExistingResourceEntry("texture", resourceStartPos, regId, argBufferStr); + bool isAdditionSuccessfull = AddExistingResourceEntry("texture", resourceStartPos, regId, argBufferStr); + if(!isAdditionSuccessfull) + { + //In metal depth textures use keyword depth2d/depth2d_array/depthcube/depthcube_array/depth2d_ms/depth2d_ms_array + isAdditionSuccessfull |= AddExistingResourceEntry("depth", resourceStartPos, regId, argBufferStr); + } + result &= isAdditionSuccessfull; } } return result; @@ -827,10 +833,13 @@ namespace AZ AZStd::string& argBufferStr) const { size_t prevEndOfLine = argBufferStr.rfind("\n", resourceStartPos); + size_t nextEndOfLine = argBufferStr.find("\n", resourceStartPos); size_t startOfEntryPos = argBufferStr.find(resourceStr, prevEndOfLine); - if(startOfEntryPos == AZStd::string::npos) + + //Check to see if a valid entry is found. + if(startOfEntryPos == AZStd::string::npos || startOfEntryPos > nextEndOfLine) { - AZ_Error(MetalShaderPlatformName, false, "Entry-> %s not found within Descriptor set %s", resourceStr, argBufferStr.c_str()); + AZ_Error(MetalShaderPlatformName, startOfEntryPos != AZStd::string::npos, "Entry-> %s not found within Descriptor set %s", resourceStr, argBufferStr.c_str()); return false; } else diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp index f831c3a9b0..891f9ea2f3 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp @@ -295,7 +295,7 @@ namespace AZ const RHI::Size sourceSize = RHI::Size(subresourceLayout.m_size.m_width, heightToCopy, 1); const RHI::Origin sourceOrigin = RHI::Origin(0, destHeight, depth); - CopyBufferToImage(framePacket, image, stagingRowPitch, stagingSlicePitch, + CopyBufferToImage(framePacket, image, stagingRowPitch, bytesCopied, curMip, arraySlice, sourceSize, sourceOrigin); framePacket->m_dataOffset += stagingSize; diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Conversions.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/Conversions.cpp index fbd50661cb..f95e871d33 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Conversions.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Conversions.cpp @@ -210,6 +210,12 @@ namespace AZ { return GetCPUGPUMemoryMode(); } + + //This flag is used for IA buffers that is updated frequently and hence shared mmory is the best fit + if (RHI::CheckBitsAll(descriptor.m_bindFlags, RHI::BufferBindFlags::DynamicInputAssembly)) + { + return MTLStorageModeShared; + } return GetCPUGPUMemoryMode(); } diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/BufferPool.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/BufferPool.cpp index b9d146d84e..081469b39a 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/BufferPool.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/BufferPool.cpp @@ -107,6 +107,7 @@ namespace AZ bool forceUnique = RHI::CheckBitsAny( bufferDescriptor.m_bindFlags, RHI::BufferBindFlags::InputAssembly | + RHI::BufferBindFlags::DynamicInputAssembly | RHI::BufferBindFlags::RayTracingAccelerationStructure | RHI::BufferBindFlags::RayTracingShaderTable); diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Conversion.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Conversion.cpp index 6ac761a929..accc18b5ec 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Conversion.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Conversion.cpp @@ -685,7 +685,7 @@ namespace AZ using BindFlags = RHI::BufferBindFlags; VkBufferUsageFlags usageFlags{ 0 }; - if (RHI::CheckBitsAny(bindFlags, BindFlags::InputAssembly)) + if (RHI::CheckBitsAny(bindFlags, BindFlags::InputAssembly | BindFlags::DynamicInputAssembly)) { usageFlags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT | @@ -932,7 +932,7 @@ namespace AZ VkPipelineStageFlags GetResourcePipelineStateFlags(const RHI::BufferBindFlags& bindFlags) { VkPipelineStageFlags stagesFlags = {}; - if (RHI::CheckBitsAny(bindFlags, RHI::BufferBindFlags::InputAssembly)) + if (RHI::CheckBitsAny(bindFlags, RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly)) { stagesFlags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; } @@ -1042,7 +1042,7 @@ namespace AZ VkAccessFlags GetResourceAccessFlags(const RHI::BufferBindFlags& bindFlags) { VkAccessFlags accessFlags = {}; - if (RHI::CheckBitsAny(bindFlags, RHI::BufferBindFlags::InputAssembly)) + if (RHI::CheckBitsAny(bindFlags, RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly)) { accessFlags |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDEX_READ_BIT; } diff --git a/Gems/Atom/RPI/Assets/ResourcePools/DefaultDynInputBufferPool.resourcepool b/Gems/Atom/RPI/Assets/ResourcePools/DefaultDynInputBufferPool.resourcepool index c80734cc38..0f2cb48580 100644 --- a/Gems/Atom/RPI/Assets/ResourcePools/DefaultDynInputBufferPool.resourcepool +++ b/Gems/Atom/RPI/Assets/ResourcePools/DefaultDynInputBufferPool.resourcepool @@ -8,6 +8,6 @@ "BudgetInBytes": 25165824, "BufferPoolHeapMemoryLevel": "Host", "BufferPoolhostMemoryAccess": "Write", - "BufferPoolBindFlags": "InputAssembly" + "BufferPoolBindFlags": "DynamicInputAssembly" } -} \ No newline at end of file +} diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicBuffer.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicBuffer.h index 9b6caeeaef..a1bbcd8d78 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicBuffer.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/DynamicDraw/DynamicBuffer.h @@ -36,7 +36,7 @@ namespace AZ //! buffer->Write(data, size); //! // Use the buffer view for DrawItem or etc. //! } - //! Note: DynamicBuffer should only be used for InputAssembly buffer or Constant buffer (not supported yet). + //! Note: DynamicBuffer should only be used for DynamicInputAssembly buffer or Constant buffer (not supported yet). class DynamicBuffer : public AZStd::intrusive_base { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/Buffer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/Buffer.cpp index 7bfcc588f1..81fd9e751b 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/Buffer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/Buffer.cpp @@ -74,8 +74,9 @@ namespace AZ const RHI::BufferView* Buffer::GetBufferView() const { - if (m_rhiBuffer->GetDescriptor().m_bindFlags == RHI::BufferBindFlags::InputAssembly) + if(RHI::CheckBitsAny(m_rhiBuffer->GetDescriptor().m_bindFlags, RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly)) { + AZ_Assert(false, "Input assembly buffer doesn't need a regular buffer view, it requires a stream or index buffer view."); return nullptr; } @@ -203,11 +204,11 @@ namespace AZ void Buffer::InitBufferView() { // Skip buffer view creation for input assembly buffers - if (m_rhiBuffer->GetDescriptor().m_bindFlags == RHI::BufferBindFlags::InputAssembly) + if(RHI::CheckBitsAny(m_rhiBuffer->GetDescriptor().m_bindFlags, RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly)) { return; } - + m_bufferView = m_rhiBuffer->GetBufferView(m_bufferViewDescriptor); if(!m_bufferView.get()) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp index 5f279ba533..fd2d029ddb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp @@ -105,7 +105,7 @@ namespace AZ bufferPoolDesc.m_hostMemoryAccess = RHI::HostMemoryAccess::Write; break; case CommonBufferPoolType::DynamicInputAssembly: - bufferPoolDesc.m_bindFlags = RHI::BufferBindFlags::InputAssembly; + bufferPoolDesc.m_bindFlags = RHI::BufferBindFlags::DynamicInputAssembly; bufferPoolDesc.m_heapMemoryLevel = RHI::HeapMemoryLevel::Host; bufferPoolDesc.m_hostMemoryAccess = RHI::HostMemoryAccess::Write; break; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicBufferAllocator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicBufferAllocator.cpp index e4599901a9..e79aa2e1bb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicBufferAllocator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicBufferAllocator.cpp @@ -63,6 +63,7 @@ namespace AZ // [GFX TODO][ATOM-13182] Add unit tests for DynamicBufferAllocator's Allocate function RHI::Ptr DynamicBufferAllocator::Allocate(uint32_t size, [[maybe_unused]]uint32_t alignment) { + size = RHI::AlignUp(size, alignment); uint32_t allocatePosition = 0; //m_ringBufferStartAddress can be null for Null back end diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp index d0262f7f83..a5082c5ee6 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp @@ -174,7 +174,7 @@ namespace AZ } else if (GetAttachmentType() == RHI::AttachmentType::Buffer) { - bool isInputAssembly = RHI::CheckBitsAny(m_descriptor.m_buffer.m_bindFlags, RHI::BufferBindFlags::InputAssembly); + bool isInputAssembly = RHI::CheckBitsAny(m_descriptor.m_buffer.m_bindFlags, RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly); bool isConstant = RHI::CheckBitsAny(m_descriptor.m_buffer.m_bindFlags, RHI::BufferBindFlags::Constant); // Since InputAssembly and Constant cannot be inferred they are set manually. If those flags are set we don't want to add inferred flags on top as it may have a performance penalty