Parcourir la source

sample works now with amd+vulkan

Signed-off-by: mrieggeramzn <[email protected]>
mrieggeramzn il y a 3 ans
Parent
commit
5b8bf5fa96

+ 0 - 10
Gem/Code/Source/Platform/Windows/TriangleConstantBufferExampleComponent_Traits_Platform.h

@@ -1,10 +0,0 @@
-/*
- * 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
- *
- */
-
-#define ATOMSAMPLEVIEWER_TRAIT_TRIANGLE_CONSTANT_BUFFER_SAMPLE_SINGLE_CONSTANT_BUFFER_SIZE       15u  
-#define ATOMSAMPLEVIEWER_TRAIT_TRIANGLE_CONSTANT_BUFFER_SAMPLE_MULTIPLE_CONSTANT_BUFFER_SIZE     15u

+ 29 - 114
Gem/Code/Source/RHI/TrianglesConstantBufferExampleComponent.cpp

@@ -22,19 +22,10 @@
 
 
 #include <AzCore/Serialization/SerializeContext.h>
 #include <AzCore/Serialization/SerializeContext.h>
 
 
-#include <TriangleConstantBufferExampleComponent_Traits_Platform.h>
-
 namespace AtomSampleViewer
 namespace AtomSampleViewer
 {
 {
     const char* TrianglesConstantBufferExampleComponent::s_trianglesConstantBufferExampleName = "TrianglesConstantBufferExample";
     const char* TrianglesConstantBufferExampleComponent::s_trianglesConstantBufferExampleName = "TrianglesConstantBufferExample";
-    // The number of triangles that are represented with a single constant buffer, that contains multiple buffer views;
-    // each view containing a partial view of the constant buffer
-    const uint32_t TrianglesConstantBufferExampleComponent::s_numberOfTrianglesSingleCB = ATOMSAMPLEVIEWER_TRAIT_TRIANGLE_CONSTANT_BUFFER_SAMPLE_SINGLE_CONSTANT_BUFFER_SIZE;
-    // The number of triangles that are represented with multiple constant buffers;
-    // each having their own constant buffer and view containing the whole buffer
-    const uint32_t TrianglesConstantBufferExampleComponent::s_numberOfTrianglesMultipleCB = ATOMSAMPLEVIEWER_TRAIT_TRIANGLE_CONSTANT_BUFFER_SAMPLE_MULTIPLE_CONSTANT_BUFFER_SIZE;
-    // The total number of views and triangles that will be rendered for this sample
-    const uint32_t TrianglesConstantBufferExampleComponent::s_numberOfTrianglesTotal = s_numberOfTrianglesSingleCB + s_numberOfTrianglesMultipleCB;
+    const uint32_t TrianglesConstantBufferExampleComponent::s_numberOfTrianglesTotal = 30;
 
 
     void TrianglesConstantBufferExampleComponent::Reflect(AZ::ReflectContext* context)
     void TrianglesConstantBufferExampleComponent::Reflect(AZ::ReflectContext* context)
     {
     {
@@ -100,53 +91,22 @@ namespace AtomSampleViewer
         const uint32_t alignment = RHI::AlignUp(static_cast<uint32_t>(sizeof(InstanceInfo)), m_constantBufferAlighment);
         const uint32_t alignment = RHI::AlignUp(static_cast<uint32_t>(sizeof(InstanceInfo)), m_constantBufferAlighment);
 
 
         // All triangles data will be uploaded in one go to the constant buffer once per frame.
         // All triangles data will be uploaded in one go to the constant buffer once per frame.
-        UploadDataToSingleConstantBuffer(trianglesData, alignment, s_numberOfTrianglesSingleCB);
-        UploadDataToMultipleConstantBuffers(trianglesData + s_numberOfTrianglesSingleCB, alignment);
+        UploadDataToConstantBuffer(trianglesData, alignment, s_numberOfTrianglesTotal);
         
         
         BasicRHIComponent::OnFramePrepare(frameGraphBuilder);
         BasicRHIComponent::OnFramePrepare(frameGraphBuilder);
     }
     }
 
 
-    void TrianglesConstantBufferExampleComponent::UploadDataToSingleConstantBuffer(InstanceInfo* data, uint32_t elementSize, uint32_t elementCount)
+    void TrianglesConstantBufferExampleComponent::UploadDataToConstantBuffer(InstanceInfo* data, uint32_t elementSize, uint32_t elementCount)
     {
     {
         AZ::RHI::BufferMapRequest mapRequest;
         AZ::RHI::BufferMapRequest mapRequest;
         mapRequest.m_buffer = m_constantBuffer.get();
         mapRequest.m_buffer = m_constantBuffer.get();
-        mapRequest.m_byteCount = elementSize;
-
-        // NOTE: Due to the Constant Buffer alignment not being handled internally by the RHI, updating the Constant Buffer
-        // that is bound to an alignment needs to be handled by the user.
-        // Update the instance data of the triangles that are mapped to a single Constant Buffer
-        for (uint32_t triangleIdx = 0u; triangleIdx < elementCount; ++triangleIdx)
-        {
-            mapRequest.m_byteOffset = triangleIdx * elementSize;
-
-            AZ::RHI::BufferMapResponse mapResponse;
-            m_constantBufferPool->MapBuffer(mapRequest, mapResponse);
-            if (mapResponse.m_data)
-            {
-                memcpy(mapResponse.m_data, data + triangleIdx, sizeof(InstanceInfo));
-                m_constantBufferPool->UnmapBuffer(*mapRequest.m_buffer);
-            }
-        }
-    }
-
-    void TrianglesConstantBufferExampleComponent::UploadDataToMultipleConstantBuffers(InstanceInfo* data, uint32_t elementSize)
-    {
-        // Update the instance data of the triangles that are mapped to their individual Constant Buffer
-        for (uint32_t triangleIdx = 0u; triangleIdx < (uint32_t)m_constantBufferArray.size(); ++triangleIdx)
+        mapRequest.m_byteCount = elementSize * elementCount;
+        AZ::RHI::BufferMapResponse mapResponse;
+        AZ::RHI::ResultCode resultCode = m_constantBufferPool->MapBuffer(mapRequest, mapResponse);
+        if (resultCode == AZ::RHI::ResultCode::Success)
         {
         {
-            AZ::RHI::BufferMapRequest mapRequest;
-            mapRequest.m_buffer = m_constantBufferArray[triangleIdx].get();
-            mapRequest.m_byteCount = elementSize;
-            mapRequest.m_byteOffset = 0u;
-
-            AZ::RHI::BufferMapResponse mapResponse;
-            m_constantBufferPool->MapBuffer(mapRequest, mapResponse);
-
-            if(mapResponse.m_data)
-            {
-                memcpy(mapResponse.m_data, data + triangleIdx, sizeof(InstanceInfo));
-                m_constantBufferPool->UnmapBuffer(*mapRequest.m_buffer);
-            }
+            memcpy(mapResponse.m_data, data, sizeof(InstanceInfo) * elementCount);
+            m_constantBufferPool->UnmapBuffer(*mapRequest.m_buffer);
         }
         }
     }
     }
 
 
@@ -233,62 +193,7 @@ namespace AtomSampleViewer
             AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialized constant buffer pool");
             AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialized constant buffer pool");
         }
         }
 
 
