diff --git a/pxr/imaging/plugin/hdRpr/CMakeLists.txt b/pxr/imaging/plugin/hdRpr/CMakeLists.txt index c36817eeb..aa1a49ea9 100644 --- a/pxr/imaging/plugin/hdRpr/CMakeLists.txt +++ b/pxr/imaging/plugin/hdRpr/CMakeLists.txt @@ -139,6 +139,7 @@ pxr_plugin(hdRpr ${OptIncludeDir} PRIVATE_CLASSES + aovDescriptor rendererPlugin renderDelegate renderPass diff --git a/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp b/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp new file mode 100644 index 000000000..100df0608 --- /dev/null +++ b/pxr/imaging/plugin/hdRpr/aovDescriptor.cpp @@ -0,0 +1,146 @@ +/************************************************************************ +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 "aovDescriptor.h" + +#include "pxr/base/tf/instantiateSingleton.h" + +#include "pxr/imaging/hd/tokens.h" + +PXR_NAMESPACE_OPEN_SCOPE + +const HdRprAovDescriptor kInvalidDesc; + +TF_INSTANTIATE_SINGLETON(HdRprAovRegistry); +TF_DEFINE_PUBLIC_TOKENS(HdRprAovTokens, HDRPR_AOV_TOKENS); + +HdRprAovRegistry::HdRprAovRegistry() { + const auto rprAovMax = RPR_AOV_COLOR_RIGHT + 1; + const GfVec4f idClearValue(255.0f, 255.0f, 255.0f, 0.0f); + + m_aovDescriptors.resize(rprAovMax); + m_aovDescriptors[RPR_AOV_COLOR] = HdRprAovDescriptor(RPR_AOV_COLOR); + m_aovDescriptors[RPR_AOV_DIFFUSE_ALBEDO] = HdRprAovDescriptor(RPR_AOV_DIFFUSE_ALBEDO); // XXX: RPR's albedo can be noisy in some cases, so we left it as multisampled + m_aovDescriptors[RPR_AOV_VARIANCE] = HdRprAovDescriptor(RPR_AOV_VARIANCE); + m_aovDescriptors[RPR_AOV_OPACITY] = HdRprAovDescriptor(RPR_AOV_OPACITY); + m_aovDescriptors[RPR_AOV_EMISSION] = HdRprAovDescriptor(RPR_AOV_EMISSION); + m_aovDescriptors[RPR_AOV_DIRECT_ILLUMINATION] = HdRprAovDescriptor(RPR_AOV_DIRECT_ILLUMINATION); + m_aovDescriptors[RPR_AOV_INDIRECT_ILLUMINATION] = HdRprAovDescriptor(RPR_AOV_INDIRECT_ILLUMINATION); + m_aovDescriptors[RPR_AOV_AO] = HdRprAovDescriptor(RPR_AOV_AO); + m_aovDescriptors[RPR_AOV_DIRECT_DIFFUSE] = HdRprAovDescriptor(RPR_AOV_DIRECT_DIFFUSE); + m_aovDescriptors[RPR_AOV_DIRECT_REFLECT] = HdRprAovDescriptor(RPR_AOV_DIRECT_REFLECT); + m_aovDescriptors[RPR_AOV_INDIRECT_DIFFUSE] = HdRprAovDescriptor(RPR_AOV_INDIRECT_DIFFUSE); + m_aovDescriptors[RPR_AOV_INDIRECT_REFLECT] = HdRprAovDescriptor(RPR_AOV_INDIRECT_REFLECT); + m_aovDescriptors[RPR_AOV_REFRACT] = HdRprAovDescriptor(RPR_AOV_REFRACT); + m_aovDescriptors[RPR_AOV_VOLUME] = HdRprAovDescriptor(RPR_AOV_VOLUME); + m_aovDescriptors[RPR_AOV_LIGHT_GROUP0] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP0); + m_aovDescriptors[RPR_AOV_LIGHT_GROUP1] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP1); + m_aovDescriptors[RPR_AOV_LIGHT_GROUP2] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP2); + m_aovDescriptors[RPR_AOV_LIGHT_GROUP3] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP3); + m_aovDescriptors[RPR_AOV_COLOR_RIGHT] = HdRprAovDescriptor(RPR_AOV_COLOR_RIGHT); + m_aovDescriptors[RPR_AOV_SHADOW_CATCHER] = HdRprAovDescriptor(RPR_AOV_SHADOW_CATCHER); + m_aovDescriptors[RPR_AOV_REFLECTION_CATCHER] = HdRprAovDescriptor(RPR_AOV_REFLECTION_CATCHER); + + m_aovDescriptors[RPR_AOV_DEPTH] = HdRprAovDescriptor(RPR_AOV_DEPTH, false, HdFormatFloat32, GfVec4f(std::numeric_limits::infinity())); + m_aovDescriptors[RPR_AOV_UV] = HdRprAovDescriptor(RPR_AOV_UV, false, HdFormatFloat32Vec3); + m_aovDescriptors[RPR_AOV_SHADING_NORMAL] = HdRprAovDescriptor(RPR_AOV_SHADING_NORMAL, false, HdFormatFloat32Vec3); + m_aovDescriptors[RPR_AOV_GEOMETRIC_NORMAL] = HdRprAovDescriptor(RPR_AOV_GEOMETRIC_NORMAL, false); + m_aovDescriptors[RPR_AOV_OBJECT_ID] = HdRprAovDescriptor(RPR_AOV_OBJECT_ID, false, HdFormatInt32, idClearValue); + m_aovDescriptors[RPR_AOV_MATERIAL_IDX] = HdRprAovDescriptor(RPR_AOV_MATERIAL_IDX, false, HdFormatInt32, idClearValue); + m_aovDescriptors[RPR_AOV_OBJECT_GROUP_ID] = HdRprAovDescriptor(RPR_AOV_OBJECT_GROUP_ID, false, HdFormatInt32, idClearValue); + m_aovDescriptors[RPR_AOV_WORLD_COORDINATE] = HdRprAovDescriptor(RPR_AOV_WORLD_COORDINATE, false); + m_aovDescriptors[RPR_AOV_BACKGROUND] = HdRprAovDescriptor(RPR_AOV_BACKGROUND, false); + m_aovDescriptors[RPR_AOV_VELOCITY] = HdRprAovDescriptor(RPR_AOV_VELOCITY, false); + m_aovDescriptors[RPR_AOV_VIEW_SHADING_NORMAL] = HdRprAovDescriptor(RPR_AOV_VIEW_SHADING_NORMAL, false); + + m_computedAovDescriptors.resize(kComputedAovsCount); + m_computedAovDescriptors[kNdcDepth] = HdRprAovDescriptor(kNdcDepth, false, HdFormatFloat32, GfVec4f(std::numeric_limits::infinity()), true); + m_computedAovDescriptors[kColorAlpha] = HdRprAovDescriptor(kColorAlpha); + + auto addAovNameLookup = [this](TfToken const& name, HdRprAovDescriptor const& descriptor) { + auto status = m_aovNameLookup.emplace(name, AovNameLookupValue(descriptor.id, descriptor.computed)); + if (!status.second) { + TF_CODING_ERROR("AOV lookup name should be unique"); + } + }; + + addAovNameLookup(HdAovTokens->color, m_computedAovDescriptors[kColorAlpha]); + addAovNameLookup(HdAovTokens->normal, m_aovDescriptors[RPR_AOV_SHADING_NORMAL]); + addAovNameLookup(HdAovTokens->primId, m_aovDescriptors[RPR_AOV_OBJECT_ID]); + addAovNameLookup(HdAovTokens->Neye, m_aovDescriptors[RPR_AOV_VIEW_SHADING_NORMAL]); + addAovNameLookup(HdAovTokens->depth, m_computedAovDescriptors[kNdcDepth]); + addAovNameLookup(HdRprGetCameraDepthAovName(), m_aovDescriptors[RPR_AOV_DEPTH]); + + addAovNameLookup(HdRprAovTokens->rawColor, m_aovDescriptors[RPR_AOV_COLOR]); + addAovNameLookup(HdRprAovTokens->albedo, m_aovDescriptors[RPR_AOV_DIFFUSE_ALBEDO]); + addAovNameLookup(HdRprAovTokens->variance, m_aovDescriptors[RPR_AOV_VARIANCE]); + addAovNameLookup(HdRprAovTokens->opacity, m_aovDescriptors[RPR_AOV_OPACITY]); + addAovNameLookup(HdRprAovTokens->emission, m_aovDescriptors[RPR_AOV_EMISSION]); + addAovNameLookup(HdRprAovTokens->directIllumination, m_aovDescriptors[RPR_AOV_DIRECT_ILLUMINATION]); + addAovNameLookup(HdRprAovTokens->indirectIllumination, m_aovDescriptors[RPR_AOV_INDIRECT_ILLUMINATION]); + addAovNameLookup(HdRprAovTokens->ao, m_aovDescriptors[RPR_AOV_AO]); + addAovNameLookup(HdRprAovTokens->directDiffuse, m_aovDescriptors[RPR_AOV_DIRECT_DIFFUSE]); + addAovNameLookup(HdRprAovTokens->directReflect, m_aovDescriptors[RPR_AOV_DIRECT_REFLECT]); + addAovNameLookup(HdRprAovTokens->indirectDiffuse, m_aovDescriptors[RPR_AOV_INDIRECT_DIFFUSE]); + addAovNameLookup(HdRprAovTokens->indirectReflect, m_aovDescriptors[RPR_AOV_INDIRECT_REFLECT]); + addAovNameLookup(HdRprAovTokens->refract, m_aovDescriptors[RPR_AOV_REFRACT]); + addAovNameLookup(HdRprAovTokens->volume, m_aovDescriptors[RPR_AOV_VOLUME]); + addAovNameLookup(HdRprAovTokens->lightGroup0, m_aovDescriptors[RPR_AOV_LIGHT_GROUP0]); + addAovNameLookup(HdRprAovTokens->lightGroup1, m_aovDescriptors[RPR_AOV_LIGHT_GROUP1]); + addAovNameLookup(HdRprAovTokens->lightGroup2, m_aovDescriptors[RPR_AOV_LIGHT_GROUP2]); + addAovNameLookup(HdRprAovTokens->lightGroup3, m_aovDescriptors[RPR_AOV_LIGHT_GROUP3]); + addAovNameLookup(HdRprAovTokens->colorRight, m_aovDescriptors[RPR_AOV_COLOR_RIGHT]); + addAovNameLookup(HdRprAovTokens->materialIdx, m_aovDescriptors[RPR_AOV_MATERIAL_IDX]); + addAovNameLookup(HdRprAovTokens->objectGroupId, m_aovDescriptors[RPR_AOV_OBJECT_GROUP_ID]); + addAovNameLookup(HdRprAovTokens->geometricNormal, m_aovDescriptors[RPR_AOV_GEOMETRIC_NORMAL]); + addAovNameLookup(HdRprAovTokens->worldCoordinate, m_aovDescriptors[RPR_AOV_WORLD_COORDINATE]); + addAovNameLookup(HdRprAovTokens->primvarsSt, m_aovDescriptors[RPR_AOV_UV]); + addAovNameLookup(HdRprAovTokens->shadowCatcher, m_aovDescriptors[RPR_AOV_SHADOW_CATCHER]); + addAovNameLookup(HdRprAovTokens->reflectionCatcher, m_aovDescriptors[RPR_AOV_REFLECTION_CATCHER]); + addAovNameLookup(HdRprAovTokens->background, m_aovDescriptors[RPR_AOV_BACKGROUND]); + addAovNameLookup(HdRprAovTokens->velocity, m_aovDescriptors[RPR_AOV_VELOCITY]); + addAovNameLookup(HdRprAovTokens->viewShadingNormal, m_aovDescriptors[RPR_AOV_VIEW_SHADING_NORMAL]); +} + +HdRprAovDescriptor const& HdRprAovRegistry::GetAovDesc(TfToken const& name) { + auto it = m_aovNameLookup.find(name); + if (it == m_aovNameLookup.end()) { + return kInvalidDesc; + } + + return GetAovDesc(it->second.id, it->second.isComputed); +} + +HdRprAovDescriptor const& HdRprAovRegistry::GetAovDesc(uint32_t id, bool computed) { + size_t descsSize = computed ? m_computedAovDescriptors.size() : m_aovDescriptors.size(); + if (id < 0 || id >= descsSize) { + TF_RUNTIME_ERROR("Invalid arguments: %#x (computed=%d)", id, int(computed)); + return kInvalidDesc; + } + + if (computed) { + return m_computedAovDescriptors[id]; + } else { + return m_aovDescriptors[id]; + } +} + +TfToken const& HdRprGetCameraDepthAovName() { +#if PXR_VERSION < 2002 + return HdAovTokens->linearDepth; +#else + return HdAovTokens->cameraDepth; +#endif +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/aovDescriptor.h b/pxr/imaging/plugin/hdRpr/aovDescriptor.h new file mode 100644 index 000000000..adfae48c9 --- /dev/null +++ b/pxr/imaging/plugin/hdRpr/aovDescriptor.h @@ -0,0 +1,123 @@ +/************************************************************************ +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 HDRPR_AOV_DESCRIPTOR_H +#define HDRPR_AOV_DESCRIPTOR_H + +#include "pxr/base/tf/singleton.h" +#include "pxr/base/tf/staticTokens.h" +#include "pxr/base/gf/vec4f.h" + +#include "pxr/imaging/hd/types.h" + +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +#define HDRPR_AOV_TOKENS \ + (rawColor) \ + (albedo) \ + (variance) \ + (worldCoordinate) \ + (opacity) \ + ((primvarsSt, "primvars:st")) \ + (materialIdx) \ + (geometricNormal) \ + (objectGroupId) \ + (shadowCatcher) \ + (background) \ + (emission) \ + (velocity) \ + (directIllumination) \ + (indirectIllumination) \ + (ao) \ + (directDiffuse) \ + (directReflect) \ + (indirectDiffuse) \ + (indirectReflect) \ + (refract) \ + (volume) \ + (lightGroup0) \ + (lightGroup1) \ + (lightGroup2) \ + (lightGroup3) \ + (viewShadingNormal) \ + (reflectionCatcher) \ + (colorRight) + +TF_DECLARE_PUBLIC_TOKENS(HdRprAovTokens, HDRPR_AOV_TOKENS); + +const rpr::Aov kAovNone = static_cast(-1); + +enum ComputedAovs { + kNdcDepth = 0, + kColorAlpha, + kComputedAovsCount +}; + +struct HdRprAovDescriptor { + uint32_t id; + HdFormat format; + bool multiSampled; + bool computed; + GfVec4f clearValue; + + HdRprAovDescriptor(uint32_t id = kAovNone, bool multiSampled = true, HdFormat format = HdFormatFloat32Vec4, GfVec4f clearValue = GfVec4f(0.0f), bool computed = false) + : id(id), multiSampled(multiSampled), format(format), clearValue(clearValue), computed(computed) { + + } +}; + +class HdRprAovRegistry { +public: + static HdRprAovRegistry& GetInstance() { + return TfSingleton::GetInstance(); + } + + HdRprAovDescriptor const& GetAovDesc(TfToken const& name); + HdRprAovDescriptor const& GetAovDesc(uint32_t id, bool computed); + + HdRprAovRegistry(HdRprAovRegistry const&) = delete; + HdRprAovRegistry& operator=(HdRprAovRegistry const&) = delete; + HdRprAovRegistry(HdRprAovRegistry&&) = delete; + HdRprAovRegistry& operator=(HdRprAovRegistry&&) = delete; + +private: + HdRprAovRegistry(); + ~HdRprAovRegistry() = default; + + friend class TfSingleton; + +private: + struct AovNameLookupValue { + uint32_t id; + bool isComputed; + + AovNameLookupValue(uint32_t id, bool isComputed = false) + : id(id), isComputed(isComputed) { + + } + }; + std::map m_aovNameLookup; + + std::vector m_aovDescriptors; + std::vector m_computedAovDescriptors; +}; + +TfToken const& HdRprGetCameraDepthAovName(); + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // HDRPR_AOV_DESCRIPTOR_H diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index 34d78049d..d5290936c 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -305,6 +305,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, m_geomSubsets = m_topology.GetGeomSubsets(); if (m_geomSubsets.empty()) { if (auto rprMesh = rprApi->CreateMesh(m_points, m_faceVertexIndices, m_normals, m_normalIndices, m_uvs, m_uvIndices, m_faceVertexCounts, m_topology.GetOrientation())) { + rprApi->SetMeshId(rprMesh, GetPrimId()); m_rprMeshes.push_back(rprMesh); } } else { @@ -431,6 +432,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } if (auto rprMesh = rprApi->CreateMesh(subsetPoints, subsetIndexes, subsetNormals, subsetNormalIndices, subsetUv, subsetUvIndices, subsetVertexPerFace, m_topology.GetOrientation())) { + rprApi->SetMeshId(rprMesh, GetPrimId()); m_rprMeshes.push_back(rprMesh); ++it; } else { diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index dc6496e8c..87fd6e7d1 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -299,6 +299,19 @@ def hidewhen_not_ambient_occlusion_mode(render_setting_categories): } ] }, + { + 'name': 'Alpha', + 'settings': [ + { + 'name': 'enableAlpha', + 'ui_name': 'Enable Color Alpha', + 'defaultValue': True, + 'houdini': { + 'hidewhen': 'renderQuality != 3' + } + } + ] + }, { 'name': 'UsdNativeCamera', 'settings': [ @@ -474,7 +487,7 @@ class HdRprConfig {{ if (FILE* f = fopen(rprPreferencePath.c_str(), "rb")) {{ if (!fread(this, sizeof(PrefData), 1, f)) {{ - TF_CODING_ERROR("Fail to read rpr preferences dat file"); + TF_RUNTIME_ERROR("Fail to read rpr preferences dat file"); }} fclose(f); return IsValid(); diff --git a/pxr/imaging/plugin/hdRpr/renderBuffer.cpp b/pxr/imaging/plugin/hdRpr/renderBuffer.cpp index 4ea2be946..c35c010d9 100644 --- a/pxr/imaging/plugin/hdRpr/renderBuffer.cpp +++ b/pxr/imaging/plugin/hdRpr/renderBuffer.cpp @@ -49,7 +49,6 @@ void HdRprRenderBuffer::Finalize(HdRenderParam* renderParam) { bool HdRprRenderBuffer::Allocate(GfVec3i const& dimensions, HdFormat format, bool multiSampled) { - TF_VERIFY(!IsMapped()); TF_UNUSED(multiSampled); if (dimensions[2] != 1) { @@ -69,8 +68,6 @@ bool HdRprRenderBuffer::Allocate(GfVec3i const& dimensions, } void HdRprRenderBuffer::_Deallocate() { - TF_VERIFY(!IsMapped()); - m_width = 0u; m_height = 0u; m_format = HdFormatInvalid; diff --git a/pxr/imaging/plugin/hdRpr/renderDelegate.cpp b/pxr/imaging/plugin/hdRpr/renderDelegate.cpp index 050c795f3..0a2e85a20 100644 --- a/pxr/imaging/plugin/hdRpr/renderDelegate.cpp +++ b/pxr/imaging/plugin/hdRpr/renderDelegate.cpp @@ -12,6 +12,7 @@ limitations under the License. ************************************************************************/ #include "renderDelegate.h" +#include "aovDescriptor.h" #include "pxr/imaging/hd/extComputation.h" @@ -334,42 +335,14 @@ void HdRprDelegate::DestroyBprim(HdBprim* bPrim) { } HdAovDescriptor HdRprDelegate::GetDefaultAovDescriptor(TfToken const& name) const { - HdParsedAovToken aovId(name); - if (name != HdAovTokens->color && - name != HdAovTokens->normal && - name != HdAovTokens->primId && - name != HdAovTokens->depth && - name != HdRprUtilsGetCameraDepthName() && - !(aovId.isPrimvar && aovId.name == "st")) { - // TODO: implement support for instanceId and elementId aov - return HdAovDescriptor(); - } - - if (!m_rprApi->IsAovFormatConversionAvailable()) { - if (name == HdAovTokens->primId) { - // Integer images required, no way to support it - return HdAovDescriptor(); - } - // Only native RPR format can be used for AOVs when there is no support for AOV format conversion - return HdAovDescriptor(HdFormatFloat32Vec4, false, VtValue(GfVec4f(0.0f))); - } + auto& rprAovDesc = HdRprAovRegistry::GetInstance().GetAovDesc(name); - HdFormat format = HdFormatInvalid; - - float clearColorValue = 0.0f; - if (name == HdAovTokens->depth || - name == HdRprUtilsGetCameraDepthName()) { - clearColorValue = name == HdRprUtilsGetCameraDepthName() ? 0.0f : 1.0f; - format = HdFormatFloat32; - } else if (name == HdAovTokens->color) { - format = HdFormatFloat32Vec4; - } else if (name == HdAovTokens->primId) { - format = HdFormatInt32; - } else { - format = HdFormatFloat32Vec3; - } + HdAovDescriptor hdAovDesc; + hdAovDesc.format = rprAovDesc.format; + hdAovDesc.multiSampled = rprAovDesc.multiSampled; + hdAovDesc.clearValue = VtValue(rprAovDesc.clearValue); - return HdAovDescriptor(format, false, VtValue(GfVec4f(clearColorValue))); + return hdAovDesc; } HdRenderSettingDescriptorList HdRprDelegate::GetRenderSettingDescriptors() const { @@ -430,14 +403,6 @@ bool HdRprDelegate::Restart() { #endif // PXR_VERSION >= 2005 -TfToken const& HdRprUtilsGetCameraDepthName() { -#if PXR_VERSION < 2002 - return HdAovTokens->linearDepth; -#else - return HdAovTokens->cameraDepth; -#endif -} - PXR_NAMESPACE_CLOSE_SCOPE void SetHdRprRenderDevice(int renderDevice) { diff --git a/pxr/imaging/plugin/hdRpr/renderDelegate.h b/pxr/imaging/plugin/hdRpr/renderDelegate.h index 98cd9c6ff..78cf5236a 100644 --- a/pxr/imaging/plugin/hdRpr/renderDelegate.h +++ b/pxr/imaging/plugin/hdRpr/renderDelegate.h @@ -105,7 +105,6 @@ class HdRprDelegate final : public HdRenderDelegate { DiagnostMgrDelegatePtr m_diagnosticMgrDelegate; }; -TfToken const& HdRprUtilsGetCameraDepthName(); PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index fd19218f1..b7a203d30 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -13,6 +13,7 @@ limitations under the License. #include "rprApi.h" #include "rprApiAov.h" +#include "aovDescriptor.h" #include "materialFactory.h" #include "rifcpp/rifFilter.h" @@ -63,17 +64,6 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE -TF_DEFINE_ENV_SETTING(HDRPR_DISABLE_ALPHA, false, - "Disable alpha in color AOV. All alpha values would be 1.0"); - -TF_DEFINE_PRIVATE_TOKENS(HdRprAovTokens, - (albedo) \ - (variance) \ - (worldCoordinate) \ - (opacity) \ - ((primvarsSt, "primvars:st")) -); - namespace { using LockGuard = std::lock_guard; @@ -116,19 +106,6 @@ struct HdRprApiEnvironmentLight { } state = kDetached; }; -static const std::map kAovTokenToRprAov = { - {HdAovTokens->color, RPR_AOV_COLOR}, - {HdAovTokens->depth, RPR_AOV_DEPTH}, - {HdAovTokens->primId, RPR_AOV_OBJECT_ID}, - {HdAovTokens->normal, RPR_AOV_SHADING_NORMAL}, - {HdRprUtilsGetCameraDepthName(), RPR_AOV_DEPTH}, - {HdRprAovTokens->albedo, RPR_AOV_DIFFUSE_ALBEDO}, - {HdRprAovTokens->variance, RPR_AOV_VARIANCE}, - {HdRprAovTokens->worldCoordinate, RPR_AOV_WORLD_COORDINATE}, - {HdRprAovTokens->primvarsSt, RPR_AOV_UV}, - {HdRprAovTokens->opacity, RPR_AOV_OPACITY}, -}; - class HdRprApiImpl { public: HdRprApiImpl(HdRprDelegate* delegate) @@ -1004,13 +981,24 @@ class HdRprApiImpl { return m_aovBindings; } - void ResolveFramebuffers(std::vector> const& outputRenderBuffers) { + void ResolveFramebuffers(std::vector> const& outputRenderBuffers, bool* firstResolve) { + std::vector> computedAovsToResolve; for (auto& aovEntry : m_aovRegistry) { auto aov = aovEntry.second.lock(); if (TF_VERIFY(aov)) { - aov->Resolve(); + if (*firstResolve || aov->GetDesc().multiSampled) { + if (aov->GetDesc().computed) { + // Computed AOVs depend on raw AOVs + computedAovsToResolve.push_back(aov); + } else { + aov->Resolve(); + } + } } } + for (auto& aov : computedAovsToResolve) { + aov->Resolve(); + } if (m_rifContext) { m_rifContext->ExecuteCommandQueue(); @@ -1020,10 +1008,14 @@ class HdRprApiImpl { if (outputRenderBuffers[i].first) { auto aovIter = m_boundAovs.find(m_aovBindings[i].aovName); if (aovIter != m_boundAovs.end()) { - aovIter->second->GetData(outputRenderBuffers[i].first, outputRenderBuffers[i].second); + if (*firstResolve || aovIter->second->GetDesc().multiSampled) { + aovIter->second->GetData(outputRenderBuffers[i].first, outputRenderBuffers[i].second); + } } } } + + *firstResolve = false; } void Update() { @@ -1206,6 +1198,11 @@ class HdRprApiImpl { } } + if (preferences.IsDirty(HdRprConfig::DirtyAlpha) || force) { + m_isAlphaEnabled = preferences.GetEnableAlpha(); + UpdateColorAlpha(); + } + m_currentRenderQuality = preferences.GetRenderQuality(); if (m_rprContextMetadata.pluginType == rpr::kPluginTahoe) { @@ -1350,18 +1347,14 @@ class HdRprApiImpl { } if (m_dirtyFlags & ChangeTracker::DirtyViewport) { - for (auto& aovEntry : m_internalAovs) { - aovEntry.second->Resize(m_viewportSize[0], m_viewportSize[1], aovEntry.second->GetFormat()); - } - for (auto& aovBinding : m_aovBindings) { - if (auto rb = aovBinding.renderBuffer) { - auto boundAovIter = m_boundAovs.find(aovBinding.aovName); - if (boundAovIter != m_boundAovs.end()) { - boundAovIter->second->Resize(rb->GetWidth(), rb->GetHeight(), rb->GetFormat()); - } + for (auto it = m_aovRegistry.begin(); it != m_aovRegistry.end();) { + if (auto aov = it->second.lock()) { + aov->Resize(m_viewportSize[0], m_viewportSize[1], aov->GetFormat()); + ++it; + } else { + it = m_aovRegistry.erase(it); } } - // Size of bound AOVs controled by aovBinding's renderBuffer } if (m_dirtyFlags & ChangeTracker::DirtyScene || @@ -1422,13 +1415,13 @@ class HdRprApiImpl { if (filterType == rif::FilterType::EawDenoise) { colorAov->EnableEAWDenoise(m_internalAovs.at(HdRprAovTokens->albedo), m_internalAovs.at(HdAovTokens->normal), - m_internalAovs.at(HdRprUtilsGetCameraDepthName()), + m_internalAovs.at(HdRprGetCameraDepthAovName()), m_internalAovs.at(HdAovTokens->primId), m_internalAovs.at(HdRprAovTokens->worldCoordinate)); } else { colorAov->EnableAIDenoise(m_internalAovs.at(HdRprAovTokens->albedo), m_internalAovs.at(HdAovTokens->normal), - m_internalAovs.at(HdRprUtilsGetCameraDepthName())); + m_internalAovs.at(HdRprGetCameraDepthAovName())); } } @@ -1436,7 +1429,8 @@ class HdRprApiImpl { int numSamplesPerIter = 1; const bool isBatch = m_delegate->IsBatch(); - const bool isProgressive = m_delegate->IsProgressive(); + // XXX(RPR): until FIR-1681 is not resolved we should stick to progressive renders otherwise singlesampled AOV output will be broken + const bool isProgressive = true /*m_delegate->IsProgressive()*/; if (isBatch && !isProgressive) { // Render as many samples as possible per Render call if (m_varianceThreshold > 0.0f) { @@ -1447,6 +1441,8 @@ class HdRprApiImpl { m_rprContext->SetParameter(RPR_CONTEXT_ITERATIONS, numSamplesPerIter); } + bool firstResolve = true; + bool stopRequested = false; while (!IsConverged() || stopRequested) { renderThread->WaitUntilPaused(); @@ -1462,7 +1458,7 @@ class HdRprApiImpl { auto status = m_rprContext->Render(); if (status == RPR_ERROR_ABORTED || - RPR_ERROR_CHECK(status, "Fail contex render framebuffer")) { + RPR_ERROR_CHECK(status, "Fail context render framebuffer", m_rprContext.get())) { stopRequested = true; break; } @@ -1482,14 +1478,14 @@ class HdRprApiImpl { if (!isBatch && !IsConverged()) { // Last framebuffer resolve will be called after "while" in case framebuffer is converged. // We do not resolve framebuffers in case user requested render stop - ResolveFramebuffers(outputRenderBuffers); + ResolveFramebuffers(outputRenderBuffers, &firstResolve); } stopRequested = renderThread->IsStopRequested(); } if (!stopRequested) { - ResolveFramebuffers(outputRenderBuffers); + ResolveFramebuffers(outputRenderBuffers, &firstResolve); } } @@ -1631,10 +1627,6 @@ Don't show this message again? return m_rprContext && m_rprContextMetadata.isGlInteropEnabled; } - bool IsAovFormatConversionAvailable() const { - return m_rifContext != nullptr; - } - bool IsArbitraryShapedLightSupported() const { return m_rprContextMetadata.pluginType != rpr::kPluginHybrid; } @@ -1709,18 +1701,12 @@ Don't show this message again? } auto initInternalAov = [this](TfToken const& name) { - if (auto aov = CreateAov(name)) { + auto& aovDesc = HdRprAovRegistry::GetInstance().GetAovDesc(name); + if (auto aov = CreateAov(name, 0, 0, aovDesc.format)) { m_internalAovs.emplace(name, std::move(aov)); } }; - // In case we have RIF we can use it to combine opacity and color AOVs - // into image that can be used for alpha compositing, - // without it color AOV always have 1.0 in alpha channel - if (!TfGetEnvSetting(HDRPR_DISABLE_ALPHA)) { - initInternalAov(HdRprAovTokens->opacity); - } - // We create separate AOVs needed for denoising ASAP // In such a way, when user enables denoising it will not require to rerender // but it requires more memory, obviously, it should be taken into an account @@ -1729,7 +1715,7 @@ Don't show this message again? filterType = rif::FilterType::AIDenoise; } - initInternalAov(HdRprUtilsGetCameraDepthName()); + initInternalAov(HdRprGetCameraDepthAovName()); initInternalAov(HdRprAovTokens->albedo); initInternalAov(HdAovTokens->color); initInternalAov(HdAovTokens->normal); @@ -1958,6 +1944,35 @@ Don't show this message again? return CreateMesh(position, indexes, normals, VtIntArray(), VtVec2fArray(), VtIntArray(), vpf); } + void UpdateColorAlpha(HdRprApiColorAov* colorAov = nullptr) { + if (!colorAov) { + colorAov = GetColorAov(); + if (!colorAov) return; + } + + if (m_isAlphaEnabled) { + auto opacityAov = GetAov(HdRprAovTokens->opacity, m_viewportSize[0], m_viewportSize[1], HdFormatFloat32Vec4); + if (opacityAov) { + colorAov->SetOpacityAov(opacityAov); + } else { + TF_WARN("Cannot enable alpha"); + } + } else { + colorAov->SetOpacityAov(nullptr); + } + } + + std::shared_ptr GetAov(TfToken const& aovName, int width, int height, HdFormat format) { + std::shared_ptr aov; + auto aovIter = m_aovRegistry.find(aovName); + if (aovIter == m_aovRegistry.end() || + !(aov = aovIter->second.lock())) { + + aov = CreateAov(aovName, width, height, format); + } + return aov; + } + std::shared_ptr CreateAov(TfToken const& aovName, int width = 0, int height = 0, HdFormat format = HdFormatFloat32Vec4) { if (!m_rprContext || width < 0 || height < 0 || @@ -1965,12 +1980,19 @@ Don't show this message again? return nullptr; } - auto rprAovIt = kAovTokenToRprAov.find(aovName); - if (rprAovIt == kAovTokenToRprAov.end()) { + auto& aovDesc = HdRprAovRegistry::GetInstance().GetAovDesc(aovName); + if (aovDesc.id == kAovNone || + aovDesc.format == HdFormatInvalid) { TF_WARN("Unsupported aov type: %s", aovName.GetText()); return nullptr; } + if (aovDesc.format != format) { + TF_RUNTIME_ERROR("Invalid format for %s AOV: expected - %s, got - %s", + aovName.GetText(), TfEnum::GetName(aovDesc.format).c_str(), TfEnum::GetName(format).c_str()); + return nullptr; + } + std::shared_ptr aov; auto iter = m_aovRegistry.find(aovName); @@ -1981,31 +2003,33 @@ Don't show this message again? try { if (!aov) { if (aovName == HdAovTokens->color) { - auto colorAov = std::make_shared(width, height, format, m_rprContext.get(), m_rprContextMetadata); - - auto opacityAovIter = m_aovRegistry.find(HdRprAovTokens->opacity); - if (opacityAovIter != m_aovRegistry.end()) { - if (auto opacityAov = opacityAovIter->second.lock()) { - colorAov->SetOpacityAov(opacityAov); - } + auto rawColorAov = GetAov(HdRprAovTokens->rawColor, width, height, HdFormatFloat32Vec4); + if (!rawColorAov) { + TF_RUNTIME_ERROR("Failed to create color AOV: can't create rawColor AOV"); + return nullptr; } + auto colorAov = std::make_shared(format, std::move(rawColorAov), m_rprContext.get(), m_rprContextMetadata); + UpdateColorAlpha(colorAov.get()); + aov = colorAov; } else if (aovName == HdAovTokens->normal) { aov = std::make_shared(width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else if (aovName == HdAovTokens->depth) { - auto worldCoordinateAovIter = m_internalAovs.find(HdRprAovTokens->worldCoordinate); - if (worldCoordinateAovIter == m_internalAovs.end()) { - if (auto worldCoordinateAov = CreateAov(HdRprAovTokens->worldCoordinate, width, height, HdFormatFloat32Vec4)) { - worldCoordinateAovIter = m_internalAovs.emplace(HdRprAovTokens->worldCoordinate, worldCoordinateAov).first; - } else { - TF_CODING_ERROR("Failed to create depth AOV: can't create worldCoordinate AOV"); - return nullptr; - } + auto worldCoordinateAov = GetAov(HdRprAovTokens->worldCoordinate, width, height, HdFormatFloat32Vec4); + if (!worldCoordinateAov) { + TF_RUNTIME_ERROR("Failed to create depth AOV: can't create worldCoordinate AOV"); + return nullptr; } - aov = std::make_shared(format, worldCoordinateAovIter->second, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + + aov = std::make_shared(format, std::move(worldCoordinateAov), m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else { - aov = std::make_shared(rprAovIt->second, width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + if (!aovDesc.computed) { + aov = std::make_shared(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + } else { + TF_CODING_ERROR("Failed to create %s AOV: unprocessed computed AOV", aovName.GetText()); + return nullptr; + } } m_aovRegistry[aovName] = aov; @@ -2205,6 +2229,7 @@ Don't show this message again? GfVec2i m_viewportSize = GfVec2i(0); GfMatrix4d m_cameraProjectionMatrix = GfMatrix4d(1.f); HdRprCamera const* m_hdCamera; + bool m_isAlphaEnabled; std::atomic m_numLights{0}; HdRprApiEnvironmentLight* m_defaultLightObject = nullptr; @@ -2454,10 +2479,6 @@ bool HdRprApi::IsGlInteropEnabled() const { return m_impl->IsGlInteropEnabled(); } -bool HdRprApi::IsAovFormatConversionAvailable() const { - return m_impl->IsAovFormatConversionAvailable(); -} - bool HdRprApi::IsArbitraryShapedLightSupported() const { m_impl->InitIfNeeded(); return m_impl->IsArbitraryShapedLightSupported(); diff --git a/pxr/imaging/plugin/hdRpr/rprApi.h b/pxr/imaging/plugin/hdRpr/rprApi.h index ef8ae8d24..9823d06cc 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.h +++ b/pxr/imaging/plugin/hdRpr/rprApi.h @@ -146,7 +146,6 @@ class HdRprApi final { bool IsChanged() const; bool IsGlInteropEnabled() const; - bool IsAovFormatConversionAvailable() const; bool IsArbitraryShapedLightSupported() const; int GetCurrentRenderQuality() const; void ExportRprSceneOnNextRender(const char* exportPath); diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index 4f942f7cb..934bf09ec 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -53,14 +53,11 @@ bool ReadRifImage(rif_image image, void* dstBuffer, size_t dstBufferSize) { HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, rpr::Context* rprContext, rpr::ContextMetadata const& rprContextMetadata, std::unique_ptr filter) - : m_format(format), + : m_aovDescriptor(HdRprAovRegistry::GetInstance().GetAovDesc(rprAovType, false)) + , m_format(format), m_filter(std::move(filter)) { - auto componentType = HdGetComponentFormat(format); - if (componentType != HdFormatUNorm8 && - componentType != HdFormatFloat16 && - componentType != HdFormatFloat32) { - TF_CODING_ERROR("Unsupported component type: %d", componentType); - m_format = HdFormatFloat32Vec4; + 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); @@ -81,9 +78,11 @@ HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat for } auto filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_RESAMPLE, rifContext); - if (filter) { - filter->SetParam("interpOperator", RIF_IMAGE_INTERPOLATION_NEAREST); + if (!filter) { + RPR_THROW_ERROR_MSG("Failed to create resample filter"); } + + filter->SetParam("interpOperator", RIF_IMAGE_INTERPOLATION_NEAREST); return filter; }()) { @@ -101,7 +100,8 @@ void HdRprApiAov::Resolve() { void HdRprApiAov::Clear() { if (m_aov) { - m_aov->Clear(); + auto& v = m_aovDescriptor.clearValue; + m_aov->Clear(v[0], v[1], v[2], v[3]); } } @@ -193,8 +193,9 @@ void HdRprApiAov::OnSizeChange(rif::Context* rifContext) { } } -HdRprApiColorAov::HdRprApiColorAov(int width, int height, HdFormat format, rpr::Context* rprContext, rpr::ContextMetadata const& rprContextMetadata) - : HdRprApiAov(RPR_AOV_COLOR, width, height, format, rprContext, rprContextMetadata, nullptr) { +HdRprApiColorAov::HdRprApiColorAov(HdFormat format, std::shared_ptr rawColorAov, rpr::Context* rprContext, rpr::ContextMetadata const& rprContextMetadata) + : HdRprApiAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kColorAlpha), true)) + , m_retainedRawColor(std::move(rawColorAov)) { } @@ -344,7 +345,7 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) if ((m_enabledFilters & kFilterAIDenoise) || (m_enabledFilters & kFilterEAWDenoise)) { auto denoiseFilterType = (m_enabledFilters & kFilterAIDenoise) ? rif::FilterType::AIDenoise : rif::FilterType::EawDenoise; - auto fbDesc = m_aov->GetDesc(); + auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); auto type = (m_enabledFilters & kFilterAIDenoise) ? kFilterAIDenoise : kFilterEAWDenoise; auto filter = rif::Filter::Create(denoiseFilterType, rifContext, fbDesc.fb_width, fbDesc.fb_height); @@ -385,6 +386,14 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) } } +bool HdRprApiColorAov::GetData(void* dstBuffer, size_t dstBufferSize) { + if (!m_filter) { + return m_retainedRawColor->GetData(dstBuffer, dstBufferSize); + } else { + return HdRprApiAov::GetData(dstBuffer, dstBufferSize); + } +} + void HdRprApiColorAov::Resolve() { HdRprApiAov::Resolve(); @@ -424,15 +433,15 @@ void HdRprApiColorAov::OnSizeChange(rif::Context* rifContext) { return; } - auto fbDesc = m_aov->GetDesc(); + auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); if (m_auxFilters.empty()) { - ResizeFilter(fbDesc.fb_width, fbDesc.fb_height, m_mainFilterType, m_filter.get(), GetResolvedFb()); + 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, GetResolvedFb()); + 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); @@ -469,7 +478,8 @@ HdRprApiDepthAov::HdRprApiDepthAov( HdFormat format, std::shared_ptr worldCoordinateAov, rpr::Context* rprContext, rpr::ContextMetadata const& rprContextMetadata, rif::Context* rifContext) - : m_retainedWorldCoordinateAov(worldCoordinateAov) { + : HdRprApiAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kNdcDepth), true)) + , m_retainedWorldCoordinateAov(worldCoordinateAov) { if (!rifContext) { RPR_THROW_ERROR_MSG("Can not create depth AOV: RIF context required"); } diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index cb63020f3..37a84c28e 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -14,6 +14,7 @@ limitations under the License. #ifndef HDRPR_RPR_API_AOV_H #define HDRPR_RPR_API_AOV_H +#include "aovDescriptor.h" #include "rprApiFramebuffer.h" #include "rifcpp/rifFilter.h" #include "rpr/contextMetadata.h" @@ -36,20 +37,24 @@ class HdRprApiAov { virtual void Update(HdRprApi const* rprApi, rif::Context* rifContext); virtual void Resolve(); - bool GetData(void* dstBuffer, size_t dstBufferSize); + virtual bool GetData(void* dstBuffer, size_t dstBufferSize); void Clear(); HdFormat GetFormat() const { return m_format; } + HdRprAovDescriptor const& GetDesc() const { return m_aovDescriptor; } + HdRprApiFramebuffer* GetAovFb() { return m_aov.get(); }; HdRprApiFramebuffer* GetResolvedFb(); protected: - HdRprApiAov() = default; + HdRprApiAov(HdRprAovDescriptor const& aovDescriptor) : m_aovDescriptor(aovDescriptor) {}; virtual void OnFormatChange(rif::Context* rifContext); virtual void OnSizeChange(rif::Context* rifContext); protected: + HdRprAovDescriptor const& m_aovDescriptor; + std::unique_ptr m_aov; std::unique_ptr m_resolved; std::unique_ptr m_filter; @@ -69,10 +74,11 @@ class HdRprApiAov { class HdRprApiColorAov : public HdRprApiAov { public: - HdRprApiColorAov(int width, int height, HdFormat format, rpr::Context* rprContext, rpr::ContextMetadata const& rprContextMetadata); + HdRprApiColorAov(HdFormat format, std::shared_ptr rawColorAov, rpr::Context* rprContext, rpr::ContextMetadata const& rprContextMetadata); ~HdRprApiColorAov() override = default; 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); @@ -127,6 +133,7 @@ class HdRprApiColorAov : public HdRprApiAov { void SetTonemapFilterParams(rif::Filter* filter); private: + std::shared_ptr m_retainedRawColor; std::shared_ptr m_retainedOpacity; std::shared_ptr m_retainedDenoiseInputs[rif::MaxInput]; diff --git a/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.cpp b/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.cpp index 9b80a8d4d..201788c83 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.cpp @@ -12,6 +12,7 @@ limitations under the License. ************************************************************************/ #include "rprApiFramebuffer.h" +#include "aovDescriptor.h" #include "rpr/helpers.h" PXR_NAMESPACE_OPEN_SCOPE @@ -63,11 +64,19 @@ void HdRprApiFramebuffer::AttachAs(rpr::Aov aov) { m_aov = aov; } -void HdRprApiFramebuffer::Clear() { +void HdRprApiFramebuffer::Clear(float r, float g, float b, float a) { if (m_width == 0 || m_height == 0) { return; } RPR_ERROR_CHECK(m_rprFb->Clear(), "Failed to clear framebuffer"); + + // XXX (FIR-1681): We can not rely on clear values because every AOV in RPR is multisampled, i.e. + // value of singlesampled AOV (any ID AOV, worldCoordinate, etc) is always equals to `clearValue + renderedValue` + /*if (r == 0.0f && g == 0.0f && b == 0.0f && a == 0.0f) { + RPR_ERROR_CHECK(m_rprFb->Clear(), "Failed to clear framebuffer"); + } else { + RPR_ERROR_CHECK(m_rprFb->FillWithColor(r, g, b, a), "Failed to clear framebuffer"); + }*/ } void HdRprApiFramebuffer::Resolve(HdRprApiFramebuffer* dstFrameBuffer) { diff --git a/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.h b/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.h index 08af8e501..dbd0174be 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.h +++ b/pxr/imaging/plugin/hdRpr/rprApiFramebuffer.h @@ -23,7 +23,6 @@ PXR_NAMESPACE_OPEN_SCOPE class HdRprApiFramebuffer { public: - static constexpr rpr::Aov kAovNone = static_cast(-1); static constexpr uint32_t kNumChannels = 4; HdRprApiFramebuffer(rpr::Context* context, uint32_t width, uint32_t height); @@ -33,7 +32,7 @@ class HdRprApiFramebuffer { HdRprApiFramebuffer& operator=(HdRprApiFramebuffer&& fb) noexcept; void AttachAs(rpr::Aov aov); - void Clear(); + void Clear(float r, float g, float b, float a); void Resolve(HdRprApiFramebuffer* dstFrameBuffer); /// Return true if framebuffer was actually resized bool Resize(uint32_t width, uint32_t height);