123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- /*
- * 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 <RHI/BasicRHIComponent.h>
- #include <SampleComponentConfig.h>
- #include <Atom/Utils/AssetCollectionAsyncLoader.h>
- namespace AtomSampleViewer
- {
- AZ::RPI::Ptr<RHISamplePass> RHISamplePass::Create(const AZ::RPI::PassDescriptor& descriptor)
- {
- AZ::RPI::Ptr<RHISamplePass> pass = aznew RHISamplePass(descriptor);
- return AZStd::move(pass);
- }
- RHISamplePass::RHISamplePass(const AZ::RPI::PassDescriptor& descriptor)
- : AZ::RPI::RenderPass(descriptor)
- {
- m_flags.m_hasPipelineViewTag = true;
- m_pipelineViewTag = "MainCamera";
- }
- RHISamplePass::~RHISamplePass()
- {
- m_rhiSample = nullptr;
- }
- const AZ::RPI::PipelineViewTag& RHISamplePass::GetPipelineViewTag() const
- {
- return m_pipelineViewTag;
- }
- void RHISamplePass::SetRHISample(BasicRHIComponent* sample)
- {
- m_rhiSample = sample;
- if (m_rhiSample)
- {
- m_rhiSample->SetOutputInfo(m_outputAttachment->m_descriptor.m_image.m_size.m_width
- , m_outputAttachment->m_descriptor.m_image.m_size.m_height
- , m_outputAttachment->m_descriptor.m_image.m_format
- , m_outputAttachment->GetAttachmentId());
- }
- }
- void RHISamplePass::BuildInternal()
- {
- Base::BuildInternal();
- // The RHISamplePass template should have one owned image attachment which is the render target
- m_outputAttachment = m_ownedAttachments[0];
- // Force update pass attachment to get correct size and save it to local variables
- m_outputAttachment->Update();
- // update output info for the rhi sample
- if (m_rhiSample)
- {
- SetRHISample(m_rhiSample);
- }
- }
- void RHISamplePass::FrameBeginInternal(FramePrepareParams params)
- {
- // Note: we can't preview the output attachment of this pass properly
- // Ideally, we should import RHISamplePass's scope producer first, then rhi sample's scope producers
- // then add readback scope and preview copy scope.
- // We can't do it since some of them private to RenderPass which we can't access here.
- // Import this pass's scope producer
- Base::FrameBeginInternal(params);
- // Import sample's scope producer
- if (m_rhiSample)
- {
- auto frameGraphBuilder = params.m_frameGraphBuilder;
- m_rhiSample->FrameBeginInternal(*frameGraphBuilder);
- for (AZStd::shared_ptr<AZ::RHI::ScopeProducer>& producer : m_rhiSample->m_scopeProducers)
- {
- frameGraphBuilder->ImportScopeProducer(*producer);
- }
- }
- }
- uint32_t RHISamplePass::GetViewIndex() const
- {
- return m_viewIndex;
- }
- void RHISamplePass::SetViewIndex(const uint32_t viewIndex)
- {
- m_viewIndex = viewIndex;
- }
- bool BasicRHIComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
- {
- using namespace AZ;
- const auto config = azrtti_cast<const SampleComponentConfig*>(baseConfig);
- if (config != nullptr && config->m_windowContext)
- {
- m_windowContext = config->m_windowContext;
- return true;
- }
- return false;
- }
- void BasicRHIComponent::OnFramePrepare(AZ::RHI::FrameGraphBuilder& frameGraphBuilder)
- {
- // Check the swap chain since the system may still tick one more frame when window is closed and swapchain got destroied.
- if (!IsSupportedRHISamplePipeline() && m_windowContext->GetSwapChain())
- {
- SetOutputInfoFromWindowContext();
- FrameBeginInternal(frameGraphBuilder);
- for (AZStd::shared_ptr<AZ::RHI::ScopeProducer>& producer : m_scopeProducers)
- {
- frameGraphBuilder.ImportScopeProducer(*producer);
- }
- }
- }
- void BasicRHIComponent::SetVertexPosition(VertexPosition* positionBuffer, int bufferIndex, float x, float y, float z)
- {
- positionBuffer[bufferIndex].m_position[0] = x;
- positionBuffer[bufferIndex].m_position[1] = y;
- positionBuffer[bufferIndex].m_position[2] = z;
- }
- void BasicRHIComponent::SetVertexPosition(VertexPosition* positionBuffer, int bufferIndex, const AZ::Vector3& position)
- {
- positionBuffer[bufferIndex].m_position[0] = position.GetX();
- positionBuffer[bufferIndex].m_position[1] = position.GetY();
- positionBuffer[bufferIndex].m_position[2] = position.GetZ();
- }
- void BasicRHIComponent::SetVertexPosition(VertexPosition* positionBuffer, int bufferIndex, const VertexPosition& position)
- {
- positionBuffer[bufferIndex].m_position[0] = position.m_position[0];
- positionBuffer[bufferIndex].m_position[1] = position.m_position[1];
- positionBuffer[bufferIndex].m_position[2] = position.m_position[2];
- }
- void BasicRHIComponent::SetVertexColor(VertexColor* colorBuffer, int bufferIndex, float r, float g, float b, float a)
- {
- colorBuffer[bufferIndex].m_color[0] = r;
- colorBuffer[bufferIndex].m_color[1] = g;
- colorBuffer[bufferIndex].m_color[2] = b;
- colorBuffer[bufferIndex].m_color[3] = a;
- }
- void BasicRHIComponent::SetVertexColor(VertexColor* colorBuffer, int bufferIndex, const AZ::Vector4& color)
- {
- colorBuffer[bufferIndex].m_color[0] = color.GetX();
- colorBuffer[bufferIndex].m_color[1] = color.GetY();
- colorBuffer[bufferIndex].m_color[2] = color.GetZ();
- colorBuffer[bufferIndex].m_color[3] = color.GetW();
- }
- void BasicRHIComponent::SetVertexColor(VertexColor* colorBuffer, int bufferIndex, const VertexColor& color)
- {
- colorBuffer[bufferIndex].m_color[0] = color.m_color[0];
- colorBuffer[bufferIndex].m_color[1] = color.m_color[1];
- colorBuffer[bufferIndex].m_color[2] = color.m_color[2];
- colorBuffer[bufferIndex].m_color[3] = color.m_color[3];
- }
- void BasicRHIComponent::SetVertexIndex(uint16_t* indexBuffer, int bufferIndex, const uint16_t index)
- {
- indexBuffer[bufferIndex] = index;
- }
- void BasicRHIComponent::SetVertexU(VertexU* uBuffer, int bufferIndex, float u)
- {
- uBuffer[bufferIndex].m_u = u;
- }
- void BasicRHIComponent::SetVertexUV(VertexUV* uvBuffer, int bufferIndex, float u, float v)
- {
- uvBuffer[bufferIndex].m_uv[0] = u;
- uvBuffer[bufferIndex].m_uv[1] = v;
- }
- void BasicRHIComponent::SetVertexUVW(VertexUVW* uvwBuffer, int bufferIndex, float u, float v, float w)
- {
- uvwBuffer[bufferIndex].m_uvw[0] = u;
- uvwBuffer[bufferIndex].m_uvw[1] = v;
- uvwBuffer[bufferIndex].m_uvw[2] = w;
- }
- void BasicRHIComponent::SetVertexUVW(VertexUVW* uvwBuffer, int bufferIndex, const AZ::Vector3& uvw)
- {
- uvwBuffer[bufferIndex].m_uvw[0] = uvw.GetX();
- uvwBuffer[bufferIndex].m_uvw[1] = uvw.GetY();
- uvwBuffer[bufferIndex].m_uvw[2] = uvw.GetZ();
- }
- void BasicRHIComponent::SetVertexUVWX(VertexUVWX* uvwxBuffer, int bufferIndex, float u, float v, float w, float x)
- {
- uvwxBuffer[bufferIndex].m_uvwx[0] = u;
- uvwxBuffer[bufferIndex].m_uvwx[1] = v;
- uvwxBuffer[bufferIndex].m_uvwx[2] = w;
- uvwxBuffer[bufferIndex].m_uvwx[3] = x;
- }
- void BasicRHIComponent::SetVertexNormal(VertexNormal* normalBuffer, int bufferIndex, float nx, float ny, float nz)
- {
- normalBuffer[bufferIndex].m_normal[0] = nx;
- normalBuffer[bufferIndex].m_normal[1] = ny;
- normalBuffer[bufferIndex].m_normal[2] = nz;
- }
- void BasicRHIComponent::SetVertexNormal(VertexNormal* normalBuffer, int bufferIndex, const AZ::Vector3& normal)
- {
- normalBuffer[bufferIndex].m_normal[0] = normal.GetX();
- normalBuffer[bufferIndex].m_normal[1] = normal.GetY();
- normalBuffer[bufferIndex].m_normal[2] = normal.GetZ();
- }
- void BasicRHIComponent::SetFullScreenRect(VertexPosition* positionBuffer, VertexUV* uvBuffer, uint16_t* indexBuffer)
- {
- SetVertexPosition(positionBuffer, 0, -1.0f, -1.0f, 0.0f);
- SetVertexPosition(positionBuffer, 1, -1.0f, 1.0f, 0.0f);
- SetVertexPosition(positionBuffer, 2, 1.0f, 1.0f, 0.0f);
- SetVertexPosition(positionBuffer, 3, 1.0f, -1.0f, 0.0f);
- if (uvBuffer)
- {
- SetVertexUV(uvBuffer, 0, 0.0f, 0.0f);
- SetVertexUV(uvBuffer, 1, 0.0f, 1.0f);
- SetVertexUV(uvBuffer, 2, 1.0f, 1.0f);
- SetVertexUV(uvBuffer, 3, 1.0f, 0.0f);
- }
- indexBuffer[0] = 0;
- indexBuffer[1] = 3;
- indexBuffer[2] = 1;
- indexBuffer[3] = 1;
- indexBuffer[4] = 3;
- indexBuffer[5] = 2;
- }
- void BasicRHIComponent::SetCube(VertexPosition* positionBuffer, VertexColor* colorBuffer, VertexNormal* normalBuffer, uint16_t* indexBuffer)
- {
- static AZ::Vector3 vertices[] =
- {
- //Front Face
- AZ::Vector3(1.0, 1.0, 1.0), AZ::Vector3(-1.0, 1.0, 1.0), AZ::Vector3(-1.0, -1.0, 1.0), AZ::Vector3(1.0, -1.0, 1.0),
- //Back Face
- AZ::Vector3(1.0, 1.0, -1.0), AZ::Vector3(-1.0, 1.0, -1.0), AZ::Vector3(-1.0, -1.0, -1.0), AZ::Vector3(1.0, -1.0, -1.0),
- //Left Face
- AZ::Vector3(-1.0, 1.0, 1.0), AZ::Vector3(-1.0, -1.0, 1.0), AZ::Vector3(-1.0, -1.0, -1.0), AZ::Vector3(-1.0, 1.0, -1.0),
- //Right Face
- AZ::Vector3(1.0, 1.0, 1.0), AZ::Vector3(1.0, -1.0, 1.0), AZ::Vector3(1.0, -1.0, -1.0), AZ::Vector3(1.0, 1.0, -1.0),
- //Top Face
- AZ::Vector3(1.0, 1.0, 1.0), AZ::Vector3(-1.0, 1.0, 1.0), AZ::Vector3(-1.0, 1.0, -1.0), AZ::Vector3(1.0, 1.0, -1.0),
- //Bottom Face
- AZ::Vector3(1.0, -1.0, 1.0), AZ::Vector3(-1.0, -1.0, 1.0), AZ::Vector3(-1.0, -1.0, -1.0), AZ::Vector3(1.0, -1.0, -1.0)
- };
- static AZ::Vector4 colors[] =
- {
- //Front Face
- AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
- //Back Face
- AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
- //Left Face
- AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
- //Right Face
- AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
- //Top Face
- AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
- //Bottom Face
- AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0)
- };
- static AZ::Vector3 normals[] =
- {
- //Front Face
- AZ::Vector3(0.0, 0.0, 1.0), AZ::Vector3(0.0, 0.0, 1.0), AZ::Vector3(0.0, 0.0, 1.0), AZ::Vector3(0.0, 0.0, 1.0),
- //Back Face
- AZ::Vector3(0.0, 0.0,-1.0), AZ::Vector3(0.0, 0.0,-1.0), AZ::Vector3(0.0, 0.0,-1.0), AZ::Vector3(0.0, 0.0,-1.0),
- //Left Face
- AZ::Vector3(-1.0, 0.0, 0.0), AZ::Vector3(-1.0, 0.0, 0.0), AZ::Vector3(-1.0, 0.0, 0.0), AZ::Vector3(-1.0, 0.0, 0.0),
- //Right Face
- AZ::Vector3(1.0, 0.0, 0.0), AZ::Vector3(1.0, 0.0, 0.0), AZ::Vector3(1.0, 0.0, 0.0), AZ::Vector3(1.0, 0.0, 0.0),
- //Top Face
- AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0),
- //Bottom Face
- AZ::Vector3(0.0, -1.0, 0.0), AZ::Vector3(0.0, -1.0, 0.0), AZ::Vector3(0.0, -1.0, 0.0), AZ::Vector3(0.0, -1.0, 0.0)
- };
- static uint16_t indices[] =
- {
- //Back
- 2, 0, 1,
- 0, 2, 3,
- //Front
- 4, 6, 5,
- 6, 4, 7,
- //Left
- 8, 10, 9,
- 10, 8, 11,
- //Right
- 14, 12, 13,
- 15, 12, 14,
- //Top
- 16, 18, 17,
- 18, 16, 19,
- //Bottom
- 22, 20, 21,
- 23, 20, 22
- };
- for (int i = 0; i < AZ_ARRAY_SIZE(vertices); ++i)
- {
- SetVertexPosition(positionBuffer, i, vertices[i]);
- if (colorBuffer)
- {
- SetVertexColor(colorBuffer, i, colors[i]);
- }
-
- if (normalBuffer)
- {
- SetVertexNormal(normalBuffer, i, normals[i]);
- }
- }
-
- ::memcpy(indexBuffer, indices, sizeof(indices));
- }
- void BasicRHIComponent::SetVertexIndexIncreasing(uint16_t* indexBuffer, size_t bufferSize)
- {
- for (int i = 0; i < bufferSize; ++i)
- {
- indexBuffer[i] = static_cast<uint16_t>(i);
- }
- }
- AZ::Matrix4x4 BasicRHIComponent::CreateViewMatrix(AZ::Vector3 eye, AZ::Vector3 up, AZ::Vector3 lookAt)
- {
- AZ::Vector3 zaxis, xaxis, yaxis;
- zaxis = eye - lookAt;
- if (!zaxis.IsZero())
- {
- zaxis.Normalize();
- }
- xaxis = up.Cross(zaxis);
- if (!xaxis.IsZero())
- {
- xaxis.Normalize();
- }
- yaxis = zaxis.Cross(xaxis);
- AZ::Matrix4x4 result = AZ::Matrix4x4::CreateFromRows
- (
- AZ::Vector4(xaxis.GetX(), xaxis.GetY(), xaxis.GetZ(), -xaxis.Dot(eye)),
- AZ::Vector4(yaxis.GetX(), yaxis.GetY(), yaxis.GetZ(), -yaxis.Dot(eye)),
- AZ::Vector4(zaxis.GetX(), zaxis.GetY(), zaxis.GetZ(), -zaxis.Dot(eye)),
- AZ::Vector4( 0.f, 0.f, 0.f, 1.f)
- );
- return result;
- }
- void BasicRHIComponent::FindShaderInputIndex(
- AZ::RHI::ShaderInputConstantIndex* shaderInputConstIndex,
- AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> shaderResourceGroup,
- const AZ::Name& shaderInputName,
- [[maybe_unused]] const char* componentName)
- {
- *shaderInputConstIndex = shaderResourceGroup->FindShaderInputConstantIndex(shaderInputName);
- AZ_Error(componentName, shaderInputConstIndex->IsValid(), "Failed to find shader input constant %s.", shaderInputName.GetCStr());
- }
- void BasicRHIComponent::FindShaderInputIndex(
- AZ::RHI::ShaderInputImageIndex* shaderInputImageIndex,
- AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> shaderResourceGroup,
- const AZ::Name& shaderInputName,
- [[maybe_unused]] const char* componentName)
- {
- *shaderInputImageIndex = shaderResourceGroup->FindShaderInputImageIndex(shaderInputName);
- AZ_Error(componentName, shaderInputImageIndex->IsValid(), "Failed to find shader input image %s.", shaderInputName.GetCStr());
- }
- void BasicRHIComponent::FindShaderInputIndex(
- AZ::RHI::ShaderInputBufferIndex* shaderInputBufferIndex,
- AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> shaderResourceGroup,
- const AZ::Name& shaderInputName,
- [[maybe_unused]] const char* componentName)
- {
- *shaderInputBufferIndex = shaderResourceGroup->FindShaderInputBufferIndex(shaderInputName);
- AZ_Error(componentName, shaderInputBufferIndex->IsValid(), "Failed to find shader input buffer %s.", shaderInputName.GetCStr());
- }
- void BasicRHIComponent::FindShaderInputIndex(
- AZ::RHI::ShaderInputSamplerIndex* shaderInputSamplerIndex,
- AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> shaderResourceGroup,
- const AZ::Name& shaderInputName,
- [[maybe_unused]] const char* componentName)
- {
- *shaderInputSamplerIndex = shaderResourceGroup->FindShaderInputSamplerIndex(shaderInputName);
- AZ_Error(componentName, shaderInputSamplerIndex->IsValid(), "Failed to find sampler %s.", shaderInputName.GetCStr());
- }
- AZ::Data::Instance<AZ::RPI::Shader> BasicRHIComponent::LoadShader(const char* shaderFilePath, [[maybe_unused]] const char* sampleName, const AZ::Name* supervariantName)
- {
- using namespace AZ;
- Data::AssetId shaderAssetId;
- Data::AssetCatalogRequestBus::BroadcastResult(
- shaderAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
- shaderFilePath, azrtti_typeid<RPI::ShaderAsset>(), false);
- if (!shaderAssetId.IsValid())
- {
- AZ_Error(sampleName, false, "Failed to get shader asset id with path %s", shaderFilePath);
- return nullptr;
- }
- auto shaderAsset = Data::AssetManager::Instance().GetAsset<RPI::ShaderAsset>(
- shaderAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
- shaderAsset.BlockUntilLoadComplete();
- if (!shaderAsset.IsReady())
- {
- AZ_Error(sampleName, false, "Failed to get shader asset with path %s", shaderFilePath);
- return nullptr;
- }
- auto shader = RPI::Shader::FindOrCreate(shaderAsset, (supervariantName != nullptr) ? *supervariantName : AZ::Name{""});
- if (!shader)
- {
- AZ_Error(sampleName, false, "Failed to find or create a shader instance from shader asset '%s'", shaderFilePath);
- return nullptr;
- }
- return shader;
- }
- AZ::Data::Instance<AZ::RPI::Shader> BasicRHIComponent::LoadShader(const AZ::AssetCollectionAsyncLoader& assetLoadMgr, const char* shaderFilePath, [[maybe_unused]] const char* sampleName)
- {
- using namespace AZ;
- auto shaderAsset = assetLoadMgr.GetAsset<RPI::ShaderAsset>(shaderFilePath);
- AZ_Assert(shaderAsset.IsReady(), "Shader asset %s is supposed to be ready", shaderFilePath);
- auto shader = RPI::Shader::FindOrCreate(shaderAsset);
- if (!shader)
- {
- AZ_Error(sampleName, false, "Failed to find or create a shader instance from shader asset '%s'", shaderFilePath);
- return nullptr;
- }
- return shader;
- }
- AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> BasicRHIComponent::CreateShaderResourceGroup(AZ::Data::Instance<AZ::RPI::Shader> shader, const char* shaderResourceGroupId, [[maybe_unused]] const char* sampleName)
- {
- auto srg = AZ::RPI::ShaderResourceGroup::Create(shader->GetAsset(), shader->GetSupervariantIndex(), AZ::Name { shaderResourceGroupId });
- if (!srg)
- {
- AZ_Error(sampleName, false, "Failed to create shader resource group");
- return nullptr;
- }
- return srg;
- }
- AZ::Data::Instance<AZ::RPI::StreamingImage> BasicRHIComponent::LoadStreamingImage(const char* textureFilePath, [[maybe_unused]] const char* sampleName)
- {
- using namespace AZ;
- Data::AssetId streamingImageAssetId;
- Data::AssetCatalogRequestBus::BroadcastResult(
- streamingImageAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
- textureFilePath, azrtti_typeid<RPI::StreamingImageAsset>(), false);
- if (!streamingImageAssetId.IsValid())
- {
- AZ_Error(sampleName, false, "Failed to get streaming image asset id with path %s", textureFilePath);
- return nullptr;
- }
- auto streamingImageAsset = Data::AssetManager::Instance().GetAsset<RPI::StreamingImageAsset>(
- streamingImageAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
- streamingImageAsset.BlockUntilLoadComplete();
- if (!streamingImageAsset.IsReady())
- {
- AZ_Error(sampleName, false, "Failed to get streaming image asset '%s'", textureFilePath);
- return nullptr;
- }
- auto image = RPI::StreamingImage::FindOrCreate(streamingImageAsset);
- if (!image)
- {
- AZ_Error(sampleName, false, "Failed to find or create an image instance from image asset '%s'", textureFilePath);
- return nullptr;
- }
- return image;
- }
- void BasicRHIComponent::CreateImage3dData(AZStd::vector<uint8_t>& data, AZ::RHI::ImageSubresourceLayout& layout, AZ::RHI::Format& format, AZStd::vector<const char*>&& imageAssetPaths)
- {
- using namespace AZ;
- const auto getStreamingImageAsset = [](const char* path) -> AZ::Data::Asset<AZ::RPI::StreamingImageAsset>
- {
- Data::AssetId streamingImageAssetId;
- Data::AssetCatalogRequestBus::BroadcastResult(
- streamingImageAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
- path, azrtti_typeid<RPI::StreamingImageAsset>(), false);
- AZ::Data::Asset<AZ::RPI::StreamingImageAsset> streamingImageAsset = Data::AssetManager::Instance().GetAsset<RPI::StreamingImageAsset>(
- streamingImageAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
- streamingImageAsset.BlockUntilLoadComplete();
- return streamingImageAsset;
- };
- AZStd::vector<RHI::ImageDescriptor> imageDescriptors;
- imageDescriptors.reserve(imageAssetPaths.size());
- AZStd::vector<RHI::ImageSubresourceLayout> imageSubresourceLayouts;
- imageSubresourceLayouts.reserve(imageAssetPaths.size());
- AZStd::vector<Data::Asset<RPI::ImageMipChainAsset>> imageMipAssets;
- imageMipAssets.reserve(imageAssetPaths.size());
- // Load the first mip of the images
- for (const char* imageAssetPath : imageAssetPaths)
- {
- Data::Asset<AZ::RPI::StreamingImageAsset> streamingImageAsset = getStreamingImageAsset(imageAssetPath);
- RHI::ImageDescriptor imageDescriptor = streamingImageAsset->GetImageDescriptor();
- imageDescriptors.emplace_back(imageDescriptor);
- // Load the mip
- Data::Asset<RPI::ImageMipChainAsset> mipAsset = streamingImageAsset->GetMipChainAsset(0);
- mipAsset = Data::AssetManager::Instance().GetAsset<RPI::ImageMipChainAsset>(
- mipAsset.GetId(), AZ::Data::AssetLoadBehavior::PreLoad);
- mipAsset.BlockUntilLoadComplete();
- imageMipAssets.emplace_back(mipAsset);
- const RHI::ImageSubresourceLayout subImageLayout = mipAsset->GetSubImageLayout(0);
- imageSubresourceLayouts.emplace_back(subImageLayout);
- }
- // Validate the compatibility of the image sub resources
- for (uint32_t i = 1; i < imageSubresourceLayouts.size(); i++)
- {
- [[maybe_unused]] const bool compatibleFormat = imageDescriptors[0].m_format == imageDescriptors[i].m_format;
- [[maybe_unused]] const bool compatibleLayout = imageSubresourceLayouts[0].m_size == imageSubresourceLayouts[i].m_size &&
- imageSubresourceLayouts[0].m_rowCount == imageSubresourceLayouts[i].m_rowCount &&
- imageSubresourceLayouts[0].m_bytesPerRow == imageSubresourceLayouts[i].m_bytesPerRow &&
- imageSubresourceLayouts[0].m_bytesPerImage == imageSubresourceLayouts[i].m_bytesPerImage;
- AZ_Assert(compatibleLayout && compatibleFormat, "The image sub resources of the first MIP aren't compatible.");
- }
- // Allocate the data of the first mip of the images sequentially
- const uint32_t bytesPerImage = imageSubresourceLayouts[0].m_bytesPerImage;
- data.resize(imageSubresourceLayouts[0].m_bytesPerImage * imageSubresourceLayouts.size());
- for (uint32_t i = 0; i < imageMipAssets.size(); i++)
- {
- const uint64_t dataOffset = i * bytesPerImage;
- memcpy(static_cast<uint8_t*>(data.data()) + dataOffset, imageMipAssets[i]->GetSubImageData(0).data(), imageSubresourceLayouts[0].m_bytesPerImage);
- }
- format = imageDescriptors[0].m_format;
- layout = imageSubresourceLayouts[0];
- layout.m_size.m_depth = static_cast<uint32_t>(imageAssetPaths.size());
- }
- void BasicRHIComponent::SetOutputInfo(uint32_t width, uint32_t height, AZ::RHI::Format format, AZ::RHI::AttachmentId attachmentId)
- {
- m_outputWidth = width;
- m_outputHeight = height;
- m_outputFormat = format;
- m_outputAttachmentId = attachmentId;
- UpdateViewportAndScissor();
- }
- void BasicRHIComponent::SetOutputInfoFromWindowContext()
- {
- m_outputFormat = m_windowContext->GetSwapChain()->GetDescriptor().m_dimensions.m_imageFormat;
- m_outputWidth = aznumeric_cast<uint32_t>(m_windowContext->GetViewport().m_maxX - m_windowContext->GetViewport().m_minX);
- m_outputHeight = aznumeric_cast<uint32_t>(m_windowContext->GetViewport().m_maxY - m_windowContext->GetViewport().m_minY);
- m_outputAttachmentId = m_windowContext->GetSwapChain()->GetAttachmentId();
- UpdateViewportAndScissor();
- }
- void BasicRHIComponent::UpdateViewportAndScissor()
- {
- m_viewport = AZ::RHI::Viewport(0, aznumeric_cast<float>(m_outputWidth), 0, aznumeric_cast<float>(m_outputHeight));
- m_scissor = AZ::RHI::Scissor(0, 0, m_outputWidth, m_outputHeight);
- }
- bool BasicRHIComponent::IsSupportedRHISamplePipeline()
- {
- return m_supportRHISamplePipeline;
- }
- float BasicRHIComponent::GetViewportWidth()
- {
- return m_viewport.m_maxX - m_viewport.m_minX;
- }
- float BasicRHIComponent::GetViewportHeight()
- {
- return m_viewport.m_maxY - m_viewport.m_minY;
- }
- void BasicRHIComponent::SetViewIndex(const uint32_t viewIndex)
- {
- m_viewIndex = viewIndex;
- }
- }
|