You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
5.0 KiB
C++
147 lines
5.0 KiB
C++
/*
|
|
* 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 <Atom/RPI.Reflect/Image/ImageMipChainAssetCreator.h>
|
|
#include <Atom/RPI.Reflect/Image/StreamingImageAssetCreator.h>
|
|
|
|
#include <AzCore/Asset/AssetManager.h>
|
|
|
|
namespace AZ
|
|
{
|
|
namespace RPI
|
|
{
|
|
void StreamingImageAssetCreator::Begin(const Data::AssetId& assetId)
|
|
{
|
|
BeginCommon(assetId);
|
|
|
|
m_mipLevels = 0;
|
|
}
|
|
|
|
void StreamingImageAssetCreator::SetImageDescriptor(const RHI::ImageDescriptor& descriptor)
|
|
{
|
|
if (!ValidateIsReady())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (descriptor.m_mipLevels > RHI::Limits::Image::MipCountMax)
|
|
{
|
|
ReportError("Exceeded the maximum number of mip levels supported by the RHI.");
|
|
return;
|
|
}
|
|
|
|
m_asset->m_imageDescriptor = descriptor;
|
|
}
|
|
|
|
void StreamingImageAssetCreator::SetImageViewDescriptor(const RHI::ImageViewDescriptor& descriptor)
|
|
{
|
|
if (ValidateIsReady())
|
|
{
|
|
m_asset->m_imageViewDescriptor = descriptor;
|
|
}
|
|
}
|
|
|
|
void StreamingImageAssetCreator::AddMipChainAsset(ImageMipChainAsset& mipChainAsset)
|
|
{
|
|
if (!ValidateIsReady())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!mipChainAsset.GetId().IsValid())
|
|
{
|
|
ReportError("ImageMipChainAsset does not have a valid id. A valid id is required.");
|
|
return;
|
|
}
|
|
|
|
const uint16_t mipLevelOffset = m_mipLevels;
|
|
const uint16_t localMipCount = mipChainAsset.GetMipLevelCount();
|
|
const uint16_t localMipBegin = m_mipLevels;
|
|
const uint16_t localMipEnd = m_mipLevels + localMipCount;
|
|
const uint16_t mipChainIndex = static_cast<uint16_t>(m_asset->m_mipChains.size());
|
|
|
|
if (localMipEnd > RHI::Limits::Image::MipCountMax)
|
|
{
|
|
ReportError("Exceeded the maximum number of mip levels supported by the RHI.");
|
|
return;
|
|
}
|
|
|
|
// Map the image mip slice indices to mip chain asset. This is likely a many-to-one mapping.
|
|
for (uint16_t localMipIndex = localMipBegin; localMipIndex < localMipEnd; ++localMipIndex)
|
|
{
|
|
m_asset->m_mipLevelToChainIndex[localMipIndex] = mipChainIndex;
|
|
}
|
|
|
|
StreamingImageAsset::MipChain mipChain;
|
|
mipChain.m_mipOffset = mipLevelOffset;
|
|
mipChain.m_mipCount = localMipCount;
|
|
// Mipchain assets are not loaded by default
|
|
mipChain.m_asset = { &mipChainAsset, AZ::Data::AssetLoadBehavior::NoLoad };
|
|
|
|
m_asset->m_mipChains.push_back(mipChain);
|
|
|
|
m_mipLevels += localMipCount;
|
|
}
|
|
|
|
void StreamingImageAssetCreator::SetPoolAssetId(const Data::AssetId& poolAssetId)
|
|
{
|
|
if (ValidateIsReady())
|
|
{
|
|
m_asset->m_poolAssetId = poolAssetId;
|
|
}
|
|
}
|
|
|
|
void StreamingImageAssetCreator::SetFlags(StreamingImageFlags flag)
|
|
{
|
|
if (ValidateIsReady())
|
|
{
|
|
m_asset->m_flags = flag;
|
|
}
|
|
}
|
|
|
|
bool StreamingImageAssetCreator::End(Data::Asset<StreamingImageAsset>& result)
|
|
{
|
|
if (!ValidateIsReady())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const RHI::ImageDescriptor& imageDescriptor = m_asset->GetImageDescriptor();
|
|
const uint16_t expectedMipLevels = imageDescriptor.m_mipLevels;
|
|
|
|
if (m_mipLevels != expectedMipLevels)
|
|
{
|
|
ReportError("Expected %d mip levels, but %d were added through mip chains.", expectedMipLevels, m_mipLevels);
|
|
return false;
|
|
}
|
|
|
|
size_t totalImageBytes = 0;
|
|
for (const StreamingImageAsset::MipChain& mipChain : m_asset->m_mipChains)
|
|
{
|
|
totalImageBytes += mipChain.m_asset->GetImageDataSize();
|
|
}
|
|
m_asset->m_totalImageDataSize = aznumeric_cast<uint32_t>(totalImageBytes);
|
|
|
|
Data::Asset<ImageMipChainAsset> mipChainTail(m_asset->m_mipChains.back().m_asset);
|
|
m_asset->m_tailMipChain.CopyFrom(*mipChainTail.Get());
|
|
m_asset->m_mipChains.back().m_asset = Data::Asset<ImageMipChainAsset>();
|
|
|
|
// If the streaming image is not streamable, it should have one and only one mip chain
|
|
if (RHI::CheckBitsAny(m_asset->GetFlags(), StreamingImageFlags::NotStreamable) && m_asset->GetMipChainCount() != 1)
|
|
{
|
|
ReportError("Expected only one mip chain asset for non-streamable streaming image");
|
|
return false;
|
|
}
|
|
|
|
|
|
m_asset->SetReady();
|
|
return EndCommon(result);
|
|
}
|
|
}
|
|
}
|