Png fix for vulkan rhi (#962)

* Add supported formats for pngs in frame capture system. Add conversion logic from bgra to rgba.
main
hershey5045 5 years ago committed by GitHub
parent b20f3bc72f
commit 75cb293b2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,6 +21,8 @@
#include <Atom/Utils/PpmFile.h>
#include <AtomCore/Serialization/Json/JsonUtils.h>
#include <AzCore/Jobs/JobFunction.h>
#include <AzCore/Jobs/JobCompletion.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/RTTI/BehaviorContext.h>
@ -55,6 +57,43 @@ namespace AZ
FrameCaptureOutputResult PngFrameCaptureOutput(
const AZStd::string& outputFilePath, const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
AZStd::shared_ptr<AZStd::vector<uint8_t>> buffer = readbackResult.m_dataBuffer;
// convert bgra to rgba by swapping channels
const int numChannels = AZ::RHI::GetFormatComponentCount(readbackResult.m_imageDescriptor.m_format);
if (readbackResult.m_imageDescriptor.m_format == RHI::Format::B8G8R8A8_UNORM)
{
buffer = AZStd::make_shared<AZStd::vector<uint8_t>>(readbackResult.m_dataBuffer->size());
AZStd::copy(readbackResult.m_dataBuffer->begin(), readbackResult.m_dataBuffer->end(), buffer->begin());
AZ::JobCompletion jobCompletion;
const int numThreads = 8;
const int numPixelsPerThread = buffer->size() / numChannels / numThreads;
for (int i = 0; i < numThreads; ++i)
{
int startPixel = i * numPixelsPerThread;
AZ::Job* job = AZ::CreateJobFunction(
[&, startPixel, numPixelsPerThread]()
{
for (int pixelOffset = 0; pixelOffset < numPixelsPerThread; ++pixelOffset)
{
if (startPixel * numChannels + numChannels < buffer->size())
{
AZStd::swap(
buffer->data()[(startPixel + pixelOffset) * numChannels],
buffer->data()[(startPixel + pixelOffset) * numChannels + 2]
);
}
}
}, true, nullptr);
job->SetDependent(&jobCompletion);
job->Start();
}
jobCompletion.StartAndWaitForCompletion();
}
using namespace OIIO;
AZStd::unique_ptr<ImageOutput> out = ImageOutput::create(outputFilePath.c_str());
if (out)
@ -62,13 +101,13 @@ namespace AZ
ImageSpec spec(
readbackResult.m_imageDescriptor.m_size.m_width,
readbackResult.m_imageDescriptor.m_size.m_height,
AZ::RHI::GetFormatComponentCount(readbackResult.m_imageDescriptor.m_format)
numChannels
);
spec.attribute("png:compressionLevel", r_pngCompressionLevel);
if (out->open(outputFilePath.c_str(), spec))
{
out->write_image(TypeDesc::UINT8, readbackResult.m_dataBuffer->data());
out->write_image(TypeDesc::UINT8, buffer->data());
out->close();
return FrameCaptureOutputResult{FrameCaptureResult::Success, AZStd::nullopt};
}
@ -460,13 +499,23 @@ namespace AZ
#if defined(OPEN_IMAGE_IO_ENABLED)
else if (extension == "png")
{
AZStd::string folderPath;
AzFramework::StringFunc::Path::GetFolderPath(m_outputFilePath.c_str(), folderPath);
AZ::IO::SystemFile::CreateDir(folderPath.c_str());
if (readbackResult.m_imageDescriptor.m_format == RHI::Format::R8G8B8A8_UNORM ||
readbackResult.m_imageDescriptor.m_format == RHI::Format::B8G8R8A8_UNORM)
{
AZStd::string folderPath;
AzFramework::StringFunc::Path::GetFolderPath(m_outputFilePath.c_str(), folderPath);
AZ::IO::SystemFile::CreateDir(folderPath.c_str());
const auto frameCaptureResult = PngFrameCaptureOutput(m_outputFilePath, readbackResult);
m_result = frameCaptureResult.m_result;
m_latestCaptureInfo = frameCaptureResult.m_errorMessage.value_or("");
const auto frameCaptureResult = PngFrameCaptureOutput(m_outputFilePath, readbackResult);
m_result = frameCaptureResult.m_result;
m_latestCaptureInfo = frameCaptureResult.m_errorMessage.value_or("");
}
else
{
m_latestCaptureInfo = AZStd::string::format(
"Can't save image with format %s to a png file", RHI::ToString(readbackResult.m_imageDescriptor.m_format));
m_result = FrameCaptureResult::UnsupportedFormat;
}
}
#endif
else

Loading…
Cancel
Save