diff --git a/.gitmodules b/.gitmodules index 43c4683e3..fb0669955 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "deps/RIF"] - path = deps/RIF - url = https://github.com/GPUOpen-LibrariesAndSDKs/RadeonImageFilter [submodule "deps/RPR"] path = deps/RPR url = https://github.com/GPUOpen-LibrariesAndSDKs/RadeonProRenderSDK diff --git a/cmake/defaults/Packages.cmake b/cmake/defaults/Packages.cmake index 0297547d8..29022ddfd 100644 --- a/cmake/defaults/Packages.cmake +++ b/cmake/defaults/Packages.cmake @@ -77,7 +77,6 @@ if(NOT USD_SCHEMA_GENERATOR) endif() find_package(Rpr REQUIRED) -find_package(Rif REQUIRED) # Core USD Package Requirements # ---------------------------------------------- diff --git a/cmake/modules/FindRif.cmake b/cmake/modules/FindRif.cmake deleted file mode 100644 index 9079ceeb5..000000000 --- a/cmake/modules/FindRif.cmake +++ /dev/null @@ -1,76 +0,0 @@ -if(NOT RIF_LOCATION) - set(RIF_LOCATION ${PROJECT_SOURCE_DIR}/deps/RIF) -endif() - -macro(SET_RIF_VARIABLES dirName) - if(NOT RIF_LOCATION_LIB) - set(RIF_LOCATION_LIB ${RIF_LOCATION}/${dirName}/Dynamic) - endif() - - if(NOT RIF_LOCATION_INCLUDE) - set(RIF_LOCATION_INCLUDE ${RIF_LOCATION}/include) - endif() -endmacro(SET_RIF_VARIABLES) - -if(APPLE) - if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64") - SET_RIF_VARIABLES(OSX) - else() - SET_RIF_VARIABLES(MacOS_ARM) - endif() -elseif(WIN32) - SET_RIF_VARIABLES(Windows) -elseif(RPR_SDK_PLATFORM STREQUAL "ubuntu18.04") - SET_RIF_VARIABLES(Ubuntu18) -elseif(RPR_SDK_PLATFORM STREQUAL "ubuntu20.04") - SET_RIF_VARIABLES(Ubuntu20) -else() - SET_RIF_VARIABLES(CentOS7) -endif() - -find_library(RIF_LIBRARY - NAMES RadeonImageFilters - HINTS - "${RIF_LOCATION_LIB}" - DOC - "Radeon Image Filter library path" - NO_DEFAULT_PATH - NO_SYSTEM_ENVIRONMENT_PATH -) - -if(WIN32) - set(RIF_BINARIES - ${RIF_LOCATION_LIB}/dxcompiler.dll - ${RIF_LOCATION_LIB}/dxil.dll - ${RIF_LOCATION_LIB}/MIOpen.dll - ${RIF_LOCATION_LIB}/RadeonImageFilters.dll - ${RIF_LOCATION_LIB}/RadeonML.dll - ${RIF_LOCATION_LIB}/RadeonML_MIOpen.dll - ${RIF_LOCATION_LIB}/RadeonML_DirectML.dll) -else(WIN32) - if(APPLE) - set(RIF_DEPENDENCY_LIBRARIES - ${RIF_LOCATION_LIB}/libRadeonML.dylib - ${RIF_LOCATION_LIB}/libRadeonML_MPS.dylib) - else() - set(RIF_DEPENDENCY_LIBRARIES - ${RIF_LOCATION_LIB}/libMIOpen.so - ${RIF_LOCATION_LIB}/libRadeonML_MIOpen.so - ${RIF_LOCATION_LIB}/libRadeonML.so.0) - endif(APPLE) -endif(WIN32) - -if(NOT DEFINED RIF_MODELS_DIR) - set(RIF_MODELS_DIR "${RIF_LOCATION}/models") -endif() - -parseVersion("${RIF_LOCATION_INCLUDE}/RadeonImageFilters_version.h" RIF) - -include(FindPackageHandleStandardArgs) - -find_package_handle_standard_args(Rif - REQUIRED_VARS - RIF_LOCATION_INCLUDE - RIF_VERSION_STRING - RIF_LIBRARY -) diff --git a/deps/RIF b/deps/RIF deleted file mode 160000 index a8868f5a7..000000000 --- a/deps/RIF +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a8868f5a7ae37086dc21a9d4fa0688fdaedaa93b diff --git a/pxr/imaging/plugin/hdRpr/CMakeLists.txt b/pxr/imaging/plugin/hdRpr/CMakeLists.txt index 9b5ddfeba..f4dbb07c8 100644 --- a/pxr/imaging/plugin/hdRpr/CMakeLists.txt +++ b/pxr/imaging/plugin/hdRpr/CMakeLists.txt @@ -79,15 +79,6 @@ add_custom_command( OUTPUT ${GENERATED_FILES} COMMENT "Generating files") -file(GLOB_RECURSE RIF_MODEL_FILES "${RIF_MODELS_DIR}/*") -foreach(file ${RIF_MODEL_FILES}) - file(RELATIVE_PATH rel_file ${RIF_MODELS_DIR} ${file}) - list(APPEND RIF_MODEL_RESOURCE_FILES "${file}${_sep}rif_models/${rel_file}") -endforeach() -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/rif_models.version ${RIF_VERSION_STRING}) -list(APPEND RIF_MODEL_RESOURCE_FILES - "${CMAKE_CURRENT_BINARY_DIR}/rif_models.version${_sep}rif_models/rif_models.version") - pxr_plugin(hdRpr DISABLE_PRECOMPILED_HEADERS @@ -110,13 +101,11 @@ pxr_plugin(hdRpr rprUsd json murmurhash - ${RIF_LIBRARY} ${OPENEXR_LIBRARIES} ${OptLibs} INCLUDE_DIRS - ${RIF_LOCATION_INCLUDE} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty ${OPENEXR_INCLUDE_DIRS} @@ -146,6 +135,7 @@ pxr_plugin(hdRpr debugCodes primvarUtil points + cpuFilters ${OptClass} @@ -156,7 +146,6 @@ pxr_plugin(hdRpr RESOURCE_FILES plugInfo.json ${RESTART_REQUIRED_RESOURCE_FILE} - ${RIF_MODEL_RESOURCE_FILES} ${SCRIPT_RESOURCE_FILES} CPPFILES @@ -188,7 +177,6 @@ else() ${CMAKE_CURRENT_SOURCE_DIR}/notify/message.cpp) endif() -add_subdirectory(rifcpp) add_subdirectory(houdini) if(NOT HoudiniUSD_FOUND) add_subdirectory(usdviewMenu) @@ -209,12 +197,12 @@ if(WIN32) list(APPEND RPR_BINARIES ${RPR_BIN_LOCATION}/RprLoadStore64.dll) endif() install( - FILES ${RPR_BINARIES} ${RPR_PLUGINS} ${RIF_BINARIES} ${OptBin} + FILES ${RPR_BINARIES} ${RPR_PLUGINS} ${OptBin} DESTINATION lib) else(WIN32) # install() does not follow symlinks, so we do it manually set(RESOLVED_LIBRARIES "") - foreach (file ${RPR_LIBRARY} ${RPR_LOADSTORE_LIBRARY} ${RPR_PLUGINS} ${RIF_LIBRARY} ${RIF_DEPENDENCY_LIBRARIES}) + foreach (file ${RPR_LIBRARY} ${RPR_LOADSTORE_LIBRARY} ${RPR_PLUGINS}) while(IS_SYMLINK ${file}) file(READ_SYMLINK ${file} symfile) if(NOT IS_ABSOLUTE "${symfile}") diff --git a/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp b/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp index 0d6750c64..0258c8c9f 100644 --- a/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp +++ b/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp @@ -158,7 +158,6 @@ HdRprAovRegistry::HdRprAovRegistry() { addAovNameLookup(HdRprAovTokens->materialIdMask, m_computedAovDescriptors[kMaterialIdMask]); addAovNameLookup(HdRprAovTokens->objectIdMask, m_computedAovDescriptors[kObjectIdMask]); addAovNameLookup(HdRprAovTokens->objectGroupIdMask, m_computedAovDescriptors[kObjectGroupIdMask]); - addAovNameLookup(HdRprAovTokens->colorWithTransparency, m_computedAovDescriptors[kScTransparentBackground]); } HdRprAovDescriptor const& HdRprAovRegistry::GetAovDesc(TfToken const& name) { diff --git a/pxr/imaging/plugin/hdRpr/aovDescriptor.h b/pxr/imaging/plugin/hdRpr/aovDescriptor.h index 306e902b5..dc5244a67 100644 --- a/pxr/imaging/plugin/hdRpr/aovDescriptor.h +++ b/pxr/imaging/plugin/hdRpr/aovDescriptor.h @@ -75,7 +75,6 @@ PXR_NAMESPACE_OPEN_SCOPE (materialIdMask) \ (objectIdMask) \ (objectGroupIdMask) \ - (colorWithTransparency) \ TF_DECLARE_PUBLIC_TOKENS(HdRprAovTokens, HDRPR_AOV_TOKENS); diff --git a/pxr/imaging/plugin/hdRpr/cpuFilters.cpp b/pxr/imaging/plugin/hdRpr/cpuFilters.cpp new file mode 100644 index 000000000..0bc99de73 --- /dev/null +++ b/pxr/imaging/plugin/hdRpr/cpuFilters.cpp @@ -0,0 +1,214 @@ +/************************************************************************ +Copyright 2023 Advanced Micro Devices, Inc +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +************************************************************************/ + +#include "cpuFilters.h" +#include "pxr/base/work/loops.h" + +PXR_NAMESPACE_OPEN_SCOPE + +void CpuRemapFilter(float* src, float* dest, size_t length, float srcLo, float srcHi, float dstLo, float dstHi) { + WorkParallelForN(length, + [&](size_t begin, size_t end) { + for (size_t i = begin; i < end; ++i) { + dest[i] = ((src[i] - srcLo) / (srcHi - srcLo)) * (dstHi - dstLo) + dstLo; + }}); +} + +void CpuVec4toVec3Filter(GfVec4f* src, GfVec3f* dest, size_t numPixels) { + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (size_t i = begin; i < end; ++i) { + dest[i][0] = src[i][0]; + dest[i][1] = src[i][1]; + dest[i][2] = src[i][2]; + } + }); +} + +void CpuVec4toFloatFilter(GfVec4f* src, float* dest, size_t numPixels) { + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (size_t i = begin; i < end; ++i) { + dest[i] = src[i][0]; + } + }); +} + +void CpuVec4toInt32Filter(GfVec4f* src, int32_t* dest, size_t numPixels) { + char* destAsChar = (char*)dest; + float* srcAsFloat = (float*)src; + WorkParallelForN(numPixels * sizeof(int32_t), // output as char, input as GfVec4f + [&](size_t begin, size_t end) { + for (size_t i = begin; i < end; ++i) { + if (i % 4 == 3) + { + destAsChar[i] = 0; + } + else + { + destAsChar[i] = (char)(srcAsFloat[i] * 255 + 0.5f); + } + } + }); + + int32_t* destAsInt = (int32_t*)dest; + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (size_t i = begin; i < end; ++i) { + destAsInt[i] -= 1; + } + }); +} + +void CpuFloatToInt32Filter(float* src, int32_t* dest, size_t length) { + // RPR store integer ID values to RGB images using such formula: + // c[i].x = i; + // c[i].y = i/256; + // c[i].z = i/(256*256); + // i.e. saving little endian int24 to uchar3 + // That's why we interpret the value as int and filling the alpha channel with zeros + int32_t* srcAsInt = (int32_t*)src; + WorkParallelForN(length, + [&](size_t begin, size_t end) { + for (size_t i = begin; i < end; ++i) { + dest[i] = (srcAsInt[i] & 0xFFFFFF) - 1; + } + }); +} + +void CpuNdcFilter(GfVec4f* src, GfVec4f* dest, size_t numPixels, const GfMatrix4f& viewProjectionMatrix) { + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + float norm = std::max(src[i][3], 1.0f); + GfVec4f pos(src[i][0] / norm, src[i][1] / norm, src[i][2] / norm, 1.0f); + GfVec4f posResult = viewProjectionMatrix * pos; + float depth = posResult[2] / posResult[3]; + dest[i][0] = depth; + dest[i][1] = depth; + dest[i][2] = depth; + dest[i][3] = 1.0f; + } + }); +} + +void CpuOpacityFilter(GfVec4f* opacity, GfVec4f* srcdest, size_t numPixels) { + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + float op = opacity[i][0]; + srcdest[i][0] *= op; + srcdest[i][1] *= op; + srcdest[i][2] *= op; + srcdest[i][3] = op; + } + }); +} + +void CpuOpacityMaskFilter(GfVec4f* opacity, GfVec4f* srcdest, size_t numPixels) { + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + if (opacity[i][0] == 0.0f) { + srcdest[i][0] = 1.0f; + srcdest[i][1] = 1.0f; + srcdest[i][1] = 1.0f; + srcdest[i][1] = 1.0f; + } + } + }); +} + +void CpuFillMaskFilter(GfVec4f* srcdest, size_t numPixels) { + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + unsigned int idDecoded = (unsigned int)(srcdest[i][0] * 256) + (unsigned int)(srcdest[i][1] * 256 * 256) + (unsigned int)(srcdest[i][2] * 256 * 256 * 256); + if (idDecoded) { + unsigned int v0 = 0x123; + unsigned int v1 = idDecoded; + unsigned int s0 = 0; + const unsigned int N = 4; + for (unsigned int n = 0; n < N; n++) { + s0 += 0x9e3779b9; + v0 += ((v1 << 4) + 0xa341316c) ^ (v1 + s0) ^ ((v1 >> 5) + 0xc8013ea4); + v1 += ((v0 << 4) + 0xad90777d) ^ (v0 + s0) ^ ((v0 >> 5) + 0x7e95761e); + } + srcdest[i][0] = (v0 & 0xFFFF) / (float)(0xFFFF); + srcdest[i][1] = (v0 >> 16) / (float)(0xFFFF); + srcdest[i][2] = (v1 & 0xFFFF) / (float)(0xFFFF); + srcdest[i][3] = 1.0f; + } + else { + srcdest[i][0] = srcdest[i][1] = srcdest[i][2] = srcdest[i][3] = 0; + } + } + }); +} + +void CpuResampleNearest(GfVec4f* src, size_t srcWidth, size_t srcHeight, GfVec4f* dest, size_t destWidth, size_t destHeight) { + if (destWidth <= 1 || destHeight <= 1) { + return; + } + + float xratio = 1.0f * (srcWidth - 1.0f) / (destWidth - 1.0f); + float yratio = 1.0f * (srcHeight - 1.0f) / (destHeight - 1.0f); + + WorkParallelForN(destHeight, + [&](size_t begin, size_t end) { + for (int y = begin; y < end; ++y) { + for (int x = 0; x < destWidth; ++x) { + int cx = xratio * x; + int cy = yratio * y; + dest[(y * destWidth + x)][0] = src[(cy * srcWidth + cx)][0]; + dest[(y * destWidth + x)][1] = src[(cy * srcWidth + cx)][1]; + dest[(y * destWidth + x)][2] = src[(cy * srcWidth + cx)][2]; + dest[(y * destWidth + x)][3] = src[(cy * srcWidth + cx)][3]; + } + }}); +} + +void CpuGammaCorrection(GfVec4f* srcdest, size_t numPixels, float gamma) { + if (gamma == 0) { + return; + } + float _1_g = 1 / gamma; + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + srcdest[i][0] = powf(srcdest[i][0], _1_g); + srcdest[i][1] = powf(srcdest[i][1], _1_g); + srcdest[i][2] = powf(srcdest[i][2], _1_g); + // skiping alpha + } + }); +} + +void CpuTonemap(GfVec4f* srcdest, size_t numPixels, float gamma, float exposureTime, float sensitivity, float fstop) { + if (gamma == 0 || fstop == 0) { + return; + } + float h = (0.65f * 21.61f * sensitivity * exposureTime) / (fstop * fstop); + float _1_g = 1 / gamma; + WorkParallelForN(numPixels, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + srcdest[i][0] = powf(srcdest[i][0] * h, _1_g); + srcdest[i][1] = powf(srcdest[i][1] * h, _1_g); + srcdest[i][2] = powf(srcdest[i][2] * h, _1_g); + // skiping alpha + } + }); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/cpuFilters.h b/pxr/imaging/plugin/hdRpr/cpuFilters.h new file mode 100644 index 000000000..950034760 --- /dev/null +++ b/pxr/imaging/plugin/hdRpr/cpuFilters.h @@ -0,0 +1,36 @@ +/************************************************************************ +Copyright 2023 Advanced Micro Devices, Inc +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +************************************************************************/ + +#ifndef HDRPR_CPU_FILTERS_H +#define HDRPR_CPU_FILTERS_H + +#include "pxr/base/gf/matrix4f.h" + +PXR_NAMESPACE_OPEN_SCOPE + +void CpuRemapFilter(float* src, float* dest, size_t length, float srcLo, float srcHi, float dstLo, float dstHi); +void CpuVec4toVec3Filter(GfVec4f* src, GfVec3f* dest, size_t numPixels); +void CpuVec4toFloatFilter(GfVec4f* src, float* dest, size_t numPixels); +void CpuVec4toInt32Filter(GfVec4f* src, int32_t* dest, size_t numPixels); +void CpuFloatToInt32Filter(float* src, int32_t* dest, size_t length); +void CpuNdcFilter(GfVec4f* src, GfVec4f* dest, size_t numPixels, const GfMatrix4f& viewProjectionMatrix); +void CpuOpacityFilter(GfVec4f* opacity, GfVec4f* srcdest, size_t numPixels); +void CpuOpacityMaskFilter(GfVec4f* opacity, GfVec4f* srcdest, size_t numPixels); +void CpuFillMaskFilter(GfVec4f* srcdest, size_t numPixels); +void CpuResampleNearest(GfVec4f* src, size_t srcWidth, size_t srcHeight, GfVec4f* dest, size_t destWidth, size_t destHeight); +void CpuGammaCorrection(GfVec4f* srcdest, size_t numPixels, float gamma); +void CpuTonemap(GfVec4f* srcdest, size_t numPixels, float gamma, float exposureTime, float sensitivity, float fstop); + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // HDRPR_CPU_FILTERS_H diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/CMakeLists.txt b/pxr/imaging/plugin/hdRpr/rifcpp/CMakeLists.txt deleted file mode 100644 index 9cc753073..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -target_sources(hdRpr PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/rifError.h - ${CMAKE_CURRENT_SOURCE_DIR}/rifObject.h - ${CMAKE_CURRENT_SOURCE_DIR}/rifContext.h - ${CMAKE_CURRENT_SOURCE_DIR}/rifContext.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rifFilter.h - ${CMAKE_CURRENT_SOURCE_DIR}/rifFilter.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rifImage.h - ${CMAKE_CURRENT_SOURCE_DIR}/rifImage.cpp) diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifContext.cpp b/pxr/imaging/plugin/hdRpr/rifcpp/rifContext.cpp deleted file mode 100644 index 619340bc5..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifContext.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#include "rifContext.h" -#include "rifError.h" - -#include "rprApiFramebuffer.h" -#include "pxr/imaging/rprUsd/contextMetadata.h" -#include "pxr/imaging/rprUsd/helpers.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -PXR_NAMESPACE_OPEN_SCOPE - -namespace rif { - -namespace { - -class ContextOpenCL final : public Context { -public: - explicit ContextOpenCL(rpr::Context* rprContext, std::string const& modelPath); - ~ContextOpenCL() override = default; - - std::unique_ptr CreateImage(HdRprApiFramebuffer* rprFrameBuffer) override; -private: - const rif_backend_api_type rifBackendApiType = RIF_BACKEND_API_OPENCL; -}; - -class ContextMetal final : public Context { -public: - explicit ContextMetal(rpr::Context* rprContext, std::string const& modelPath); - ~ContextMetal() override = default; - - std::unique_ptr CreateImage(HdRprApiFramebuffer* rprFrameBuffer) override; -private: - const rif_backend_api_type rifBackendApiType = RIF_BACKEND_API_METAL; -}; - -class ContextCPU final : public Context { -public: - explicit ContextCPU(rpr::Context* rprContext, std::string const& modelPath); - ~ContextCPU() override = default; - - std::unique_ptr CreateImage(HdRprApiFramebuffer* rprFrameBuffer) override; - - void UpdateInputImage(HdRprApiFramebuffer* rprFrameBuffer, rif_image image) override; -private: -#ifdef __APPLE__ - const rif_backend_api_type rifBackendApiType = RIF_BACKEND_API_METAL; -#else - const rif_backend_api_type rifBackendApiType = RIF_BACKEND_API_OPENCL; -#endif -}; - -std::vector GetRprCachePath(rpr::Context* rprContext) { - size_t length; - rpr_status status = rprContext->GetInfo(RPR_CONTEXT_CACHE_PATH, sizeof(size_t), nullptr, &length); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to get cache path", rprContext)); - } - - std::vector path(length); - status = rprContext->GetInfo(RPR_CONTEXT_CACHE_PATH, path.size(), &path[0], nullptr); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to get cache path", rprContext)); - } - - return path; -} - -rif_image_desc GetRifImageDesc(HdRprApiFramebuffer* rprFrameBuffer) { - auto rprDesc = rprFrameBuffer->GetDesc(); - - rif_image_desc imageDesc = {}; - imageDesc.image_width = rprDesc.fb_width; - imageDesc.image_height = rprDesc.fb_height; - imageDesc.image_depth = 1; - imageDesc.image_row_pitch = 0; - imageDesc.image_slice_pitch = 0; - imageDesc.num_components = 4; - imageDesc.type = RIF_COMPONENT_TYPE_FLOAT32; - - return imageDesc; -} - -ContextOpenCL::ContextOpenCL(rpr::Context* rprContext, std::string const& modelPath) - : Context(modelPath) { - int deviceCount = 0; - RIF_ERROR_CHECK_THROW(rifGetDeviceCount(rifBackendApiType, &deviceCount), "Failed to query device count"); - - assert(deviceCount != 0); - if (0 == deviceCount) - throw rif::Error("No compatible devices."); - - rpr_cl_context clContext; - rpr_status status = rprContext->GetInfo(rpr::ContextInfo(RPR_CL_CONTEXT), sizeof(rpr_cl_context), &clContext, nullptr); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to query CL context", rprContext)); - } - - rpr_cl_device clDevice; - status = rprContext->GetInfo(rpr::ContextInfo(RPR_CL_DEVICE), sizeof(rpr_cl_device), &clDevice, nullptr); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to query CL device", rprContext)); - } - - rpr_cl_command_queue clCommandQueue; - status = rprContext->GetInfo(rpr::ContextInfo(RPR_CL_COMMAND_QUEUE), sizeof(rpr_cl_command_queue), &clCommandQueue, nullptr); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to query CL command queue", rprContext)); - } - - std::vector path = GetRprCachePath(rprContext); - RIF_ERROR_CHECK_THROW(rifCreateContextFromOpenClContext(RIF_API_VERSION, clContext, clDevice, clCommandQueue, path.data(), &m_context), "Failed to create RIF context") -} - -std::unique_ptr ContextOpenCL::CreateImage(HdRprApiFramebuffer* rprFrameBuffer) { - if (!rprFrameBuffer) { - return nullptr; - } - - rif_image rifImage = nullptr; - - rpr_cl_mem clMem = rprFrameBuffer->GetCLMem(); - assert(clMem); - if (!clMem) { - RIF_THROW_ERROR_MSG("Failed to get rpr framebuffer cl_mem"); - } - - auto rifImageDesc = GetRifImageDesc(rprFrameBuffer); - RIF_ERROR_CHECK_THROW(rifContextCreateImageFromOpenClMemory(m_context, &rifImageDesc, clMem, &rifImage), "Failed to create RIF image from OpenCL memory"); - - return std::unique_ptr(new Image(rifImage)); -} - -ContextCPU::ContextCPU(rpr::Context* rprContext, std::string const& modelPath) - : Context(modelPath) { - int deviceCount = 0; - RIF_ERROR_CHECK_THROW(rifGetDeviceCount(rifBackendApiType, &deviceCount), "Failed to query device count"); - - assert(deviceCount != 0); - if (0 == deviceCount) - RIF_THROW_ERROR_MSG("No compatible devices"); - - std::vector path = GetRprCachePath(rprContext); - - RIF_ERROR_CHECK_THROW(rifCreateContext(RIF_API_VERSION, rifBackendApiType, 0, path.data(), &m_context), "Failed to create RIF context") -} - -std::unique_ptr ContextCPU::CreateImage(HdRprApiFramebuffer* rprFrameBuffer) { - if (!rprFrameBuffer) { - return nullptr; - } - - return Context::CreateImage(GetRifImageDesc(rprFrameBuffer)); -} - -void ContextCPU::UpdateInputImage(HdRprApiFramebuffer* rprFrameBuffer, rif_image image) { - if (!rprFrameBuffer || !image) { - return; - } - - // data have to be acquired from RPR framebuffers and moved to filter inputs - - size_t sizeInBytes = 0; - size_t retSize = 0; - - // verify image size - RIF_ERROR_CHECK_THROW(rifImageGetInfo(image, RIF_IMAGE_DATA_SIZEBYTE, sizeof(size_t), (void*)& sizeInBytes, &retSize), "Failed to get RIF image info"); - - size_t fbSize; - rpr_status status = rprFrameBuffer->GetRprObject()->GetInfo(RPR_FRAMEBUFFER_DATA, 0, NULL, &fbSize); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to query RPR_FRAMEBUFFER_DATA")); - } - - assert(sizeInBytes == fbSize); - - if (sizeInBytes != fbSize) - RIF_THROW_ERROR_MSG("Failed to match RIF image and frame buffer sizes"); - - // resolve framebuffer data to rif image - void* imageData = nullptr; - RIF_ERROR_CHECK_THROW(rifImageMap(image, RIF_IMAGE_MAP_WRITE, &imageData), "Failed to map RIF image"); - - auto rprStatus = rprFrameBuffer->GetRprObject()->GetInfo(RPR_FRAMEBUFFER_DATA, fbSize, imageData, NULL); - assert(RPR_SUCCESS == rprStatus); - - // try to unmap at first, then raise a possible error - - RIF_ERROR_CHECK_THROW(rifImageUnmap(image, imageData), "Failed to unmap RIF image"); - - if (RPR_SUCCESS != rprStatus) - RIF_THROW_ERROR_MSG("Failed to get data from RPR frame buffer"); -} - -rpr_int GpuDeviceIdUsed(rpr_creation_flags contextFlags) { - -#define GPU(x) RPR_CREATION_FLAGS_ENABLE_GPU##x - - std::vector gpu_ids; - gpu_ids.reserve(16); - gpu_ids.push_back(GPU(0)); - gpu_ids.push_back(GPU(1)); - gpu_ids.push_back(GPU(2)); - gpu_ids.push_back(GPU(3)); - gpu_ids.push_back(GPU(4)); - gpu_ids.push_back(GPU(5)); - gpu_ids.push_back(GPU(6)); - gpu_ids.push_back(GPU(7)); - gpu_ids.push_back(GPU(8)); - gpu_ids.push_back(GPU(9)); - gpu_ids.push_back(GPU(10)); - gpu_ids.push_back(GPU(11)); - gpu_ids.push_back(GPU(12)); - gpu_ids.push_back(GPU(13)); - gpu_ids.push_back(GPU(14)); - gpu_ids.push_back(GPU(15)); - -#undef GPU - - for (rpr_int i = 0; i < gpu_ids.size(); i++ ) - { - if ((contextFlags & gpu_ids[i]) != 0) - return i; - } - - return -1; -} - -ContextMetal::ContextMetal(rpr::Context* rprContext, std::string const& modelPath) - : Context(modelPath) { - int deviceCount = 0; - RIF_ERROR_CHECK_THROW(rifGetDeviceCount(rifBackendApiType, &deviceCount), "Failed to query device count"); - - assert(deviceCount != 0); - if (0 == deviceCount) - RIF_THROW_ERROR_MSG("No compatible devices"); - - rpr_creation_flags contextFlags = 0; - rpr_status status = rprContext->GetInfo(RPR_CONTEXT_CREATION_FLAGS, sizeof(rpr_creation_flags), &contextFlags, nullptr); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to query RPR context creation flags")); - } - - std::vector path = GetRprCachePath(rprContext); - - // we find the active gpu from the rpr contextFlags and then use that to create the rif context - RIF_ERROR_CHECK_THROW(rifCreateContext(RIF_API_VERSION, rifBackendApiType, GpuDeviceIdUsed(contextFlags), path.data(), &m_context), "Failed to create RIF context"); -} - -std::unique_ptr ContextMetal::CreateImage(HdRprApiFramebuffer* rprFrameBuffer) { -#ifdef __APPLE__ - if (!rprFrameBuffer) { - return nullptr; - } - - rif_image rifImage = nullptr; - rpr_cl_mem clMem = rprFrameBuffer->GetCLMem(); - assert(clMem); - if (!clMem) - RIF_THROW_ERROR_MSG("Failed to get frame buffer cl_mem"); - - rpr::ImageFormat fbFormat; - auto status = rprFrameBuffer->GetRprObject()->GetInfo(RPR_FRAMEBUFFER_FORMAT, sizeof(fbFormat), &fbFormat, nullptr); - if (status != RPR_SUCCESS) { - throw rif::Error(RPR_GET_ERROR_MESSAGE(status, "Failed to get framebuffer format")); - } - - int bytesPerComponent = 1; - if (fbFormat.type == RPR_COMPONENT_TYPE_FLOAT32) { - bytesPerComponent = 4; - } else if (fbFormat.type == RPR_COMPONENT_TYPE_FLOAT16) { - bytesPerComponent = 2; - } - auto desc = GetRifImageDesc(rprFrameBuffer); - rif_longlong size = desc.image_width * desc.image_height * fbFormat.num_components * bytesPerComponent; - - RIF_ERROR_CHECK_THROW(rifContextCreateImageFromMetalMemory(m_context, &desc, clMem, size, &rifImage), "Failed to create RIF image from metal memory"); - - return std::unique_ptr(new Image(rifImage)); -#else - return nullptr; -#endif -} - -bool HasGpuContext(rpr_creation_flags contextFlags) { - -#define GPU(x) RPR_CREATION_FLAGS_ENABLE_GPU##x - - rpr_creation_flags gpuMask = GPU(0) | GPU(1) | GPU(2) | GPU(3) | GPU(4) | GPU(5) | GPU(6) | GPU(7) | - GPU(8) | GPU(9) | GPU(10) | GPU(11) | GPU(12) | GPU(13) | GPU(14) | GPU(15); - -#undef GPU - - return (contextFlags & gpuMask) != 0; -} - -} // namespace anonymous - -std::unique_ptr Context::Create(rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, std::string const& modelPath) { - if (!rprContext) { - return nullptr; - } - - rpr_creation_flags contextFlags = 0; - if (RPR_ERROR_CHECK(rprContext->GetInfo(RPR_CONTEXT_CREATION_FLAGS, sizeof(rpr_creation_flags), &contextFlags, nullptr), "Failed to query RPR context creation flags")) { - return nullptr; - } - - try { - std::unique_ptr rifContext; - rifContext.reset(new ContextCPU(rprContext, modelPath)); - - RIF_ERROR_CHECK_THROW(rifContextCreateCommandQueue(rifContext->m_context, &rifContext->m_commandQueue), "Failed to create RIF command queue"); - - return rifContext; - } catch (rif::Error const& e) { - TF_RUNTIME_ERROR("Failed to create RIF context. RIF error: %s", e.what()); - } - - return nullptr; -} - -Context::Context(std::string const& modelPath) - : m_modelPath(modelPath) { - -} - -Context::~Context() { - if (m_commandQueue) { - rifObjectDelete(m_commandQueue); - } - if (m_context) { - rifObjectDelete(m_context); - } -} - -std::unique_ptr Context::CreateImage(rif_image_desc const& desc) { - rif_image rifImage = nullptr; - RIF_ERROR_CHECK_THROW(rifContextCreateImage(m_context, &desc, nullptr, &rifImage), "Failed to create RIF image"); - return std::unique_ptr(new Image(rifImage)); -} - -void Context::UpdateInputImage(HdRprApiFramebuffer* rprFrameBuffer, rif_image image) { - // no-op -} - -void Context::AttachFilter(rif_image_filter filter, rif_image inputImage, rif_image outputImage) { - RIF_ERROR_CHECK_THROW(rifCommandQueueAttachImageFilter(m_commandQueue, filter, inputImage, outputImage), "Failed to attach image filter to queue"); - ++m_numAttachedFilters; -} - -void Context::DetachFilter(rif_image_filter filter) { - auto rifStatus = rifCommandQueueDetachImageFilter(m_commandQueue, filter); - if (rifStatus == RIF_ERROR_INVALID_PARAMETER) { - // Ignore if filter was not attached before - return; - } - - RIF_ERROR_CHECK_THROW(rifStatus, "Failed to detach image filter from queue"); - --m_numAttachedFilters; -} - -rif_image_filter Context::CreateImageFilter(rif_image_filter_type type) { - rif_image_filter outFilter = nullptr; - RIF_ERROR_CHECK_THROW(rifContextCreateImageFilter(m_context, type, &outFilter), "Failed to create image filter"); - return outFilter; -} - -void Context::ExecuteCommandQueue() { - if (!m_numAttachedFilters) { - return; - } - - RIF_ERROR_CHECK_THROW(rifContextExecuteCommandQueue(m_context, m_commandQueue, nullptr, nullptr, nullptr), "Failed to execute command queue"); - RIF_ERROR_CHECK_THROW(rifSyncronizeQueue(m_commandQueue), "Failed to synchronize command queue"); -} - -} // namespace rif - -PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifContext.h b/pxr/imaging/plugin/hdRpr/rifcpp/rifContext.h deleted file mode 100644 index e0990d01f..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifContext.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#ifndef RIFCPP_CONTEXT_H -#define RIFCPP_CONTEXT_H - -#include "rifImage.h" - -#include -#include - -namespace rpr { class Context; } - -PXR_NAMESPACE_OPEN_SCOPE - -struct RprUsdContextMetadata; -class HdRprApiFramebuffer; - -namespace rif { - -class Context { -public: - static std::unique_ptr Create(rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, std::string const& modelPath); - - virtual ~Context(); - - rif_image_filter CreateImageFilter(rif_image_filter_type type); - - std::unique_ptr CreateImage(rif_image_desc const& desc); - virtual std::unique_ptr CreateImage(HdRprApiFramebuffer* rprFrameBuffer) = 0; - - void AttachFilter(rif_image_filter filter, rif_image inputImage, rif_image outputImage); - void DetachFilter(rif_image_filter filter); - - virtual void UpdateInputImage(HdRprApiFramebuffer* rprFrameBuffer, rif_image image); - - void ExecuteCommandQueue(); - - std::string const& GetModelPath() const { return m_modelPath; }; - -protected: - Context(std::string const& modelPath); - -protected: - rif_context m_context = nullptr; - rif_command_queue m_commandQueue = nullptr; - -private: - int m_numAttachedFilters = 0; - std::string m_modelPath; -}; - -PXR_NAMESPACE_CLOSE_SCOPE - -} // namespace rif - -#endif // RIFCPP_CONTEXT_H diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifError.h b/pxr/imaging/plugin/hdRpr/rifcpp/rifError.h deleted file mode 100644 index 3b61f2519..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifError.h +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#ifndef RIFCPP_EXCEPTION_H -#define RIFCPP_EXCEPTION_H - -#include "pxr/base/arch/functionLite.h" -#include "pxr/base/tf/stringUtils.h" - -#include -#include -#include - -#define RIF_ERROR_CHECK_THROW(status, msg) \ - do { \ - auto st = status; \ - if (st != RIF_SUCCESS) { \ - assert(false); \ - throw rif::Error(st, msg, __ARCH_FILE__, __ARCH_FUNCTION__, __LINE__); \ - } \ - } while(0); - -#define RIF_ERROR_CHECK(status, msg) \ - rif::IsErrorCheck(status, msg, __ARCH_FILE__, __ARCH_FUNCTION__, __LINE__) - -#define RIF_GET_ERROR_MESSAGE(status, msg) \ - rif::ConstructErrorMessage(status, msg, __ARCH_FILE__, __ARCH_FUNCTION__, __LINE__) - -#define RIF_THROW_ERROR_MSG(msg) \ - throw rif::Error(RIF_GET_ERROR_MESSAGE(RIF_SUCCESS, msg)); - -PXR_NAMESPACE_OPEN_SCOPE - -namespace rif { - -inline std::string ConstructErrorMessage(rif_int errorStatus, std::string const& messageOnFail, char const* file, char const* function, size_t line) { - auto rifErrorString = [errorStatus]() -> std::string { - switch (errorStatus) { - case RIF_ERROR_INVALID_API_VERSION: return "invalid api version"; - case RIF_ERROR_INVALID_PARAMETER: return "invalid parameter"; - case RIF_ERROR_UNSUPPORTED: return "unsupported"; - case RIF_ERROR_INTERNAL_ERROR: return "internal error"; - case RIF_ERROR_INVALID_CONTEXT: return "invalid context"; - default: - break; - } - - return "error code - " + std::to_string(errorStatus); - }; - - auto suffix = TfStringPrintf(" in %s at line %zu of %s", function, line, file); -#ifdef RPR_GIT_SHORT_HASH - suffix += TfStringPrintf("(%s)", RPR_GIT_SHORT_HASH); -#endif // RPR_GIT_SHORT_HASH - if (errorStatus == RIF_SUCCESS) { - return TfStringPrintf("[RIF ERROR] %s%s", messageOnFail.c_str(), suffix.c_str()); - } else { - auto errorStr = rifErrorString(); - return TfStringPrintf("[RIF ERROR] %s -- %s%s", messageOnFail.c_str(), errorStr.c_str(), suffix.c_str()); - } -} - -inline bool IsErrorCheck(const rif_int status, const std::string& messageOnFail, char const* file, char const* function, size_t line) { - if (RIF_SUCCESS == status) { - return false; - } - - auto errorMessage = ConstructErrorMessage(status, messageOnFail.c_str(), file, function, line); - fprintf(stderr, "%s\n", errorMessage.c_str()); - return true; -} - -class Error : public std::runtime_error { -public: - Error(rif_int errorStatus, const char* messageOnFail, char const* file, char const* function, size_t line) - : std::runtime_error(ConstructErrorMessage(errorStatus, messageOnFail, file, function, line)) { - - } - - Error(std::string const& errorMesssage) - : std::runtime_error(errorMesssage) { - - } -}; - -} // namespace rif - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif // RIFCPP_EXCEPTION_H \ No newline at end of file diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.cpp b/pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.cpp deleted file mode 100644 index 75a1da8ef..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#include "rifFilter.h" -#include "rifError.h" - -PXR_NAMESPACE_OPEN_SCOPE - -namespace rif { - -namespace { - -class FilterAIDenoise final : public Filter { - enum { - RemapDepthFilter, - RemapNormalFilter, - AuxFilterMax - }; - enum { - RemappedDepthImage, - RemappedNormalImage, - AuxImageMax - }; -public: - explicit FilterAIDenoise(Context* rifContext, std::uint32_t width, std::uint32_t height); - ~FilterAIDenoise() override = default; - - void AttachFilter(rif_image inputImage) override; -}; - -class FilterEaw final : public Filter { - enum { - ColorVar, - Mlaa, - AuxFilterMax - }; - - enum { - ColorVarianceImage, - DenoisedOutputImage, - AuxImageMax - }; - -public: - explicit FilterEaw(Context* rifContext, std::uint32_t width, std::uint32_t height); - ~FilterEaw() override = default; - - void AttachFilter(rif_image inputImage) override; -}; - -class FilterResample final : public Filter { -public: - explicit FilterResample(Context* rifContext, std::uint32_t width, std::uint32_t height); - ~FilterResample() override = default; - - void Resize(std::uint32_t width, std::uint32_t height) override; -}; - -class FilterCustom final : public Filter { -public: - explicit FilterCustom(Context* rifContext, rif_image_filter_type type) : Filter(rifContext) { - m_rifFilter = rifContext->CreateImageFilter(type); - } - ~FilterCustom() override = default; -}; - -FilterAIDenoise::FilterAIDenoise(Context* rifContext, std::uint32_t width, std::uint32_t height) : Filter(rifContext) { - m_rifFilter = rifContext->CreateImageFilter(RIF_IMAGE_FILTER_AI_DENOISE); - - // setup const parameters - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1u(m_rifFilter, "useHDR", 1), "Failed to set filter \"usdHDR\" parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterString(m_rifFilter, "modelPath", rifContext->GetModelPath().c_str()), "Failed to set filter \"modelPath\" parameter"); - - // auxillary filters - m_auxFilters.resize(AuxFilterMax, nullptr); - m_auxFilters[RemapDepthFilter] = rifContext->CreateImageFilter(RIF_IMAGE_FILTER_REMAP_RANGE); - m_auxFilters[RemapNormalFilter] = rifContext->CreateImageFilter(RIF_IMAGE_FILTER_REMAP_RANGE); - - // setup remapping filters - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_auxFilters[RemapDepthFilter], "dstLo", 0.0f), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_auxFilters[RemapDepthFilter], "dstHi", 1.0f), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_auxFilters[RemapNormalFilter], "dstLo", 0.0f), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_auxFilters[RemapNormalFilter], "dstHi", 1.0f), "Failed to set filter parameter"); - - // auxillary rif images - auto desc = Image::GetDesc(width, height, HdFormatFloat32Vec4); - - m_auxImages.resize(AuxImageMax); - m_auxImages[RemappedDepthImage] = rifContext->CreateImage(desc); - m_auxImages[RemappedNormalImage] = rifContext->CreateImage(desc); -} - -void FilterAIDenoise::AttachFilter(rif_image inputImage) { - // setup inputs - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, "normalsImg", m_auxImages[RemappedNormalImage]->GetHandle()), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, "depthImg", m_auxImages[RemappedDepthImage]->GetHandle()), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, "colorImg", m_inputs.at(Color).rifImage), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, "albedoImg", m_inputs.at(Albedo).rifImage), "Failed to set filter parameter"); - - m_rifContext->AttachFilter(m_auxFilters[RemapDepthFilter], m_inputs.at(LinearDepth).rifImage, m_auxImages[RemappedDepthImage]->GetHandle()); - m_rifContext->AttachFilter(m_auxFilters[RemapNormalFilter], m_inputs.at(Normal).rifImage, m_auxImages[RemappedNormalImage]->GetHandle()); - - Filter::AttachFilter(inputImage); -} - -FilterEaw::FilterEaw(Context* rifContext, std::uint32_t width, std::uint32_t height) : Filter(rifContext) { - // main EAW filter - m_rifFilter = rifContext->CreateImageFilter(RIF_IMAGE_FILTER_EAW_DENOISE); - - // auxillary EAW filters - m_auxFilters.resize(AuxFilterMax, nullptr); - m_auxFilters[ColorVar] = rifContext->CreateImageFilter(RIF_IMAGE_FILTER_TEMPORAL_ACCUMULATOR); - m_auxFilters[Mlaa] = rifContext->CreateImageFilter(RIF_IMAGE_FILTER_MLAA); - - // auxillary rif images - auto desc = Image::GetDesc(width, height, HdFormatFloat32Vec4); - - m_auxImages.resize(AuxImageMax); - m_auxImages[ColorVarianceImage] = rifContext->CreateImage(desc); - m_auxImages[DenoisedOutputImage] = rifContext->CreateImage(desc); -} - -void FilterEaw::AttachFilter(rif_image inputImage) { - // setup params - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, "normalsImg", m_inputs.at(Normal).rifImage), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, "transImg", m_inputs.at(ObjectId).rifImage), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, "colorVar", m_inputs.at(Color).rifImage), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_rifFilter, "colorSigma", m_inputs.at(Color).sigma), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_rifFilter, "normalSigma", m_inputs.at(Normal).sigma), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_rifFilter, "depthSigma", m_inputs.at(LinearDepth).sigma), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1f(m_rifFilter, "transSigma", m_inputs.at(ObjectId).sigma), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_auxFilters[Mlaa], "normalsImg", m_inputs.at(Normal).rifImage), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_auxFilters[Mlaa], "meshIDImg", m_inputs.at(ObjectId).rifImage), "Failed to set filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_auxFilters[ColorVar], "positionsImg", m_inputs.at(WorldCoordinate).rifImage), "Failed to set variance filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_auxFilters[ColorVar], "normalsImg", m_inputs.at(Normal).rifImage), "Failed to set variance filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_auxFilters[ColorVar], "meshIdsImg", m_inputs.at(ObjectId).rifImage), "Failed to set variance filter parameter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_auxFilters[ColorVar], "outVarianceImg", m_auxImages[ColorVarianceImage]->GetHandle()), "Failed to set variance filter parameter"); - - m_rifContext->AttachFilter(m_auxFilters[ColorVar], inputImage, m_outputImage); - m_rifContext->AttachFilter(m_rifFilter, m_outputImage, m_auxImages[DenoisedOutputImage]->GetHandle()); - m_rifContext->AttachFilter(m_auxFilters[Mlaa], m_auxImages[DenoisedOutputImage]->GetHandle(), m_outputImage); -} - -FilterResample::FilterResample(Context* rifContext, std::uint32_t width, std::uint32_t height) : Filter(rifContext) { - m_rifFilter = rifContext->CreateImageFilter(RIF_IMAGE_FILTER_RESAMPLE); - - // setup const parameters - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter1u(m_rifFilter, "interpOperator", RIF_IMAGE_INTERPOLATION_NEAREST), "Failed to set parameter of resample filter"); - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter2u(m_rifFilter, "outSize", width, height), "Failed to set parameter of resample filter"); -} - -void FilterResample::Resize(std::uint32_t width, std::uint32_t height) { - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameter2u(m_rifFilter, "outSize", width, height), "Failed to set parameter of resample filter"); - Filter::Resize(width, height); -} - -} // namespace anonymous - -std::unique_ptr Filter::Create(FilterType type, Context* rifContext, std::uint32_t width, std::uint32_t height) { - if (!width || !height) { - return nullptr; - } - - switch (type) { - case FilterType::AIDenoise: - return std::unique_ptr(new FilterAIDenoise(rifContext, width, height)); - case FilterType::EawDenoise: - return std::unique_ptr(new FilterEaw(rifContext, width, height)); - case FilterType::Resample: - return std::unique_ptr(new FilterResample(rifContext, width, height)); - default: - return nullptr; - } -} -std::unique_ptr Filter::CreateCustom(rif_image_filter_type type, Context* rifContext) { - if (!rifContext) { - return nullptr; - } - - return std::unique_ptr(new FilterCustom(rifContext, type)); -} - -Filter::~Filter() { - DetachFilter(); - - rif_int rifStatus = RIF_SUCCESS; - - for (const rif_image_filter& auxFilter : m_auxFilters) { - rifStatus = rifObjectDelete(auxFilter); - assert(RIF_SUCCESS == rifStatus); - } - - if (m_rifFilter != nullptr) { - rifStatus = rifObjectDelete(m_rifFilter); - assert(RIF_SUCCESS == rifStatus); - } -} - -void Filter::SetInput(FilterInputType inputType, Filter* filter) { - m_inputs[inputType] = InputTraits(rif_image(filter->m_rifFilter), 1.0f); - m_dirtyFlags |= DirtyIOImage; -} - -void Filter::SetInput(FilterInputType inputType, rif_image rifImage, const float sigma) { - assert(rifImage); - - m_inputs[inputType] = InputTraits(rifImage, sigma); - m_dirtyFlags |= DirtyIOImage; -} - -void Filter::SetInput(FilterInputType inputType, HdRprApiFramebuffer* rprFrameBuffer, const float sigma) { - assert(rprFrameBuffer); - - m_inputs[inputType] = InputTraits(rprFrameBuffer, m_rifContext, sigma); - m_dirtyFlags |= DirtyIOImage; -} - -void Filter::SetInput(const char* name, HdRprApiFramebuffer* rprFrameBuffer) { - m_namedInputs[name] = InputTraits(rprFrameBuffer, m_rifContext, 1.0f); - m_dirtyFlags |= DirtyParameters; -} - -void Filter::SetInput(const char* name, rif_image rifImage) { - m_namedInputs[name] = InputTraits(rifImage, 1.0f); - m_dirtyFlags |= DirtyParameters; -} - -void Filter::SetOutput(rif_image_desc imageDesc) { - m_retainedOutputImage = m_rifContext->CreateImage(imageDesc); - m_outputImage = m_retainedOutputImage->GetHandle(); - m_dirtyFlags |= DirtyIOImage; -} - -void Filter::SetOutput(rif_image rifImage) { - m_retainedOutputImage = nullptr; - m_outputImage = rifImage; - m_dirtyFlags |= DirtyIOImage; -} - -void Filter::SetOutput(HdRprApiFramebuffer* rprFrameBuffer) { - m_retainedOutputImage = m_rifContext->CreateImage(rprFrameBuffer); - m_outputImage = m_retainedOutputImage->GetHandle(); - m_dirtyFlags |= DirtyIOImage; -} - -rif_image Filter::GetInput(FilterInputType inputType) const { - auto inputIter = m_inputs.find(inputType); - if (inputIter != m_inputs.end()) { - return inputIter->second.rifImage; - } - - return nullptr; -} - -rif_image Filter::GetOutput() { - return m_outputImage; -} - -void Filter::SetParam(const char* name, FilterParam param) { - m_params[name] = param; - m_dirtyFlags |= DirtyParameters; -} - -void Filter::SetParamFilter(const char* name, Filter* filter) { - if (filter) { - SetParam(name, rif_image(filter->m_rifFilter)); - } -} - -void Filter::Resize(std::uint32_t width, std::uint32_t height) { - auto desc = Image::GetDesc(width, height, HdFormatFloat32Vec4); - for (auto& image : m_auxImages) { - if (image) { - image = m_rifContext->CreateImage(desc); - } - } -} - -template -void UpdateInputs(Iter begin, Iter end, Context* context) { - for (; begin != end; ++begin) { - if (begin->second.rprFrameBuffer) { - context->UpdateInputImage(begin->second.rprFrameBuffer, begin->second.rifImage); - } - } -} - -void Filter::Update() { - if (m_dirtyFlags & DirtyParameters) { - ApplyParameters(); - } - if (m_dirtyFlags & DirtyIOImage) { - DetachFilter(); - if (m_outputImage) { - AttachFilter(GetInput(Color)); - m_isAttached = true; - } - } - - m_dirtyFlags = Clean; -} - -void Filter::Resolve() { - UpdateInputs(m_inputs.begin(), m_inputs.end(), m_rifContext); - UpdateInputs(m_namedInputs.begin(), m_namedInputs.end(), m_rifContext); -} - -void Filter::AttachFilter(rif_image inputImage) { - m_rifContext->AttachFilter(m_rifFilter, inputImage, m_outputImage); -} - -void Filter::DetachFilter() { - if (!m_rifContext || !m_isAttached) { - return; - } - m_isAttached = false; - - for (const rif_image_filter& auxFilter : m_auxFilters) { - m_rifContext->DetachFilter(auxFilter); - } - m_rifContext->DetachFilter(m_rifFilter); -} - -struct ParameterSetter : public BOOST_NS::static_visitor { - const char* paramName; - rif_image_filter filter; - - rif_int operator()(int value) { - return rifImageFilterSetParameter1u(filter, paramName, value); - } - - rif_int operator()(float value) { - return rifImageFilterSetParameter1f(filter, paramName, value); - } - - rif_int operator()(std::string const& value) { - return rifImageFilterSetParameterString(filter, paramName, value.c_str()); - } - - rif_int operator()(GfVec2i const& value) { - return rifImageFilterSetParameter2u(filter, paramName, value[0], value[1]); - } - - rif_int operator()(GfMatrix4f const& value) { - return rifImageFilterSetParameter16f(filter, paramName, const_cast(value.data())); - } - - rif_int operator()(rif_image image) { - return rifImageFilterSetParameterImage(filter, paramName, image); - } -}; - -void Filter::ApplyParameters() { - for (const auto& param : m_params) { - ParameterSetter setter; - setter.paramName = param.first.c_str(); - setter.filter = m_rifFilter; - RIF_ERROR_CHECK_THROW(BOOST_NS::apply_visitor(setter, param.second), "Failed to set image filter parameter"); - } - for (const auto& namedInput : m_namedInputs) { - if (namedInput.second.rifImage) { - RIF_ERROR_CHECK_THROW(rifImageFilterSetParameterImage(m_rifFilter, namedInput.first.c_str(), namedInput.second.rifImage), "Failed to set image filter named parameter"); - } - } -} - -} // namespace rif - -PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.h b/pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.h deleted file mode 100644 index aaa5a6df0..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#ifndef RIFCPP_FILTER_H -#define RIFCPP_FILTER_H - -#include "rifContext.h" -#include "rifImage.h" - -#include "pxr/imaging/rprUsd/boostIncludePath.h" -#include BOOST_INCLUDE_PATH(variant.hpp) - -#include "pxr/base/gf/matrix4f.h" -#include "pxr/base/gf/vec2i.h" - -#include -#include -#include - -PXR_NAMESPACE_OPEN_SCOPE - -class HdRprApiFramebuffer; - -namespace rif { - -enum FilterInputType -{ - Color, - Normal, - LinearDepth, - WorldCoordinate, - ObjectId, - Trans, - Albedo, - MaxInput -}; - -using FilterParam = BOOST_NS::variant; - -enum class FilterType -{ - None = -1, - AIDenoise, - Resample, - EawDenoise, - FIRST = AIDenoise, - LAST = EawDenoise -}; - -class Filter { -public: - static std::unique_ptr Create(FilterType type, Context* rifContext, std::uint32_t width, std::uint32_t height); - static std::unique_ptr CreateCustom(rif_image_filter_type type, Context* rifContext); - - virtual ~Filter(); - - void SetInput(FilterInputType inputType, Filter* filter); - void SetInput(FilterInputType inputType, rif_image rifImage, float sigma = 1.0f); - void SetInput(FilterInputType inputType, HdRprApiFramebuffer* rprFrameBuffer, float sigma = 1.0f); - void SetInput(const char* name, HdRprApiFramebuffer* rprFrameBuffer); - void SetInput(const char* name, rif_image rifImage); - void SetOutput(rif_image rifImage); - void SetOutput(rif_image_desc imageDesc); - void SetOutput(HdRprApiFramebuffer* rprFrameBuffer); - void SetParam(const char* name, FilterParam param); - void SetParamFilter(const char* name, Filter* filter); - - rif_image GetInput(FilterInputType inputType) const; - rif_image GetOutput(); - - virtual void Resize(std::uint32_t width, std::uint32_t height); - void Update(); - void Resolve(); - -protected: - Filter(Context* rifContext) : m_rifContext(rifContext) {} - - void DetachFilter(); - virtual void AttachFilter(rif_image inputImage); - - void ApplyParameters(); - -protected: - Context* m_rifContext; - rif_image_filter m_rifFilter = nullptr; - - std::vector m_auxFilters; - std::vector> m_auxImages; - - std::unique_ptr m_retainedOutputImage; - - struct InputTraits { - rif_image rifImage; - HdRprApiFramebuffer* rprFrameBuffer; - float sigma; - - std::unique_ptr retainedImage; - - InputTraits() : rifImage(nullptr), rprFrameBuffer(nullptr), sigma(0.0f) {} - InputTraits(rif_image rifImage, float sigma) : rifImage(rifImage), rprFrameBuffer(nullptr), sigma(sigma) {} - InputTraits(HdRprApiFramebuffer* rprFrameBuffer, Context* context, float sigma) : rprFrameBuffer(rprFrameBuffer), sigma(sigma) { - retainedImage = context->CreateImage(rprFrameBuffer); - rifImage = retainedImage->GetHandle(); - } - }; - - std::unordered_map::type>> m_inputs; - std::map m_namedInputs; - std::unordered_map m_params; - - rif_image m_outputImage = nullptr; - - enum ChangeTracker { - Clean = 0, - DirtyAll = ~0u, - DirtyIOImage = 1 << 0, - DirtyParameters = 1 << 2 - }; - uint32_t m_dirtyFlags = DirtyAll; - - bool m_isAttached = false; -}; - -} // namespace rif - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif // RIFCPP_FILTER_H diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifImage.cpp b/pxr/imaging/plugin/hdRpr/rifcpp/rifImage.cpp deleted file mode 100644 index d1624ae1e..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifImage.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#include "rifImage.h" - -PXR_NAMESPACE_OPEN_SCOPE - -namespace rif { - -Image::Image(rif_image imageHandle) - : Object(imageHandle) { - -} - -rif_image_desc Image::GetDesc(uint32_t width, uint32_t height, HdFormat format) { - if (format == HdFormatInt32) { - // Emulate integer images using 4 component unsigned char images - format = HdFormatUNorm8Vec4; - } - - rif_image_desc imageDesc = {}; - imageDesc.num_components = HdGetComponentCount(format); - switch (HdGetComponentFormat(format)) { - case HdFormatUNorm8: - imageDesc.type = RIF_COMPONENT_TYPE_UINT8; - break; - case HdFormatFloat16: - imageDesc.type = RIF_COMPONENT_TYPE_FLOAT16; - break; - case HdFormatFloat32: - imageDesc.type = RIF_COMPONENT_TYPE_FLOAT32; - break; - default: - imageDesc.type = 0; - break; - } - imageDesc.image_width = width; - imageDesc.image_height = height; - imageDesc.image_depth = 1; - imageDesc.image_row_pitch = 0; - imageDesc.image_slice_pitch = 0; - - return imageDesc; -} - -} // namespace rif - -PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifImage.h b/pxr/imaging/plugin/hdRpr/rifcpp/rifImage.h deleted file mode 100644 index 4e7fa3a28..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifImage.h +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#ifndef RIFCPP_IMAGE_H -#define RIFCPP_IMAGE_H - -#include "rifObject.h" -#include "pxr/imaging/hd/types.h" - -PXR_NAMESPACE_OPEN_SCOPE - -namespace rif { - -class Image : public Object { -public: - static rif_image_desc GetDesc(uint32_t width, uint32_t height, HdFormat format); - - explicit Image(rif_image imageHandle); - - rif_image GetHandle() { return static_cast(m_rifObjectHandle); } -}; - -} // namespace rif - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif // RIFCPP_IMAGE_H diff --git a/pxr/imaging/plugin/hdRpr/rifcpp/rifObject.h b/pxr/imaging/plugin/hdRpr/rifcpp/rifObject.h deleted file mode 100644 index ce258662c..000000000 --- a/pxr/imaging/plugin/hdRpr/rifcpp/rifObject.h +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************ -Copyright 2020 Advanced Micro Devices, Inc -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ - -#ifndef RIFCPP_OBJECT_H -#define RIFCPP_OBJECT_H - -#include "pxr/pxr.h" - -#include - -PXR_NAMESPACE_OPEN_SCOPE - -namespace rif { - -class Context; - -class Object { -public: - Object(void* objectHandle) - : m_rifObjectHandle(objectHandle) { - - } - - Object() = default; - Object(Object const&) = delete; - Object& operator=(Object const&) = delete; - - void Delete() { - if (m_rifObjectHandle) { - rifObjectDelete(m_rifObjectHandle); - } - m_rifObjectHandle = nullptr; - } - - ~Object() { - Delete(); - } - -protected: - void* m_rifObjectHandle = nullptr; -}; - -} // namespace rif - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif // RIFCPP_OBJECT_H diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 93bb99e0a..39f413392 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -17,10 +17,7 @@ using json = nlohmann::json; #include "rprApi.h" #include "rprApiAov.h" #include "aovDescriptor.h" - -#include "rifcpp/rifFilter.h" -#include "rifcpp/rifImage.h" -#include "rifcpp/rifError.h" +#include "cpuFilters.h" #include "config.h" #include "camera.h" @@ -56,6 +53,7 @@ using json = nlohmann::json; #include "pxr/base/work/loops.h" #include "pxr/base/arch/env.h" #include "pxr/base/tf/envSetting.h" +#include "pxr/base/work/loops.h" #include "notify/message.h" @@ -470,7 +468,6 @@ class HdRprApiImpl { try { m_cacheCreationRequired = !CacheCreated(); InitRpr(); - InitRif(); InitAovs(); { @@ -1764,7 +1761,7 @@ class HdRprApiImpl { RPR_ERROR_CHECK(outRb.rprAov->GetAovFb()->GetRprObject()->SetLPE(outRb.lpe.c_str()), "Failed to set LPE")) { return nullptr; } - + m_outputRenderBuffers.push_back(std::move(outRb)); return &m_outputRenderBuffers.back(); }; @@ -1796,10 +1793,6 @@ class HdRprApiImpl { } }); - if (m_rifContext) { - m_rifContext->ExecuteCommandQueue(); - } - for (auto& outRb : m_outputRenderBuffers) { if (outRb.mappedData && (m_isFirstSample || outRb.isMultiSampled)) { outRb.rprAov->GetData(outRb.mappedData, outRb.mappedDataSize); @@ -2639,7 +2632,7 @@ class HdRprApiImpl { auto rprApi = rprRenderParam->GetRprApi(); m_resolveData.ForAllAovs([=](ResolveData::AovEntry const& e) { - e.aov->Update(rprApi, m_rifContext.get()); + e.aov->Update(rprApi); if (clearAovs) { e.aov->Clear(); } @@ -3893,35 +3886,6 @@ Don't show this message again? m_isAbortingEnabled.store(false); } - bool ValidateRifModels(std::string const& modelsPath) { - // To ensure that current RIF implementation will use correct models we check for the file that points to models version - std::ifstream versionFile(modelsPath + "/rif_models.version"); - if (versionFile.is_open()) { - std::stringstream buffer; - buffer << versionFile.rdbuf(); - auto rifVersionString = std::to_string(RIF_VERSION_MAJOR) + "." + std::to_string(RIF_VERSION_MINOR) + "." + std::to_string(RIF_VERSION_REVISION); - return rifVersionString == buffer.str(); - } - - return false; - } - - void InitRif() { - if (RprUsdIsCpuOnly()) { - return; // We can't create RIF context in CPU only mode - } - PlugPluginPtr plugin = PLUG_THIS_PLUGIN; - auto modelsPath = PlugFindPluginResource(plugin, "rif_models", false); - if (modelsPath.empty()) { - TF_RUNTIME_ERROR("Failed to find RIF models in plugin package"); - } else if (!ValidateRifModels(modelsPath)) { - modelsPath = ""; - TF_RUNTIME_ERROR("RIF version and AI models version mismatch"); - } - - m_rifContext = rif::Context::Create(m_rprContext.get(), m_rprContextMetadata, modelsPath); - } - void InitAovs() { m_colorAov = std::static_pointer_cast(CreateAov(HdAovTokens->color)); @@ -4260,7 +4224,7 @@ Don't show this message again? newAov = colorAov; } else if (aovName == HdAovTokens->normal) { - newAov = new HdRprApiNormalAov(width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiNormalAov(width, height, format, m_rprContext.get(), m_rprContextMetadata); } else if (aovName == HdAovTokens->depth) { auto worldCoordinateAov = GetAov(HdRprAovTokens->worldCoordinate, width, height, HdFormatFloat32Vec4); if (!worldCoordinateAov) { @@ -4273,29 +4237,9 @@ Don't show this message again? return nullptr; } - newAov = new HdRprApiDepthAov(width, height, format, std::move(worldCoordinateAov), std::move(opacityAov), m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); - } - else if (aovName == HdRprAovTokens->colorWithTransparency) { - auto rawColorAov = GetAov(HdRprAovTokens->rawColor, width, height, HdFormatFloat32Vec4); - if (!rawColorAov) { - TF_RUNTIME_ERROR("Failed to create scTransparentBackground AOV: can't create rawColor AOV"); - return nullptr; - } - auto opacityAov = GetAov(HdRprAovTokens->opacity, width, height, HdFormatFloat32Vec4); - if (!opacityAov) { - TF_RUNTIME_ERROR("Failed to create scTransparentBackground AOV: can't create opacity AOV"); - return nullptr; - } - auto shadowCatcherAov = GetAov(HdRprAovTokens->shadowCatcher, width, height, HdFormatFloat32Vec4); - if (!shadowCatcherAov) { - TF_RUNTIME_ERROR("Failed to create scTransparentBackground AOV: can't create shadowCatcher AOV"); - return nullptr; - } - - newAov = new HdRprApiScCompositeAOV(width, height, format, std::move(rawColorAov), std::move(opacityAov), std::move(shadowCatcherAov), m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); - + newAov = new HdRprApiDepthAov(width, height, format, std::move(worldCoordinateAov), std::move(opacityAov), m_rprContext.get(), m_rprContextMetadata); } else if (TfStringStartsWith(aovName.GetString(), "lpe")) { - newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata); aovCustomDestructor = [this](HdRprApiAov* aov) { // Each LPE AOV reserves RPR's LPE AOV id (RPR_AOV_LPE_0, ...) // As soon as LPE AOV is released we want to return reserved id to the pool @@ -4321,10 +4265,10 @@ Don't show this message again? return nullptr; } - newAov = new HdRprApiIdMaskAov(aovDesc, baseAov, width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiIdMaskAov(aovDesc, baseAov, width, height, format, m_rprContext.get(), m_rprContextMetadata); } else { if (!aovDesc.computed) { - newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata); } else { TF_CODING_ERROR("Failed to create %s AOV: unprocessed computed AOV", aovName.GetText()); } @@ -4378,10 +4322,6 @@ Don't show this message again? } bool RenderImage(std::string const& path) { - if (!m_rifContext) { - return false; - } - auto colorOutputRb = GetOutputRenderBuffer(HdAovTokens->color); if (!colorOutputRb) { return false; @@ -4389,101 +4329,38 @@ Don't show this message again? auto textureData = RprUsdTextureData::New(path); if (textureData) { - rif_image_desc imageDesc = {}; - imageDesc.image_width = textureData->GetWidth(); - imageDesc.image_height = textureData->GetHeight(); - imageDesc.image_depth = 1; - imageDesc.image_row_pitch = 0; - imageDesc.image_slice_pitch = 0; - + const size_t imageWidth = textureData->GetWidth(); + const size_t imageHeight = textureData->GetHeight(); auto textureMetadata = textureData->GetGLMetadata(); - uint8_t bytesPerComponent; - if (textureMetadata.glType == GL_UNSIGNED_BYTE) { - imageDesc.type = RIF_COMPONENT_TYPE_UINT8; - bytesPerComponent = 1; - } else if (textureMetadata.glType == GL_HALF_FLOAT) { - imageDesc.type = RIF_COMPONENT_TYPE_FLOAT16; - bytesPerComponent = 2; - } else if (textureMetadata.glType == GL_FLOAT) { - imageDesc.type = RIF_COMPONENT_TYPE_FLOAT32; - bytesPerComponent = 2; - } else { - TF_RUNTIME_ERROR("\"%s\" image has unsupported pixel channel type: %#x", path.c_str(), textureMetadata.glType); + if (textureMetadata.glType != GL_UNSIGNED_BYTE || textureMetadata.glFormat != GL_RGBA) { + TF_RUNTIME_ERROR("\"%s\" image has unsupported format. Should be RGBA PNG", path.c_str()); return false; } + const uint8_t bytesPerComponent = 1; + const size_t numComponents = 4; + + size_t totalNumComponents = numComponents * imageWidth * imageHeight; + size_t imageSize = bytesPerComponent * totalNumComponents; + std::vector mappedData(imageSize); + std::memcpy(mappedData.data(), textureData->GetData(), imageSize); + std::vector mappedDataFloat(totalNumComponents); + WorkParallelForN(numComponents * imageWidth * imageHeight, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + mappedDataFloat[i] = (float)mappedData[i] / 256.0f; + } + }); - if (textureMetadata.glFormat == GL_RGBA) { - imageDesc.num_components = 4; - } else if (textureMetadata.glFormat == GL_RGB) { - imageDesc.num_components = 3; - } else if (textureMetadata.glFormat == GL_RED) { - imageDesc.num_components = 1; - } else { - TF_RUNTIME_ERROR("\"%s\" image has unsupported pixel format: %#x", path.c_str(), textureMetadata.glFormat); - return false; + auto colorRb = static_cast(colorOutputRb->aovBinding->renderBuffer); + if (auto colorRbData = colorRb->GetPointerForWriting()) { + CpuResampleNearest((GfVec4f*)mappedDataFloat.data(), imageWidth, imageHeight, (GfVec4f*)colorRbData, colorRb->GetWidth(), colorRb->GetHeight()); } - - auto rifImage = m_rifContext->CreateImage(imageDesc); - - void* mappedData; - if (RIF_ERROR_CHECK(rifImageMap(rifImage->GetHandle(), RIF_IMAGE_MAP_WRITE, &mappedData), "Failed to map rif image") || !mappedData) { + else { return false; } - size_t imageSize = bytesPerComponent * imageDesc.num_components * imageDesc.image_width * imageDesc.image_height; - std::memcpy(mappedData, textureData->GetData(), imageSize); - RIF_ERROR_CHECK(rifImageUnmap(rifImage->GetHandle(), mappedData), "Failed to unmap rif image"); - - auto colorRb = static_cast(colorOutputRb->aovBinding->renderBuffer); - - try { - auto blitFilter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_USER_DEFINED, m_rifContext.get()); - auto blitKernelCode = std::string(R"( - const int2 outSize = GET_BUFFER_SIZE(outputImage); - - int2 coord; - GET_COORD_OR_RETURN(coord, outSize); - vec2 uv = (convert_vec2(coord) + 0.5f)/convert_vec2(outSize); - float aspectRatio = (float)(outSize.x)/outSize.y; - - vec2 srcUv; - if (aspectRatio > 1.0f) { - float scale = 1.0f/aspectRatio; - srcUv = make_vec2((uv.x - (1.0f - scale)*0.5f)/scale, uv.y); - } else { - srcUv = make_vec2(uv.x, (uv.y - (1.0f - aspectRatio)*0.5f)/aspectRatio); - } - - const int2 inSize = GET_BUFFER_SIZE(srcImage); - int2 srcCoord = convert_int2(srcUv*convert_vec2(inSize)); - srcCoord = clamp(srcCoord, make_int2(0, 0), inSize - 1); - vec4 color = ReadPixelTyped(srcImage, srcCoord.x, srcCoord.y); - - WritePixelTyped(outputImage, coord.x, coord.y, color); - )"); - blitFilter->SetInput("srcImage", rifImage->GetHandle()); - blitFilter->SetParam("code", blitKernelCode); - blitFilter->SetOutput(rif::Image::GetDesc(colorRb->GetWidth(), colorRb->GetHeight(), colorRb->GetFormat())); - blitFilter->SetInput(rif::Color, blitFilter->GetOutput()); - blitFilter->Update(); - - m_rifContext->ExecuteCommandQueue(); - - if (RIF_ERROR_CHECK(rifImageMap(blitFilter->GetOutput(), RIF_IMAGE_MAP_READ, &mappedData), "Failed to map rif image") || !mappedData) { - return false; - } - size_t size = HdDataSizeOfFormat(colorRb->GetFormat()) * colorRb->GetWidth() * colorRb->GetHeight(); - if (auto colorRbData = colorRb->GetPointerForWriting()) { - std::memcpy(colorRbData, mappedData, size); - } - - RIF_ERROR_CHECK(rifImageUnmap(blitFilter->GetOutput(), mappedData), "Failed to unmap rif image"); - return true; - } catch (rif::Error const& e) { - TF_RUNTIME_ERROR("Failed to blit image: %s", e.what()); - return false; - } + return true; } else { TF_RUNTIME_ERROR("Failed to load \"%s\" image", path.c_str()); return false; @@ -4538,8 +4415,6 @@ Don't show this message again? float m_firstIterationRenderTime = 0.0f; - std::unique_ptr m_rifContext; - std::unique_ptr m_scene; std::unique_ptr m_camera; std::unique_ptr m_imageCache; diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index f014e4c38..c3dea7416 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -14,54 +14,18 @@ limitations under the License. #include "rprApiAov.h" #include "rprApi.h" #include "rprApiFramebuffer.h" -#include "rifcpp/rifError.h" +#include "cpuFilters.h" #include "pxr/imaging/rprUsd/contextMetadata.h" #include "pxr/imaging/rprUsd/error.h" PXR_NAMESPACE_OPEN_SCOPE -namespace { - - bool ReadRifImage(rif_image image, void* dstBuffer, size_t dstBufferSize) { - if (!image || !dstBuffer) { - return false; - } - - size_t size; - size_t dummy; - auto rifStatus = rifImageGetInfo(image, RIF_IMAGE_DATA_SIZEBYTE, sizeof(size), &size, &dummy); - if (rifStatus != RIF_SUCCESS || dstBufferSize < size) { - return false; - } - - void* data = nullptr; - rifStatus = rifImageMap(image, RIF_IMAGE_MAP_READ, &data); - if (rifStatus != RIF_SUCCESS) { - return false; - } - - std::memcpy(dstBuffer, data, size); - - rifStatus = rifImageUnmap(image, data); - if (rifStatus != RIF_SUCCESS) { - TF_WARN("Failed to unmap rif image"); - } - - return true; - } - -} // namespace anonymous - HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, std::unique_ptr filter) + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) : m_aovDescriptor(HdRprAovRegistry::GetInstance().GetAovDesc(rprAovType, false)) - , m_filter(std::move(filter)) , m_format(format) { - if (rif::Image::GetDesc(0, 0, format).type == 0) { - RIF_THROW_ERROR_MSG("Unsupported format: " + TfEnum::GetName(format)); - } - + m_aov = pxr::make_unique(rprContext, width, height); m_aov->AttachAs(rprAovType); @@ -71,42 +35,28 @@ HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat for } } -HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext) - : HdRprApiAov(rprAovType, width, height, format, rprContext, rprContextMetadata, [format, rifContext]() -> std::unique_ptr { - if (format == HdFormatFloat32Vec4) { - // RPR framebuffers by default with such format - return nullptr; - } - if (!rifContext) - { - if (format == HdFormatFloat32) { - return nullptr; - } - if (format == HdFormatInt32) { - return nullptr; - } - RPR_THROW_ERROR_MSG("Only Float32Vec4, Float32, and Int32 data types are supported without rifContext."); - } - - auto filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_RESAMPLE, rifContext); - if (!filter) { - RPR_THROW_ERROR_MSG("Failed to create resample filter"); - } - - filter->SetParam("interpOperator", (int)RIF_IMAGE_INTERPOLATION_NEAREST); - return filter; -}()) { - -} - void HdRprApiAov::Resolve() { if (m_aov) { m_aov->Resolve(m_resolved.get()); } + ResolveImpl(); + UpdateTempBuffer(); +} + +void HdRprApiAov::ResolveImpl() { - if (m_filter) { - m_filter->Resolve(); + + if (m_filterEnabled) { + assert(m_outputBuffer.size() > 0); + auto resolvedFb = GetResolvedFb(); + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { + return; + } + + if (m_aov) { + auto fbDesc = m_aov->GetDesc(); + CpuResampleNearest((GfVec4f*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height, (GfVec4f*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height); + } } } @@ -118,8 +68,20 @@ void HdRprApiAov::Clear() { } bool HdRprApiAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { - if (m_filter) { - return ReadRifImage(m_filter->GetOutput(), dstBuffer, dstBufferSize); + if (m_tmpBuffer.size() > 0) { + if (dstBufferSize != m_tmpBuffer.size()) { + return false; + } + memcpy(dstBuffer, m_tmpBuffer.data(), dstBufferSize); + return true; + } + + if (m_outputBuffer.size() > 0) { + if (dstBufferSize != m_outputBuffer.size() * sizeof(float)) { + return false; + } + memcpy(dstBuffer, m_outputBuffer.data(), dstBufferSize); + return true; } auto resolvedFb = GetResolvedFb(); @@ -131,84 +93,7 @@ bool HdRprApiAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { } bool HdRprApiAov::GetData(void* dstBuffer, size_t dstBufferSize) { - auto getBuffer = dstBuffer; - if (!m_filter) - { - bool needTmpBuffer = true; - // Rpr always renders to HdFormatFloat32Vec4 - // If RIF is enabled then m_filter will cast to the desired type. - // But if RIF isn't enabled we must do the cast ourselves here. - // - // When this function is called dstBufferSize is set to the desired format buffer size. - // We must allocate m_tmpBuffer to size of a HdFormatFloat32Vec4 buffer. - // For both Float32 and Int32 we do this by multiplying the desired format buffer size by 4. - if (m_format == HdFormatFloat32) { - dstBufferSize = dstBufferSize * 4; - } - else if (m_format == HdFormatInt32) { - dstBufferSize = dstBufferSize * 4; - } - else { - needTmpBuffer = false; - } - if (needTmpBuffer) - { - if (m_tmpBuffer.size() < dstBufferSize) - { - m_tmpBuffer.resize(dstBufferSize); - } - getBuffer = m_tmpBuffer.data(); - } - } - if (GetDataImpl(getBuffer, dstBufferSize)) { - if (!m_filter) - { - if (m_format == HdFormatFloat32) { - auto srcData = reinterpret_cast(getBuffer); - auto dstData = reinterpret_cast(dstBuffer); - for (size_t i = 0; i < dstBufferSize / sizeof(GfVec4f); ++i) { - dstData[i] = srcData[i][0]; - } - } - if (m_format == HdFormatInt32) { - auto srcData = reinterpret_cast(getBuffer); - auto dstData = reinterpret_cast(dstBuffer); - for (size_t i = 0; i < dstBufferSize / sizeof(float); ++i) - { - if (i % 4 == 3) - { - dstData[i] = 0; - } - else - { - dstData[i] = (char)(srcData[i] * 255 + 0.5f); - } - } - - auto primIdData = reinterpret_cast(dstBuffer); - for (size_t i = 0; i < dstBufferSize / sizeof(GfVec4f); ++i) - { - primIdData[i] -= 1; - } - } - } - else if (m_format == HdFormatInt32) { - // RPR store integer ID values to RGB images using such formula: - // c[i].x = i; - // c[i].y = i/256; - // c[i].z = i/(256*256); - // i.e. saving little endian int24 to uchar3 - // That's why we interpret the value as int and filling the alpha channel with zeros - auto primIdData = reinterpret_cast(dstBuffer); - for (size_t i = 0; i < dstBufferSize / sizeof(int); ++i) { - primIdData[i] = (primIdData[i] & 0xFFFFFF) - 1; - } - } - - return true; - } - - return false; + return GetDataImpl(dstBuffer, dstBufferSize); } void HdRprApiAov::Resize(int width, int height, HdFormat format) { @@ -224,44 +109,77 @@ void HdRprApiAov::Resize(int width, int height, HdFormat format) { if (m_resolved && m_resolved->Resize(width, height)) { m_dirtyBits |= ChangeTracker::DirtyFormat; } + + UpdateTempBufferSize(width, height, format); +} + +void HdRprApiAov::Update(HdRprApi const* rprApi) { + if (m_requiredTempBufferSize != m_tmpBuffer.size()) { + if (m_requiredTempBufferSize > 0) { + m_tmpBuffer.resize(m_requiredTempBufferSize); + } + else { + m_tmpBuffer.clear(); + } + } + UpdateImpl(rprApi); } -void HdRprApiAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { +void HdRprApiAov::UpdateImpl(HdRprApi const* rprApi) { if (m_dirtyBits & ChangeTracker::DirtyFormat) { - OnFormatChange(rifContext); + m_filterEnabled = (m_format != HdFormatFloat32Vec4); + if (m_filterEnabled) { + m_dirtyBits |= ChangeTracker::DirtySize; + } } if (m_dirtyBits & ChangeTracker::DirtySize) { - OnSizeChange(rifContext); + if (m_filterEnabled) { + auto fbDesc = m_aov->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); + } + } } m_dirtyBits = ChangeTracker::Clean; - - if (m_filter) { - m_filter->Update(); - } } HdRprApiFramebuffer* HdRprApiAov::GetResolvedFb() { return (m_resolved ? m_resolved : m_aov).get(); } -void HdRprApiAov::OnFormatChange(rif::Context* rifContext) { - m_filter = nullptr; - if (rifContext && m_format != HdFormatFloat32Vec4) { - m_filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_RESAMPLE, rifContext); - m_filter->SetParam("interpOperator", (int)RIF_IMAGE_INTERPOLATION_NEAREST); - - // Reset inputs +void HdRprApiAov::UpdateTempBufferSize(int width, int height, HdFormat format) { + switch (m_format) + { + case HdFormatFloat32: m_requiredTempBufferSize = width * height * sizeof(float); break; + case HdFormatInt32: m_filterEnabled ? m_requiredTempBufferSize = width * height * sizeof(int32_t) : 0; break; // when m_filterEnabled is true inplace conversion is used + case HdFormatFloat32Vec3: m_requiredTempBufferSize = width * height * sizeof(float) * 3; break; + case HdFormatFloat32Vec4: m_requiredTempBufferSize = 0; break; // conversion is not needed + default: 0; break; // pass data as is + } + if (m_requiredTempBufferSize != m_outputBuffer.size()) { m_dirtyBits |= ChangeTracker::DirtySize; } } -void HdRprApiAov::OnSizeChange(rif::Context* rifContext) { - if (m_filter) { - auto fbDesc = m_aov->GetDesc(); - m_filter->Resize(fbDesc.fb_width, fbDesc.fb_height); - m_filter->SetInput(rif::Color, GetResolvedFb()); - m_filter->SetOutput(rif::Image::GetDesc(fbDesc.fb_width, fbDesc.fb_height, m_format)); - m_filter->SetParam("outSize", GfVec2i(fbDesc.fb_width, fbDesc.fb_height)); +void HdRprApiAov::UpdateTempBuffer() { + if (m_requiredTempBufferSize == 0) { + return; + } + + if (!m_filterEnabled) + { + if (m_format == HdFormatFloat32) { + CpuVec4toFloatFilter((GfVec4f*)m_outputBuffer.data(), (float*)m_tmpBuffer.data(), m_tmpBuffer.size() / sizeof(float)); + } + else if (m_format == HdFormatInt32) { + CpuVec4toInt32Filter((GfVec4f*)m_outputBuffer.data(), (int32_t*)m_tmpBuffer.data(), m_tmpBuffer.size() / sizeof(int32_t)); + } + else if (m_format == HdFormatFloat32Vec3) { + CpuVec4toVec3Filter((GfVec4f*)m_outputBuffer.data(), (GfVec3f*)m_tmpBuffer.data(), m_outputBuffer.size() / 4); + } + } + else if (m_format == HdFormatInt32) { + CpuFloatToInt32Filter(m_outputBuffer.data(), (int32_t*)m_outputBuffer.data(), m_outputBuffer.size()); } } @@ -296,24 +214,7 @@ void HdRprApiColorAov::SetTonemap(TonemapParams const& params) { bool tonemapEnableDirty = params.enable != isTonemapEnabled; SetFilter(kFilterTonemap, params.enable); - - if (m_tonemap != params) { - m_tonemap = params; - - if (!tonemapEnableDirty && isTonemapEnabled) { - if (m_mainFilterType == kFilterTonemap) { - SetTonemapFilterParams(m_filter.get()); - } - else { - for (auto& entry : m_auxFilters) { - if (entry.first == kFilterTonemap) { - SetTonemapFilterParams(entry.second.get()); - break; - } - } - } - } - } + m_tonemap = params; } void HdRprApiColorAov::SetGamma(GammaParams const& params) { @@ -321,31 +222,7 @@ void HdRprApiColorAov::SetGamma(GammaParams const& params) { bool gammaEnableDirty = params.enable != isGammaEnabled; SetFilter(kFilterGamma, params.enable); - - if (m_gamma != params) { - m_gamma = params; - - if (!gammaEnableDirty && isGammaEnabled) { - if (m_mainFilterType == kFilterGamma) { - m_filter.get()->SetParam("gamma", m_gamma.value); - } - else { - for (auto& entry : m_auxFilters) { - if (entry.first == kFilterGamma) { - entry.second.get()->SetParam("gamma", m_gamma.value); - break; - } - } - } - } - } -} - -void HdRprApiColorAov::SetTonemapFilterParams(rif::Filter* filter) { - filter->SetParam("exposureTime", m_tonemap.exposureTime); - filter->SetParam("sensitivity", m_tonemap.sensitivity); - filter->SetParam("fstop", m_tonemap.fstop); - filter->SetParam("gamma", m_tonemap.gamma); + m_gamma = params; } bool HdRprApiColorAov::CanComposeAlpha() { @@ -363,400 +240,178 @@ void HdRprApiColorAov::Resize(int width, int height, HdFormat format) { HdRprApiAov::Resize(width, height, format); } -void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { +void HdRprApiColorAov::UpdateImpl(HdRprApi const* rprApi) { if (m_dirtyBits & ChangeTracker::DirtyFormat) { - OnFormatChange(rifContext); + OnFormatChange(); } if (m_isEnabledFiltersDirty) { m_isEnabledFiltersDirty = false; - if (!rifContext && m_enabledFilters != kFilterNone) { - TF_WARN("Can not enable %#x filters: rifContext required", m_enabledFilters); - m_enabledFilters = kFilterNone; - } + m_dirtyBits |= ChangeTracker::DirtySize; + } - // Reuse the previously created filters - std::vector>> filterPool = std::move(m_auxFilters); - if (m_filter) { - filterPool.emplace_back(m_mainFilterType, std::move(m_filter)); + if (m_dirtyBits & ChangeTracker::DirtySize) { + auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); } - - if ((m_enabledFilters & kFilterComposeOpacity) || - (m_enabledFilters & kFilterTonemap) || - (m_enabledFilters & kFilterGamma)) { - - auto addFilter = [this, &filterPool](Filter type, std::function()> filterCreator) { - std::unique_ptr filter; - - auto it = std::find_if(filterPool.begin(), filterPool.end(), [type](auto& entry) { return type == entry.first; }); - if (it != filterPool.end()) { - filter = std::move(it->second); - } - else { - filter = filterCreator(); - } - - if (m_filter) { - m_auxFilters.emplace_back(m_mainFilterType, std::move(m_filter)); - } - - m_filter = std::move(filter); - m_mainFilterType = type; - }; - - if (m_enabledFilters & kFilterTonemap) { - addFilter(kFilterTonemap, - [rifContext]() { - return rif::Filter::CreateCustom(RIF_IMAGE_FILTER_PHOTO_LINEAR_TONEMAP, rifContext); - } - ); - } - - if (m_enabledFilters & kFilterGamma) { - addFilter(kFilterGamma, - [rifContext]() { - return rif::Filter::CreateCustom(RIF_IMAGE_FILTER_GAMMA_CORRECTION, rifContext); - } - ); - } - - if (m_enabledFilters & kFilterComposeOpacity) { - addFilter(kFilterComposeOpacity, - [rifContext]() { - auto filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_USER_DEFINED, rifContext); - auto opacityComposingKernelCode = std::string(R"( - int2 coord; - GET_COORD_OR_RETURN(coord, GET_BUFFER_SIZE(inputImage)); - vec4 alpha = ReadPixelTyped(alphaImage, coord.x, coord.y); - vec4 color = ReadPixelTyped(inputImage, coord.x, coord.y) * alpha.x; - WritePixelTyped(outputImage, coord.x, coord.y, make_vec4(color.x, color.y, color.z, alpha.x)); - )"); - filter->SetParam("code", opacityComposingKernelCode); - return filter; - } - ); + if (m_enabledFilters & kFilterComposeOpacity) { + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_opacityBuffer.size()) { + m_opacityBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); } } - else if (m_enabledFilters & kFilterResample) { - m_filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_RESAMPLE, rifContext); - m_filter->SetParam("interpOperator", (int)RIF_IMAGE_INTERPOLATION_NEAREST); - m_mainFilterType = kFilterResample; + else { + m_opacityBuffer.clear(); } - - // Signal to update inputs - m_dirtyBits |= ChangeTracker::DirtySize; - } - - if (m_dirtyBits & ChangeTracker::DirtySize) { - OnSizeChange(rifContext); } m_dirtyBits = ChangeTracker::Clean; +} - for (auto& auxFilter : m_auxFilters) { - auxFilter.second->Update(); - } - if (m_filter) { - m_filter->Update(); +void HdRprApiColorAov::ResolveImpl() { + auto resolvedFb = m_retainedRawColor->GetResolvedFb(); + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { + return; } -} -bool HdRprApiColorAov::GetData(void* dstBuffer, size_t dstBufferSize) { - if (!m_filter) { - if (auto resolvedRawColorFb = m_retainedRawColor->GetResolvedFb()) { - return resolvedRawColorFb->GetData(dstBuffer, dstBufferSize); + size_t numPixels = m_outputBuffer.size() / 4; + if ((m_enabledFilters & kFilterComposeOpacity) || + (m_enabledFilters & kFilterTonemap) || + (m_enabledFilters & kFilterGamma)) { + + if (m_enabledFilters & kFilterTonemap) { + CpuTonemap((GfVec4f*)m_outputBuffer.data(), numPixels, m_tonemap.gamma, m_tonemap.exposureTime, m_tonemap.sensitivity, m_tonemap.fstop); } - else { - return false; + if (m_enabledFilters & kFilterGamma) { + CpuGammaCorrection((GfVec4f*)m_outputBuffer.data(), numPixels, m_gamma.value); } - } - else { - return HdRprApiAov::GetData(dstBuffer, dstBufferSize); - } -} - -void HdRprApiColorAov::Resolve() { - HdRprApiAov::Resolve(); + if (m_enabledFilters & kFilterComposeOpacity) { + auto resolvedOpFb = m_retainedOpacity->GetResolvedFb(); + if (!resolvedOpFb || !resolvedOpFb->GetData(m_opacityBuffer.data(), m_opacityBuffer.size() * sizeof(float))) { + return; + } - for (auto& auxFilter : m_auxFilters) { - auxFilter.second->Resolve(); + CpuOpacityFilter((GfVec4f*)m_opacityBuffer.data(), (GfVec4f*)m_outputBuffer.data(), numPixels); + } + } + else if (m_enabledFilters & kFilterResample) { + auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); + CpuResampleNearest((GfVec4f*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height, (GfVec4f*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height); } } -void HdRprApiColorAov::OnFormatChange(rif::Context* rifContext) { +void HdRprApiColorAov::OnFormatChange() { SetFilter(kFilterResample, m_format != HdFormatFloat32Vec4); SetFilter(kFilterComposeOpacity, CanComposeAlpha()); m_dirtyBits |= ChangeTracker::DirtySize; } -template -void HdRprApiColorAov::ResizeFilter(int width, int height, Filter filterType, rif::Filter* filter, T input) { - filter->Resize(width, height); - filter->SetInput(rif::Color, input); - filter->SetOutput(rif::Image::GetDesc(width, height, m_format)); - - if (filterType == kFilterComposeOpacity) { - filter->SetInput("alphaImage", m_retainedOpacity->GetResolvedFb()); - } - else if (filterType == kFilterResample) { - filter->SetParam("outSize", GfVec2i(width, height)); - } - else if (filterType == kFilterTonemap) { - SetTonemapFilterParams(filter); - } - else if (filterType == kFilterGamma) { - filter->SetParam("gamma", m_gamma.value); - } +HdRprApiNormalAov::HdRprApiNormalAov( + int width, int height, HdFormat format, + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) + : HdRprApiAov(RPR_AOV_SHADING_NORMAL, width, height, format, rprContext, rprContextMetadata) { } -void HdRprApiColorAov::OnSizeChange(rif::Context* rifContext) { - if (!m_filter) { - return; - } - - auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); - if (m_auxFilters.empty()) { - ResizeFilter(fbDesc.fb_width, fbDesc.fb_height, m_mainFilterType, m_filter.get(), m_retainedRawColor->GetResolvedFb()); - } - else { - // Ideally we would use "Filter combining" functionality, but it does not work with user-defined filter - // So we attach each filter separately - - auto filter = m_auxFilters.front().second.get(); - ResizeFilter(fbDesc.fb_width, fbDesc.fb_height, m_auxFilters.front().first, filter, m_retainedRawColor->GetResolvedFb()); - for (int i = 1; i < m_auxFilters.size(); ++i) { - auto filterInput = m_auxFilters[i - 1].second->GetOutput(); - ResizeFilter(fbDesc.fb_width, fbDesc.fb_height, m_auxFilters[i].first, m_auxFilters[i].second.get(), filterInput); +void HdRprApiNormalAov::UpdateImpl(HdRprApi const* rprApi) { + if (m_dirtyBits & ChangeTracker::DirtySize) { + auto fbDesc = m_aov->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 3 != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); } - ResizeFilter(fbDesc.fb_width, fbDesc.fb_height, m_mainFilterType, m_filter.get(), m_auxFilters.back().second->GetOutput()); } + m_dirtyBits = ChangeTracker::Clean; } -HdRprApiNormalAov::HdRprApiNormalAov( - int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext) - : HdRprApiAov(RPR_AOV_SHADING_NORMAL, width, height, format, rprContext, rprContextMetadata, rif::Filter::CreateCustom(RIF_IMAGE_FILTER_REMAP_RANGE, rifContext)) { - if (!rifContext) { - RPR_THROW_ERROR_MSG("Can not create normal AOV: RIF context required"); +void HdRprApiNormalAov::ResolveImpl() { + auto resolvedFb = GetResolvedFb(); + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { + return; } - m_filter->SetParam("srcRangeAuto", 0); - m_filter->SetParam("dstLo", -1.0f); - m_filter->SetParam("dstHi", 1.0f); -} - -void HdRprApiNormalAov::OnFormatChange(rif::Context* rifContext) { - m_dirtyBits |= ChangeTracker::DirtySize; -} - -void HdRprApiNormalAov::OnSizeChange(rif::Context* rifContext) { - auto fbDesc = m_aov->GetDesc(); - m_filter->Resize(fbDesc.fb_width, fbDesc.fb_height); - m_filter->SetInput(rif::Color, GetResolvedFb()); - m_filter->SetOutput(rif::Image::GetDesc(fbDesc.fb_width, fbDesc.fb_height, m_format)); + size_t numPixels = m_outputBuffer.size() / 4; + CpuRemapFilter(m_outputBuffer.data(), m_outputBuffer.data(), numPixels * 4, 0.0, 1.0, -1.0, 1.0); } void HdRprApiComputedAov::Resize(int width, int height, HdFormat format) { - if (m_format != format) { - m_format = format; - m_dirtyBits |= ChangeTracker::DirtyFormat; - } - if (m_width != width || m_height != height) { m_width = width; m_height = height; m_dirtyBits |= ChangeTracker::DirtySize; } + + HdRprApiAov::Resize(width, height, format); } -HdRprApiDepthAov::HdRprApiDepthAov( - int width, int height, HdFormat format, +HdRprApiDepthAov::HdRprApiDepthAov(int width, int height, HdFormat format, std::shared_ptr worldCoordinateAov, std::shared_ptr opacityAov, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext) + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) : HdRprApiComputedAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kNdcDepth), true), width, height, format) , m_retainedWorldCoordinateAov(worldCoordinateAov) - , m_retainedOpacityAov(opacityAov) { - - if (!rifContext) { - RPR_THROW_ERROR_MSG("Can not create depth AOV: RIF context required"); - } - - m_retainedNDCFilter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_NDC_DEPTH, rifContext); - m_ndcFilter = m_retainedNDCFilter.get(); - - m_filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_USER_DEFINED, rifContext); - - auto opacityComposingKernelCode = std::string(R"( - int2 coord; - GET_COORD_OR_RETURN(coord, GET_BUFFER_SIZE(inputImage)); - vec4 alpha = ReadPixelTyped(alphaImage, coord.x, coord.y); - vec4 color = ReadPixelTyped(inputImage, coord.x, coord.y); - if (alpha.x == 0) { - color = make_vec4(1.f, 1.f, 1.f, 1.f); - } - WritePixelTyped(outputImage, coord.x, coord.y, color); - )"); - m_filter->SetParam("code", opacityComposingKernelCode); - m_opacityFilter = m_filter.get(); - m_remapFilter = nullptr; - -#if PXR_VERSION >= 2002 - m_retainedOpacityFilter = std::move(m_filter); - - m_filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_REMAP_RANGE, rifContext); - m_filter->SetParam("srcRangeAuto", 0); - m_filter->SetParam("srcLo", -1.0f); - m_filter->SetParam("srcHi", 1.0f); - m_filter->SetParam("dstLo", 0.0f); - m_filter->SetParam("dstHi", 1.0f); - m_remapFilter = m_filter.get(); -#endif -} - -void HdRprApiDepthAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { - if (m_dirtyBits & ChangeTracker::DirtyFormat || - m_dirtyBits & ChangeTracker::DirtySize) { - - m_ndcFilter->SetInput(rif::Color, m_retainedWorldCoordinateAov->GetResolvedFb()); - m_ndcFilter->SetOutput(rif::Image::GetDesc(m_width, m_height, m_format)); - m_opacityFilter->SetInput(rif::Color, m_ndcFilter->GetOutput()); - m_opacityFilter->SetInput("alphaImage", m_retainedOpacityAov->GetResolvedFb()); - m_opacityFilter->SetOutput(rif::Image::GetDesc(m_width, m_height, m_format)); - if (m_remapFilter) { - m_remapFilter->SetInput(rif::Color, m_opacityFilter->GetOutput()); - m_remapFilter->SetOutput(rif::Image::GetDesc(m_width, m_height, m_format)); - } - } - m_dirtyBits = ChangeTracker::Clean; - auto viewProjectionMatrix = rprApi->GetCameraViewMatrix() * rprApi->GetCameraProjectionMatrix(); - m_ndcFilter->SetParam("viewProjMatrix", GfMatrix4f(viewProjectionMatrix.GetTranspose())); + , m_retainedOpacityAov(opacityAov) + , m_viewProjectionMatrix(GfMatrix4f()) { + // m_cpuFilterBuffer.resize(cpuFilterBufferSize()); +} - m_ndcFilter->Update(); - m_opacityFilter->Update(); - if (m_remapFilter) { - m_remapFilter->Update(); +void HdRprApiDepthAov::UpdateImpl(HdRprApi const* rprApi) { + m_viewProjectionMatrix = GfMatrix4f(rprApi->GetCameraViewMatrix() * rprApi->GetCameraProjectionMatrix()).GetTranspose(); + if (m_dirtyBits & ChangeTracker::DirtySize) { + auto fbDesc = m_retainedWorldCoordinateAov->GetAovFb()->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_cpuFilterBuffer.size()) { + m_cpuFilterBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); + } + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); + } } + m_dirtyBits = ChangeTracker::Clean; } -void HdRprApiDepthAov::Resolve() { - if (m_ndcFilter) { - m_ndcFilter->Resolve(); - } - if (m_opacityFilter) { - m_opacityFilter->Resolve(); +void HdRprApiDepthAov::ResolveImpl() { + static size_t numPixels = m_cpuFilterBuffer.size() / 4; + + auto coordinateFb = m_retainedWorldCoordinateAov->GetResolvedFb(); + if (!coordinateFb || !coordinateFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { + return; } - if (m_remapFilter) { - m_remapFilter->Resolve(); + + CpuNdcFilter((GfVec4f*)m_outputBuffer.data(), (GfVec4f*)m_outputBuffer.data(), numPixels, m_viewProjectionMatrix); + + auto opacityFb = m_retainedOpacityAov->GetResolvedFb(); + if (!opacityFb || !opacityFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { + return; } + + CpuOpacityMaskFilter((GfVec4f*)m_cpuFilterBuffer.data(), (GfVec4f*)m_outputBuffer.data(), numPixels); + CpuRemapFilter(m_outputBuffer.data(), m_outputBuffer.data(), numPixels * 4, -1, 1, 0, 1.0f); } HdRprApiIdMaskAov::HdRprApiIdMaskAov( HdRprAovDescriptor const& aovDescriptor, std::shared_ptr const& baseIdAov, int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext) + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) : HdRprApiComputedAov(aovDescriptor, width, height, format) , m_baseIdAov(baseIdAov) { - if (!rifContext) { - RPR_THROW_ERROR_MSG("Can not create id mask AOV: RIF context required"); - } - - m_filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_USER_DEFINED, rifContext); - auto colorizeIdKernelCode = std::string(R"( - int2 coord; - GET_COORD_OR_RETURN(coord, GET_BUFFER_SIZE(inputImage)); - vec3 idEncoded = ReadPixelTyped(inputImage, coord.x, coord.y).xyz; - unsigned int idDecoded = (unsigned int)(idEncoded.x*256) + (unsigned int)(idEncoded.y*256*256) + (unsigned int)(idEncoded.z*256*256*256); - - vec4 color; - if (idDecoded) { - unsigned int v0 = 0x123; - unsigned int v1 = idDecoded; - unsigned int s0 = 0; - const unsigned int N = 4; - for( unsigned int n = 0; n < N; n++ ) { - s0 += 0x9e3779b9; - v0 += ((v1<<4)+0xa341316c)^(v1+s0)^((v1>>5)+0xc8013ea4); - v1 += ((v0<<4)+0xad90777d)^(v0+s0)^((v0>>5)+0x7e95761e); - } - color = make_vec4(v0&0xFFFF, v0>>16, v1&0xFFFF, 0xFFFF)/(float)(0xFFFF); - } else { - color = make_vec4(0.0f, 0.0f, 0.0f, 0.0f); - } - - WritePixelTyped(outputImage, coord.x, coord.y, color); - )"); - m_filter->SetParam("code", colorizeIdKernelCode); } -void HdRprApiIdMaskAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { - if (m_dirtyBits & ChangeTracker::DirtyFormat || - m_dirtyBits & ChangeTracker::DirtySize) { - m_filter->SetInput(rif::Color, m_baseIdAov->GetResolvedFb()); - m_filter->SetOutput(rif::Image::GetDesc(m_width, m_height, m_format)); +void HdRprApiIdMaskAov::UpdateImpl(HdRprApi const* rprApi) { + if (m_dirtyBits & ChangeTracker::DirtySize) { + auto fbDesc = m_baseIdAov->GetAovFb()->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); + } } m_dirtyBits = ChangeTracker::Clean; - - if (m_filter) { - m_filter->Update(); - } } -HdRprApiScCompositeAOV::HdRprApiScCompositeAOV(int width, int height, HdFormat format, - std::shared_ptr rawColorAov, - std::shared_ptr opacityAov, - std::shared_ptr scAov, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext) - : HdRprApiAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kScTransparentBackground), true), format) - , m_retainedRawColorAov(rawColorAov) - , m_retainedOpacityAov(opacityAov) - , m_retainedScAov(scAov) -{ -} - -bool HdRprApiScCompositeAOV::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { - if (m_tempColorBuffer.size() < dstBufferSize / sizeof(GfVec4f)) { - m_tempColorBuffer.resize(dstBufferSize / sizeof(GfVec4f)); - } - if (m_tempOpacityBuffer.size() < dstBufferSize / sizeof(GfVec4f)) { - m_tempOpacityBuffer.resize(dstBufferSize / sizeof(GfVec4f)); - } - if (m_tempScBuffer.size() < dstBufferSize / sizeof(GfVec4f)) { - m_tempScBuffer.resize(dstBufferSize / sizeof(GfVec4f)); - } - - if (!m_retainedRawColorAov->GetDataImpl((void*)m_tempColorBuffer.data(), dstBufferSize)) { - return false; - } - if (!m_retainedOpacityAov->GetDataImpl((void*)m_tempOpacityBuffer.data(), dstBufferSize)) { - return false; - } - if (!m_retainedScAov->GetDataImpl((void*)m_tempScBuffer.data(), dstBufferSize)) { - return false; - } - - auto dstValue = reinterpret_cast(dstBuffer); - - // On this stage format is always HdFormatFloat32Vec4 -#pragma omp parallel for - for (int i = 0; i < dstBufferSize / sizeof(GfVec4f); i++) - { - float opacity = m_tempOpacityBuffer[i][0]; - float sc = m_tempScBuffer[i][0]; - constexpr float OneMinusEpsilon = 1.0f - 1e-5f; - - if (opacity > OneMinusEpsilon) - { - dstValue[i] = { m_tempColorBuffer[i][0], m_tempColorBuffer[i][1], m_tempColorBuffer[i][2], opacity }; - } - else - { - // Add shadows from the shadow catcher to the final image + Make the background transparent; - dstValue[i] = { 0.0f, 0.0f, 0.0f, sc }; - } +void HdRprApiIdMaskAov::ResolveImpl() { + auto resolvedFb = m_baseIdAov->GetResolvedFb(); + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { + return; } - return true; + size_t numPixels = m_outputBuffer.size() / 4; + CpuFillMaskFilter((GfVec4f*)m_outputBuffer.data(), numPixels); } PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index dc17d7ab3..28010571a 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -16,7 +16,6 @@ limitations under the License. #include "aovDescriptor.h" #include "rprApiFramebuffer.h" -#include "rifcpp/rifFilter.h" #include "pxr/base/gf/matrix4f.h" #include "pxr/imaging/hd/types.h" @@ -28,14 +27,12 @@ struct RprUsdContextMetadata; class HdRprApiAov { public: HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, std::unique_ptr filter); - HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata); virtual ~HdRprApiAov() = default; virtual void Resize(int width, int height, HdFormat format); - virtual void Update(HdRprApi const* rprApi, rif::Context* rifContext); - virtual void Resolve(); + void Update(HdRprApi const* rprApi); + void Resolve(); virtual bool GetData(void* dstBuffer, size_t dstBufferSize); void Clear(); @@ -43,24 +40,18 @@ class HdRprApiAov { HdFormat GetFormat() const { return m_format; } HdRprAovDescriptor const& GetDesc() const { return m_aovDescriptor; } - HdRprApiFramebuffer* GetAovFb() { return m_aov.get(); }; + HdRprApiFramebuffer* GetAovFb() { return m_aov.get(); } HdRprApiFramebuffer* GetResolvedFb(); - - virtual bool GetDataImpl(void* dstBuffer, size_t dstBufferSize); protected: HdRprApiAov(HdRprAovDescriptor const& aovDescriptor, HdFormat format) : m_aovDescriptor(aovDescriptor), m_format(format) {}; - - virtual void OnFormatChange(rif::Context* rifContext); - virtual void OnSizeChange(rif::Context* rifContext); + virtual void UpdateImpl(HdRprApi const* rprApi); + virtual void ResolveImpl(); protected: - HdRprAovDescriptor const& m_aovDescriptor; HdFormat m_format; std::unique_ptr m_aov; - std::unique_ptr m_resolved; - std::unique_ptr m_filter; - std::vector m_tmpBuffer; + std::vector m_outputBuffer; enum ChangeTracker { Clean = 0, @@ -69,6 +60,16 @@ class HdRprApiAov { DirtyFormat = 1 << 1, }; uint32_t m_dirtyBits = AllDirty; +private: + bool GetDataImpl(void* dstBuffer, size_t dstBufferSize); + void UpdateTempBufferSize(int width, int height, HdFormat format); + void UpdateTempBuffer(); + + HdRprAovDescriptor const& m_aovDescriptor; + bool m_filterEnabled = false; + size_t m_requiredTempBufferSize = 0; + std::vector m_tmpBuffer; + std::unique_ptr m_resolved; }; class HdRprApiColorAov : public HdRprApiAov { @@ -77,9 +78,6 @@ class HdRprApiColorAov : public HdRprApiAov { ~HdRprApiColorAov() override = default; void Resize(int width, int height, HdFormat format) override; - void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; - bool GetData(void* dstBuffer, size_t dstBufferSize) override; - void Resolve() override; void SetOpacityAov(std::shared_ptr opacity); @@ -114,36 +112,25 @@ class HdRprApiColorAov : public HdRprApiAov { } }; void SetGamma(GammaParams const& params); - protected: - void OnFormatChange(rif::Context* rifContext) override; - void OnSizeChange(rif::Context* rifContext) override; + void UpdateImpl(HdRprApi const* rprApi); + void ResolveImpl() override; private: + void OnFormatChange(); + enum Filter { kFilterNone = 0, kFilterResample = 1 << 0, - //kFilterAIDenoise = 1 << 1, - //kFilterEAWDenoise = 1 << 2, kFilterComposeOpacity = 1 << 3, kFilterTonemap = 1 << 4, kFilterGamma = 1 << 5 }; void SetFilter(Filter filter, bool enable); - - template - void ResizeFilter(int width, int height, Filter filterType, rif::Filter* filter, T input); - - void SetTonemapFilterParams(rif::Filter* filter); - bool CanComposeAlpha(); - private: std::shared_ptr m_retainedRawColor; std::shared_ptr m_retainedOpacity; - Filter m_mainFilterType = kFilterNone; - std::vector>> m_auxFilters; - uint32_t m_enabledFilters = kFilterNone; bool m_isEnabledFiltersDirty = true; @@ -152,16 +139,20 @@ class HdRprApiColorAov : public HdRprApiAov { int m_width = 0; int m_height = 0; + + std::vector m_opacityBuffer; }; class HdRprApiNormalAov : public HdRprApiAov { public: HdRprApiNormalAov(int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata); ~HdRprApiNormalAov() override = default; protected: - void OnFormatChange(rif::Context* rifContext) override; - void OnSizeChange(rif::Context* rifContext) override; + void UpdateImpl(HdRprApi const* rprApi) override; + void ResolveImpl() override; +private: + //std::vector m_cpuFilterBuffer; }; class HdRprApiComputedAov : public HdRprApiAov { @@ -180,55 +171,34 @@ class HdRprApiComputedAov : public HdRprApiAov { class HdRprApiDepthAov : public HdRprApiComputedAov { public: HdRprApiDepthAov(int width, int height, HdFormat format, - std::shared_ptr worldCoordinateAov, - std::shared_ptr opacityAov, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); + std::shared_ptr worldCoordinateAov, + std::shared_ptr opacityAov, + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata); ~HdRprApiDepthAov() override = default; - - void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; - void Resolve() override; - +protected: + void UpdateImpl(HdRprApi const* rprApi) override; + void ResolveImpl() override; private: - std::unique_ptr m_retainedNDCFilter; - std::unique_ptr m_retainedOpacityFilter; - - rif::Filter* m_ndcFilter; - rif::Filter* m_opacityFilter; - rif::Filter* m_remapFilter; + inline size_t cpuFilterBufferSize() const { return m_width * m_height * 4; } // Vec4f for each pixel std::shared_ptr m_retainedWorldCoordinateAov; std::shared_ptr m_retainedOpacityAov; + GfMatrix4f m_viewProjectionMatrix; + std::vector m_cpuFilterBuffer; }; class HdRprApiIdMaskAov : public HdRprApiComputedAov { public: HdRprApiIdMaskAov(HdRprAovDescriptor const& aovDescriptor, std::shared_ptr const& baseIdAov, - int width, int height, HdFormat format, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); + int width, int height, HdFormat format, + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata); ~HdRprApiIdMaskAov() override = default; - - void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; - +protected: + void UpdateImpl(HdRprApi const* rprApi) override; + void ResolveImpl() override; private: std::shared_ptr m_baseIdAov; -}; - -class HdRprApiScCompositeAOV : public HdRprApiAov { -public: - HdRprApiScCompositeAOV(int width, int height, HdFormat format, - std::shared_ptr rawColorAov, - std::shared_ptr opacityAov, - std::shared_ptr scAov, - rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); - bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; -private: - std::shared_ptr m_retainedRawColorAov; - std::shared_ptr m_retainedOpacityAov; - std::shared_ptr m_retainedScAov; - - std::vector m_tempColorBuffer; - std::vector m_tempOpacityBuffer; - std::vector m_tempScBuffer; + std::vector m_cpuFilterBuffer; }; PXR_NAMESPACE_CLOSE_SCOPE