-        // Calculate the total constant buffer size depending on the device alignment limit
-        const uint32_t alignedBufferSize = RHI::AlignUp(static_cast<uint32_t>(sizeof(InstanceInfo)), m_constantBufferAlighment);
-
-        // NOTE: Alignment needs to be taken into account when creating a Constant Buffer which consists of Buffer Views
-        // that have an offset that isn't 0
-        // Create single Constant Buffer with multiple Buffer Views
-        {
-            const uint32_t constantBufferSize = alignedBufferSize * s_numberOfTrianglesSingleCB;
-
-            m_constantBuffer = RHI::Factory::Get().CreateBuffer();
-            RHI::BufferInitRequest request;
-            request.m_buffer = m_constantBuffer.get();
-            request.m_descriptor = RHI::BufferDescriptor{ RHI::BufferBindFlags::Constant, constantBufferSize };
-            [[maybe_unused]] RHI::ResultCode result = m_constantBufferPool->InitBuffer(request);
-            AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize constant buffer");
-
-            for (uint32_t triangleIdx = 0u; triangleIdx < s_numberOfTrianglesSingleCB; ++triangleIdx)
-            {
-                RHI::BufferViewDescriptor bufferDesc = RHI::BufferViewDescriptor::CreateStructured(triangleIdx, 1u, alignedBufferSize);
-                AZ::RHI::Ptr<AZ::RHI::BufferView> constantBufferView = m_constantBuffer->GetBufferView(bufferDesc);
-                          
-                if(!constantBufferView.get())
-                {
-                    AZ_Assert(false, "Failed to initialized constant buffer view");
-                }
-                m_constantBufferViewArray.push_back(constantBufferView);
-            }
-        }
-
-        // Create multiple Constant Buffers, each containing one Buffer View
-        {
-            RHI::ResultCode result;
-            m_constantBufferArray.reserve(s_numberOfTrianglesMultipleCB);
-
-            for (uint32_t triangleIdx = 0u; triangleIdx < s_numberOfTrianglesMultipleCB; ++triangleIdx)
-            {
-                AZ::RHI::Ptr<AZ::RHI::Buffer> constantBuffer = RHI::Factory::Get().CreateBuffer();
-                RHI::BufferInitRequest request;
-                request.m_buffer = constantBuffer.get();
-                request.m_descriptor = RHI::BufferDescriptor{ RHI::BufferBindFlags::Constant, alignedBufferSize};
-                result = m_constantBufferPool->InitBuffer(request);
-                AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialized constant buffer");
-
-                RHI::BufferViewDescriptor bufferDesc = RHI::BufferViewDescriptor::CreateStructured(0u, 1u, alignedBufferSize);
-                AZ::RHI::Ptr<AZ::RHI::BufferView> constantBufferView = constantBuffer->GetBufferView(bufferDesc);
-                          
-                if(!constantBufferView.get())
-                {
-                    AZ_Assert(false, "Failed to initialized constant buffer view");
-                }
-                AZ_Assert(constantBufferView->IsFullView(), "Constant Buffer View initialization failed to cover in full the Constant Buffer");
-
-                m_constantBufferViewArray.push_back(constantBufferView);
-                m_constantBufferArray.push_back(constantBuffer);
-            }
-        }
+        CreateConstantBufferView();
 
 
         // Load the Shader and obtain the Pipeline state and its SRG
         // Load the Shader and obtain the Pipeline state and its SRG
         {
         {
@@ -319,13 +224,8 @@ namespace AtomSampleViewer
             RHI::ShaderInputBufferIndex trianglesBufferIndex;
             RHI::ShaderInputBufferIndex trianglesBufferIndex;
             FindShaderInputIndex(&trianglesBufferIndex, m_shaderResourceGroup, trianglesBufferId, s_trianglesConstantBufferExampleName);
             FindShaderInputIndex(&trianglesBufferIndex, m_shaderResourceGroup, trianglesBufferId, s_trianglesConstantBufferExampleName);
 
 
-            uint32_t viewIdx = 0u;
-            for (const AZ::RHI::Ptr<AZ::RHI::BufferView>& bufferView : m_constantBufferViewArray)
-            {
-                [[maybe_unused]] bool set = m_shaderResourceGroup->SetBufferView(trianglesBufferIndex, bufferView.get(), viewIdx);
-                AZ_Assert(set, "Failed to set the buffer view");
-                viewIdx++;
-            }
+            [[maybe_unused]] bool set = m_shaderResourceGroup->SetBufferView(trianglesBufferIndex, m_constantBufferView.get(), 0);
+            AZ_Assert(set, "Failed to set the buffer view");
 
 
             // All SRG data has been set already, it only had the buffer view to be set, we can compile now.
             // All SRG data has been set already, it only had the buffer view to be set, we can compile now.
             // Later then only thing to do is to update the Buffer content itself, but the SRG won't need to be recompiled.
             // Later then only thing to do is to update the Buffer content itself, but the SRG won't need to be recompiled.
@@ -398,6 +298,22 @@ namespace AtomSampleViewer
         RHI::RHISystemNotificationBus::Handler::BusConnect();
         RHI::RHISystemNotificationBus::Handler::BusConnect();
     }
     }
 
 
