Skip to content

Commit 0dc20c2

Browse files
committed
Add fetching gpu data from input denoiser images
1 parent c5d6951 commit 0dc20c2

File tree

1 file changed

+143
-0
lines changed
  • examples_tests/39.DenoiserTonemapper

1 file changed

+143
-0
lines changed

examples_tests/39.DenoiserTonemapper/main.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515

1616
#include "CommonPushConstants.h"
1717

18+
/*
19+
Uncomment bellow define to perform
20+
DDS input/output Denoiser Tonemapper's
21+
data saving.
22+
*/
23+
24+
#define DDSInputOutputDenoiserSave
25+
1826
using namespace nbl;
1927
using namespace asset;
2028
using namespace video;
@@ -835,6 +843,38 @@ void main()
835843
OptixImage2D denoiserInputs[EII_COUNT];
836844
OptixImage2D denoiserOutput;
837845

846+
const video::VkMemoryRequirements& vulkanFetchedReqs = temporaryPixelBuffer.getObject()->getMemoryReqs().vulkanReqs;
847+
auto downloadStagingArea = driver->getDefaultDownStreamingBuffer();
848+
uint32_t address = std::remove_pointer<decltype(downloadStagingArea)>::type::invalid_address; // remember without initializing the address to be allocated to invalid_address you won't get an allocation!
849+
850+
constexpr uint64_t timeoutInNanoSeconds = 300000000000u;
851+
const auto waitPoint = std::chrono::high_resolution_clock::now() + std::chrono::nanoseconds(timeoutInNanoSeconds);
852+
853+
// download buffer
854+
{
855+
const uint32_t alignment = 4096u; // common page size
856+
const uint32_t size = vulkanFetchedReqs.size;
857+
auto unallocatedSize = downloadStagingArea->multi_alloc(waitPoint, 1u, &address, &size, &alignment);
858+
if (unallocatedSize)
859+
{
860+
os::Printer::log(makeImageIDString(i) + "Could not download the buffer from the GPU!", ELL_ERROR);
861+
continue;
862+
}
863+
864+
driver->copyBuffer(temporaryPixelBuffer.getObject(), downloadStagingArea->getBuffer(), 0u, address, vulkanFetchedReqs.size);
865+
}
866+
auto downloadFence = driver->placeFence(true);
867+
868+
auto* data = reinterpret_cast<uint8_t*>(downloadStagingArea->getBufferPointer()) + address;
869+
auto denoiserInputsTexelBuffer = core::make_smart_refctd_ptr<asset::CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t>>>(vulkanFetchedReqs.size, data, core::adopt_memory);
870+
871+
while (downloadFence->waitCPU(1000ull, downloadFence->canDeferredFlush()) == video::EDFR_TIMEOUT_EXPIRED) {}
872+
873+
//downloadStagingArea->multi_free()
874+
//inline void multi_free(uint32_t count, const size_type* addr, const size_type* bytes) noexcept
875+
// @devsh count?
876+
// it fails at second image while downloading buffer, guess it's due to lack of multi-free
877+
838878
for (size_t k = 0; k < denoiserInputCount; k++)
839879
{
840880
denoiserInputs[k].data = temporaryPixelBuffer.asBuffer.pointer + shaderConstants.outImageOffset[k] * sizeof(uint16_t);
@@ -843,6 +883,108 @@ void main()
843883
denoiserInputs[k].rowStrideInBytes = param.width * forcedOptiXFormatPixelStride;
844884
denoiserInputs[k].format = forcedOptiXFormat;
845885
denoiserInputs[k].pixelStrideInBytes = forcedOptiXFormatPixelStride;
886+
887+
#ifdef DDSInputOutputDenoiserSave
888+
889+
auto createImage = [&](bool isInputFilterImage = true) -> core::smart_refctd_ptr<ICPUImage>
890+
{
891+
asset::ICPUImage::SCreationParams imgInfo;
892+
imgInfo.format = isInputFilterImage ? EF_R16G16B16_SFLOAT : EF_R16G16B16A16_SFLOAT;
893+
imgInfo.type = asset::ICPUImage::ET_2D;
894+
imgInfo.extent.width = param.width;
895+
imgInfo.extent.height = param.height;
896+
imgInfo.extent.depth = 1u;
897+
imgInfo.mipLevels = 1u;
898+
imgInfo.arrayLayers = 1u;
899+
imgInfo.samples = asset::ICPUImage::ESCF_1_BIT;
900+
imgInfo.flags = static_cast<asset::IImage::E_CREATE_FLAGS>(0u);
901+
902+
auto image = asset::ICPUImage::create(std::move(imgInfo));
903+
const auto texelFormatBytesize = getTexelOrBlockBytesize(image->getCreationParameters().format);
904+
905+
auto createTexelBuffer = [&]() -> core::smart_refctd_ptr<asset::ICPUBuffer>
906+
{
907+
if (isInputFilterImage)
908+
return core::make_smart_refctd_ptr<asset::CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t>>>(image->getImageDataSizeInBytes(), reinterpret_cast<uint16_t*>(denoiserInputsTexelBuffer->getPointer()) + shaderConstants.outImageOffset[k], core::adopt_memory);
909+
else
910+
{
911+
auto texelBuffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(image->getImageDataSizeInBytes());
912+
memset(texelBuffer->getPointer(), 0, texelBuffer->getSize());
913+
return texelBuffer;
914+
}
915+
};
916+
917+
auto texelBuffer = createTexelBuffer();
918+
auto regions = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<asset::ICPUImage::SBufferCopy>>(1u);
919+
asset::ICPUImage::SBufferCopy& region = regions->front();
920+
921+
region.imageSubresource.mipLevel = 0u;
922+
region.imageSubresource.baseArrayLayer = 0u;
923+
region.imageSubresource.layerCount = 1u;
924+
region.bufferOffset = 0u;
925+
region.bufferRowLength = image->getCreationParameters().extent.width;
926+
region.bufferImageHeight = 0u;
927+
region.imageOffset = { 0u, 0u, 0u };
928+
region.imageExtent = image->getCreationParameters().extent;
929+
930+
image->setBufferAndRegions(std::move(texelBuffer), regions);
931+
932+
return image;
933+
};
934+
935+
core::smart_refctd_ptr<asset::ICPUImage> inputTileImage = createImage();
936+
core::smart_refctd_ptr<asset::ICPUImage> outputTileImage = createImage(false);
937+
938+
using ConvertFilter = asset::CConvertFormatImageFilter<EF_R16G16B16_SFLOAT, EF_R16G16B16A16_SFLOAT>;
939+
ConvertFilter convertFilter;
940+
ConvertFilter::state_type state;
941+
942+
state.extent = { param.width, param.height, 1 };
943+
state.inBaseLayer = 0;
944+
state.inImage = inputTileImage.get();
945+
state.inMipLevel = 0;
946+
state.inOffset = { 0, 0, 0 };
947+
state.layerCount = 1;
948+
state.outBaseLayer = 0;
949+
state.outImage = outputTileImage.get();
950+
state.outMipLevel = 0;
951+
state.outOffset = { 0, 0, 0 };
952+
953+
if (!convertFilter.execute(&state))
954+
os::Printer::log("WARNING (" + std::to_string(__LINE__) + " line): Something went wrong while converting the image!", ELL_WARNING);
955+
956+
ICPUImageView::SCreationParams imageViewParams;
957+
imageViewParams.flags = static_cast<ICPUImageView::E_CREATE_FLAGS>(0u);
958+
imageViewParams.format = outputTileImage->getCreationParameters().format;
959+
imageViewParams.image = std::move(outputTileImage);
960+
imageViewParams.viewType = ICPUImageView::ET_2D;
961+
imageViewParams.subresourceRange = { static_cast<IImage::E_ASPECT_FLAGS>(0u),0u,1u,0u,1u };
962+
auto imageView = ICPUImageView::create(std::move(imageViewParams));
963+
{
964+
IAssetWriter::SAssetWriteParams wp(imageView.get());
965+
auto getInputTerminateName = [&]() -> std::string
966+
{
967+
switch (k)
968+
{
969+
case EII_COLOR:
970+
return "color";
971+
case EII_ALBEDO:
972+
return "albedo";
973+
case EII_NORMAL:
974+
return "normal";
975+
default:
976+
"";
977+
}
978+
};
979+
980+
std::string removedExtensionFile = outputFileBundle[i].value().substr(0, outputFileBundle[i].value().size() - 4);
981+
std::string fileName = removedExtensionFile + "_optix_input_" + getInputTerminateName() + ".dds";
982+
983+
if(!am->writeAsset(fileName , wp))
984+
os::Printer::log("ERROR (" + std::to_string(__LINE__) + " line): Could not save .dds file!", ELL_ERROR);
985+
}
986+
987+
#endif // DDSInputOutputDenoiserSave
846988

847989
}
848990

@@ -938,6 +1080,7 @@ void main()
9381080
{
9391081
const uint32_t alignment = 4096u; // common page size
9401082
auto unallocatedSize = downloadStagingArea->multi_alloc(waitPoint, 1u, &address, &colorBufferBytesize, &alignment);
1083+
9411084
if (unallocatedSize)
9421085
{
9431086
os::Printer::log(makeImageIDString(i)+"Could not download the buffer from the GPU!",ELL_ERROR);

0 commit comments

Comments
 (0)