+    void TrianglesConstantBufferExampleComponent::CreateConstantBufferView()
+    {
+        using namespace AZ;
+        const uint32_t constantBufferSize = sizeof(InstanceInfo) * s_numberOfTrianglesTotal;
+
+        m_constantBuffer = RHI::Factory::Get().CreateBuffer();
+        RHI::BufferInitRequest request;
+        request.m_buffer = m_constantBuffer.get();
+        request.m_descriptor = RHI::BufferDescriptor{ RHI::BufferBindFlags::Constant, constantBufferSize };
+        [[maybe_unused]] RHI::ResultCode result = m_constantBufferPool->InitBuffer(request);
+        AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize constant buffer");
+
+        RHI::BufferViewDescriptor bufferDesc = RHI::BufferViewDescriptor::CreateStructured(0, 1u, constantBufferSize);
+        m_constantBufferView = m_constantBuffer->GetBufferView(bufferDesc);
+    }
+
     void TrianglesConstantBufferExampleComponent::Deactivate()
     void TrianglesConstantBufferExampleComponent::Deactivate()
     {
     {
         using namespace AZ;
         using namespace AZ;
@@ -406,8 +322,7 @@ namespace AtomSampleViewer
         m_inputAssemblyBufferPool = nullptr;
         m_inputAssemblyBufferPool = nullptr;
 
 
         m_constantBuffer = nullptr;
         m_constantBuffer = nullptr;
-        m_constantBufferArray.clear();
-        m_constantBufferViewArray.clear();
+        m_constantBufferView = nullptr;
 
 
         m_constantBuffer = nullptr;
         m_constantBuffer = nullptr;
         m_constantBufferPool = nullptr;
         m_constantBufferPool = nullptr;

+ 4 - 12
Gem/Code/Source/RHI/TrianglesConstantBufferExampleComponent.h

@@ -61,8 +61,6 @@ namespace AtomSampleViewer
     private:
     private:
         static const char* s_trianglesConstantBufferExampleName;
         static const char* s_trianglesConstantBufferExampleName;
 
 
-        static const uint32_t s_numberOfTrianglesSingleCB;
-        static const uint32_t s_numberOfTrianglesMultipleCB;
         static const uint32_t s_numberOfTrianglesTotal;
         static const uint32_t s_numberOfTrianglesTotal;
 
 
         // AZ::Component
         // AZ::Component
@@ -75,10 +73,9 @@ namespace AtomSampleViewer
         // RHISystemNotificationBus::Handler
         // RHISystemNotificationBus::Handler
         void OnFramePrepare(AZ::RHI::FrameGraphBuilder& frameGraphBuilder) override;
         void OnFramePrepare(AZ::RHI::FrameGraphBuilder& frameGraphBuilder) override;
 
 
-        // Updates a single buffer with multiple triangle instance data
-        void UploadDataToSingleConstantBuffer(InstanceInfo* data, uint32_t elementSize, uint32_t elementCount);
-        // Updates multiple buffers, each with a single triangle instance data
-        void UploadDataToMultipleConstantBuffers(InstanceInfo* data, uint32_t elementSize);
+        // Updates a single constant buffer with multiple triangle instances
+        void UploadDataToConstantBuffer(InstanceInfo* data, uint32_t elementSize, uint32_t elementCount);
+        void CreateConstantBufferView();
         
         
         AZ::RHI::DrawItem m_drawItem;
         AZ::RHI::DrawItem m_drawItem;
 
 
@@ -100,16 +97,11 @@ namespace AtomSampleViewer
         AZStd::array<AZ::RHI::StreamBufferView, 2> m_streamBufferViews;
         AZStd::array<AZ::RHI::StreamBufferView, 2> m_streamBufferViews;
         AZ::RHI::IndexBufferView m_indexBufferView;
         AZ::RHI::IndexBufferView m_indexBufferView;
 
 
-        // Pool where both buffers are allocated from
         AZ::RHI::Ptr<AZ::RHI::BufferPool> m_constantBufferPool;
         AZ::RHI::Ptr<AZ::RHI::BufferPool> m_constantBufferPool;
 
 
-        // Pool with single Buffer
         AZ::RHI::Ptr<AZ::RHI::Buffer> m_constantBuffer;
         AZ::RHI::Ptr<AZ::RHI::Buffer> m_constantBuffer;
-        // Pool with multiple Buffers
-        AZStd::vector<AZ::RHI::Ptr<AZ::RHI::Buffer>> m_constantBufferArray;
 
 
-        // Buffer views that hold both from 
-        AZStd::vector<AZ::RHI::Ptr<AZ::RHI::BufferView>> m_constantBufferViewArray;
+        AZ::RHI::Ptr<AZ::RHI::BufferView> m_constantBufferView;
 
 
         // Cached Constant Buffer alignment queued from the device
         // Cached Constant Buffer alignment queued from the device
         uint32_t m_constantBufferAlighment = 0u;
         uint32_t m_constantBufferAlighment = 0u;

+ 4 - 70
Shaders/RHI/TrianglesConstantBuffer.azsl

@@ -8,86 +8,20 @@
 
 
  #include <Atom/Features/SrgSemantics.azsli>
  #include <Atom/Features/SrgSemantics.azsli>
 
 
-// Number of triangles that will be rendered on screen
-// Uniform limitation need to be taken into consideration for mobile devices
-// [ATOM-14949]
-#if AZ_TRAIT_CONSTANT_BUFFER_LIMITATIONS
-
-#define MAX_NUMBER_OF_INSTANCES 12
-
-#else
-
-#define MAX_NUMBER_OF_INSTANCES 30
-
-#endif
-
-// Padding sizes for different platform memory alignment requirements
-#ifdef AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT
-
-
-// Size of InstanceInfo: sizeof(float4x4) + sizeof(float4) = 64 + 16 = 80
-// if InstanceInfo size < alignment size:
-//      diff = alignment size - InstanceInfo size 
-//      if diff > 0:
-//          padding = (alignment size - InstanceInfo size) / 16
-//      else:
-//          padding = 0
-// else:
-//      left_over = InstanceInfo size % alignment
-//      if left_over > 0: 
-//          padding = (alignment - left_over) / 16
-//      else:
-//          padding = 0
-#if AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT == 16
-
-#define NUM_INSTANCE_INFO_PADDINGS 0                    // 80 % 16 == 0
-
-#elif AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT == 32
-
-#define NUM_INSTANCE_INFO_PADDINGS 1                    // 80 % 32 => (16 > 0) => (32 - 16) / 16 = 1
-
-#elif AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT == 64         
-
-#define NUM_INSTANCE_INFO_PADDINGS 3                    // 80 % 64 => (16 > 0) => (64 - 16) / 16 = 3
-
-#elif AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT == 128
-
-#define NUM_INSTANCE_INFO_PADDINGS 3                    // (128 - 80) / 16 = 3
-
-#else
-
-#define NUM_INSTANCE_INFO_PADDINGS 11                   // (256 - 80) / 16 = 11
-
-#endif
-
-#else 
-
-#define NUM_INSTANCE_INFO_PADDINGS 11                   // account for platform default values
-
-#endif // #ifdef AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT
-
-
 struct InstanceInfo
 struct InstanceInfo
 {
 {
     column_major float4x4 m_matrix;
     column_major float4x4 m_matrix;
     float4 m_colorMultiplier;
     float4 m_colorMultiplier;
-    // NOTE: This actually shouldn't be required, but the current validation will give a false positive
-    // when the stride isn't the same size as the stride defined on the applicaiton side.
-    // This assumes 256 alignment, which is standard for DX12, but is variable in Vulkan
-#if NUM_INSTANCE_INFO_PADDINGS != 0
-    float4 m_padding0[NUM_INSTANCE_INFO_PADDINGS];
-#endif
-
 };
 };
 
 
 struct InstanceData
 struct InstanceData
 {
 {
-    InstanceInfo m_instancesInfo;
+    InstanceInfo m_instancesInfo[30];
 };
 };
 
 
 ShaderResourceGroup TriangleSrg : SRG_PerObject
 ShaderResourceGroup TriangleSrg : SRG_PerObject
 {
 {
-    ConstantBuffer<InstanceData> m_trianglesCB[MAX_NUMBER_OF_INSTANCES];
+    ConstantBuffer<InstanceData> m_trianglesCB;
 }
 }
 
 
 struct VSInput
 struct VSInput
@@ -103,11 +37,11 @@ struct VSOutput
     float4 m_color : COLOR0;
     float4 m_color : COLOR0;
 };
 };
 
 
-VSOutput MainVS(VSInput vsInput)
+VSOutput MainVS(const VSInput vsInput)
 {
 {
     VSOutput OUT;
     VSOutput OUT;
     
     
-    InstanceInfo triangleInstanceInfo = TriangleSrg::m_trianglesCB[vsInput.m_instanceIndex].m_instancesInfo;
+    const InstanceInfo triangleInstanceInfo = TriangleSrg::m_trianglesCB.m_instancesInfo[vsInput.m_instanceIndex];
     
     
     OUT.m_position = mul(float4(vsInput.m_position, 1.0f),triangleInstanceInfo.m_matrix);
     OUT.m_position = mul(float4(vsInput.m_position, 1.0f),triangleInstanceInfo.m_matrix);
     OUT.m_color = vsInput.m_color * triangleInstanceInfo.m_colorMultiplier;
     OUT.m_color = vsInput.m_color * triangleInstanceInfo.m_colorMultiplier;