From 7ccd8d3164ffba3b8385cc683ddff70ca242c76b Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Thu, 5 Oct 2023 05:38:59 +0300 Subject: [PATCH 01/16] removed rif denoising and upscaling --- .../python/generateRenderSettingFiles.py | 53 +- pxr/imaging/plugin/hdRpr/rprApi.cpp | 139 +---- pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 512 +++++------------- pxr/imaging/plugin/hdRpr/rprApiAov.h | 54 +- 4 files changed, 174 insertions(+), 584 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 9810c60c8..2e733870e 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -256,48 +256,6 @@ def houdini_parm_name(name): 'hidewhen': hidewhen_hybrid } }, - { - 'name': 'Denoise', - 'houdini': { - 'hidewhen': lambda settings: hidewhen_render_quality('<', 'High', settings) - }, - 'settings': [ - { - 'name': 'denoising:enable', - 'ui_name': 'Enable AI Denoising', - 'defaultValue': False, - 'houdini': { - 'custom_tags': [ - '"uiicon" VIEW_display_denoise' - ] - } - }, - { - 'folder': 'Denoise Settings', - 'houdini': { - 'hidewhen': 'denoising:enable == 0' - }, - 'settings': [ - { - 'name': 'denoising:minIter', - 'ui_name': 'Denoise Min Iteration', - 'defaultValue': 4, - 'minValue': 1, - 'maxValue': 2 ** 16, - 'help': 'The first iteration on which denoising should be applied.' - }, - { - 'name': 'denoising:iterStep', - 'ui_name': 'Denoise Iteration Step', - 'defaultValue': 32, - 'minValue': 1, - 'maxValue': 2 ** 16, - 'help': 'Denoise use frequency. To denoise on each iteration, set to 1.' - } - ] - } - ] - }, { 'name': 'Sampling', 'houdini': { @@ -587,7 +545,10 @@ def houdini_parm_name(name): 'minValue': 1, 'maxValue': 4096 } - ] + ], + 'houdini': { + 'hidewhen': lambda settings: hidewhen_render_quality('!=', 'HybridPro', settings) + } }, { 'name': 'Tonemapping', @@ -845,7 +806,7 @@ def houdini_parm_name(name): 'help': '', 'defaultValue': False, 'houdini': { - 'hidewhen': ['denoising:enable == 0', lambda settings: hidewhen_render_quality('<', 'High', settings)] + 'hidewhen': ['hybrid:denoising == "None"', lambda settings: hidewhen_render_quality('<', 'High', settings), lambda settings: hidewhen_render_quality('==', 'Northstar', settings)] } }, { @@ -861,7 +822,7 @@ def houdini_parm_name(name): SettingValue('Ultra Performance'), ], 'houdini': { - 'hidewhen': ['rpr:viewportUpscaling == 0', 'denoising:enable == 0', lambda settings: hidewhen_render_quality('<', 'High', settings), lambda settings: hidewhen_render_quality('==', 'Northstar', settings)] + 'hidewhen': ['hybrid:denoising == "None"', 'rpr:viewportUpscaling == 0', lambda settings: hidewhen_render_quality('<', 'High', settings), lambda settings: hidewhen_render_quality('==', 'Northstar', settings)] } } ] @@ -1180,7 +1141,7 @@ def process_setting(setting): if generate_ds_files: production_render_setting_categories = [category for category in render_setting_categories if category['name'] != 'ViewportSettings'] generate_houdini_ds(install_path, 'Global', production_render_setting_categories) - viewport_render_setting_categories = [category for category in render_setting_categories if category['name'] in ('RenderQuality', 'Sampling', 'AdaptiveSampling', 'Denoise', 'ViewportSettings')] + viewport_render_setting_categories = [category for category in render_setting_categories if category['name'] in ('RenderQuality', 'Sampling', 'AdaptiveSampling', 'Hybrid', 'ViewportSettings')] for category in (cat for cat in viewport_render_setting_categories if cat['name'] == 'RenderQuality'): for setting in (s for s in category['settings'] if s['name'] == 'core:renderQuality'): setting['values'] = [SettingValue(value.get_key(), value.get_key() if value.get_key() != 'Northstar' else 'Full') for value in setting['values']] diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 590d4ed77..d6824955b 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -1666,10 +1666,6 @@ class HdRprApiImpl { m_dirtyFlags |= ChangeTracker::DirtyViewport; } - int aovSize(int size) const { - return m_upscale ? size / 2 : size; - } - void SetAovBindings(HdRenderPassAovBindingVector const& aovBindings) { m_aovBindings = aovBindings; m_dirtyFlags |= ChangeTracker::DirtyAOVBindings; @@ -1714,7 +1710,7 @@ class HdRprApiImpl { // Reuse previously created RPR AOV std::swap(outRb.rprAov, outputRenderBufferIt->rprAov); // Update underlying format if needed - outRb.rprAov->Resize(aovSize(rprRenderBuffer->GetWidth()), aovSize(rprRenderBuffer->GetHeight()), aovFormat, (rprRenderBuffer->GetWidth() % 2 != 0)); + outRb.rprAov->Resize(rprRenderBuffer->GetWidth(), rprRenderBuffer->GetHeight(), aovFormat); } if (!outRb.rprAov) return nullptr; @@ -1723,10 +1719,7 @@ class HdRprApiImpl { RPR_ERROR_CHECK(outRb.rprAov->GetAovFb()->GetRprObject()->SetLPE(outRb.lpe.c_str()), "Failed to set LPE")) { return nullptr; } - if (m_upscale) { - outRb.rprAov->InitUpscaleFilter(m_rifContext.get()); - } - + m_outputRenderBuffers.push_back(std::move(outRb)); return &m_outputRenderBuffers.back(); }; @@ -1764,12 +1757,7 @@ class HdRprApiImpl { for (auto& outRb : m_outputRenderBuffers) { if (outRb.mappedData && (m_isFirstSample || outRb.isMultiSampled)) { - if (m_upscale) { - outRb.rprAov->GetUpscaledData(outRb.mappedData, outRb.mappedDataSize, m_rifContext.get()); - } - else { - outRb.rprAov->GetData(outRb.mappedData, outRb.mappedDataSize); - } + outRb.rprAov->GetData(outRb.mappedData, outRb.mappedDataSize); } } @@ -1797,7 +1785,6 @@ class HdRprApiImpl { } bool clearAovs = false; - RenderSetting enableDenoise; RenderSetting tonemap; RenderSetting gamma; RenderSetting instantaneousShutter; @@ -1807,14 +1794,6 @@ class HdRprApiImpl { HdRprConfig* config; auto configInstanceLock = m_delegate->LockConfigInstance(&config); - enableDenoise.isDirty = config->IsDirty(HdRprConfig::DirtyDenoise); - if (enableDenoise.isDirty) { - enableDenoise.value = config->GetDenoisingEnable(); - - m_denoiseMinIter = config->GetDenoisingMinIter(); - m_denoiseIterStep = config->GetDenoisingIterStep(); - } - tonemap.isDirty = config->IsDirty(HdRprConfig::DirtyTonemapping); if (tonemap.isDirty) { tonemap.value.enable = config->GetTonemappingEnable(); @@ -1877,7 +1856,7 @@ class HdRprApiImpl { config->ResetDirty(); } UpdateCamera(cameraMode, aspectRatioPolicy, instantaneousShutter); - UpdateAovs(rprRenderParam, enableDenoise, tonemap, gamma, clearAovs); + UpdateAovs(rprRenderParam, tonemap, gamma, clearAovs); m_dirtyFlags = ChangeTracker::Clean; if (m_hdCamera) { @@ -2144,8 +2123,8 @@ class HdRprApiImpl { RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_DISPLAY_GAMMA, preferences.GetCoreDisplayGamma()), "Failed to set display gamma"); } - if (preferences.IsDirty(HdRprConfig::DirtyDenoise) || preferences.IsDirty(HdRprConfig::DirtyViewportSettings)) { - if (preferences.GetDenoisingEnable() && preferences.GetViewportUpscaling()) { + if (preferences.IsDirty(HdRprConfig::DirtyHybrid) || preferences.IsDirty(HdRprConfig::DirtyViewportSettings) || force) { + if (preferences.GetHybridDenoising() != HdRprHybridDenoisingTokens->None && preferences.GetViewportUpscaling()) { RPR_ERROR_CHECK(m_rprContext->SetParameter(rpr::ContextInfo(RPR_CONTEXT_UPSCALER), RPR_UPSCALER_FSR2), "Failed to set upscaler"); rpr_uint upscaleQuality = RPR_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE; TfToken qualityToken = preferences.GetViewportUpscalingQuality(); @@ -2302,12 +2281,6 @@ class HdRprApiImpl { m_cryptomatteAovs = nullptr; } } - - if (preferences.IsDirty(HdRprConfig::DirtyViewportSettings) || force) { - m_upscale = preferences.GetViewportUpscaling() && !RprUsdIsHybrid(m_rprContextMetadata.pluginType); - m_dirtyFlags |= (ChangeTracker::DirtyScene | ChangeTracker::DirtyViewport); - UpdateColorAlpha(m_colorAov.get()); - } } bool GetRprCameraMode(TfToken const& mode, rpr_camera_mode* out) { @@ -2550,9 +2523,7 @@ class HdRprApiImpl { return false; } - void UpdateAovs(HdRprRenderParam* rprRenderParam, RenderSetting enableDenoise, RenderSetting tonemap, RenderSetting gamma, bool clearAovs) { - UpdateDenoising(enableDenoise); - + void UpdateAovs(HdRprRenderParam* rprRenderParam, RenderSetting tonemap, RenderSetting gamma, bool clearAovs) { if (tonemap.isDirty) { m_colorAov->SetTonemap(tonemap.value); } @@ -2587,7 +2558,7 @@ class HdRprApiImpl { if (m_dirtyFlags & ChangeTracker::DirtyViewport) { m_resolveData.ForAllAovs([this](ResolveData::AovEntry const& e) { - e.aov->Resize(aovSize(m_viewportSize[0]), aovSize(m_viewportSize[1]), e.aov->GetFormat(), (m_viewportSize[0] % 2 != 0)); + e.aov->Resize(m_viewportSize[0], m_viewportSize[1], e.aov->GetFormat()); }); // If AOV bindings are dirty then we already committed HdRprRenderBuffers, see SetAovBindings @@ -2629,41 +2600,6 @@ class HdRprApiImpl { } } - void UpdateDenoising(RenderSetting enableDenoise) { - // Disable denoiser to prevent possible crashes due to incorrect AI models - if (!m_rifContext || m_rifContext->GetModelPath().empty()) { - return; - } - - if (!enableDenoise.isDirty || - m_isDenoiseEnabled == enableDenoise.value) { - return; - } - - m_isDenoiseEnabled = enableDenoise.value; - if (!m_isDenoiseEnabled) { - m_colorAov->DeinitDenoise(m_rifContext.get()); - return; - } - - rif::FilterType filterType = rif::FilterType::EawDenoise; - if (RprUsdIsGpuUsed(m_rprContextMetadata)) { - filterType = rif::FilterType::AIDenoise; - } - - if (filterType == rif::FilterType::EawDenoise) { - m_colorAov->InitEAWDenoise(CreateAov(HdRprAovTokens->albedo), - CreateAov(HdAovTokens->normal), - CreateAov(HdRprGetCameraDepthAovName()), - CreateAov(HdAovTokens->primId), - CreateAov(HdRprAovTokens->worldCoordinate)); - } else { - m_colorAov->InitAIDenoise(CreateAov(HdRprAovTokens->albedo), - CreateAov(HdAovTokens->normal), - CreateAov(HdRprGetCameraDepthAovName())); - } - } - using RenderUpdateCallbackFunc = void (*)(float progress, void* userData); void EnableRenderUpdateCallback(RenderUpdateCallbackFunc rucFunc) { if (m_rprContextMetadata.pluginType != kPluginNorthstar) { @@ -2984,12 +2920,6 @@ class HdRprApiImpl { // active pixels as often as possible const bool isAdaptiveSamplingEnabled = IsAdaptiveSamplingEnabled(); - // In a batch session, we do denoise once at the end - auto rprApi = static_cast(m_delegate->GetRenderParam())->GetRprApi(); - if (m_isDenoiseEnabled) { - m_colorAov->SetDenoise(false, rprApi, m_rifContext.get()); - } - while (!IsConverged()) { if (renderThread->IsStopRequested()) { break; @@ -3053,10 +2983,6 @@ class HdRprApiImpl { } } - if (m_isDenoiseEnabled) { - m_colorAov->SetDenoise(true, rprApi, m_rifContext.get()); - } - ResolveFramebuffers(); } @@ -3165,29 +3091,7 @@ class HdRprApiImpl { break; } - bool doDenoisedResolve = false; - if (m_colorAov) { - if (m_isDenoiseEnabled) { - ++iteration; - if (iteration >= m_denoiseMinIter) { - int relativeIter = iteration - m_denoiseMinIter; - if (relativeIter % m_denoiseIterStep == 0) { - doDenoisedResolve = true; - } - } - - // Always force denoise on the last sample because it's quite hard to match - // the max amount of samples and denoise controls (min iter and iter step) - if (m_numSamples + m_numSamplesPerIter == m_maxSamples) { - doDenoisedResolve = true; - } - } - - m_colorAov->SetDenoise(doDenoisedResolve, rprApi, m_rifContext.get()); - } - - if (m_resolveMode == kResolveAfterRender || - doDenoisedResolve) { + if (m_resolveMode == kResolveAfterRender) { ResolveFramebuffers(); } @@ -3861,7 +3765,6 @@ Don't show this message again? m_currentRenderQuality = GetRenderQuality(*config); flipRequestedByRenderSetting = config->GetCoreFlipVertical(); useGmon = config->GetCoreUseGmon(); - m_rprContextMetadata.isGlInteropEnabled = config->GetOpenglInteroperability(); m_rprContextMetadata.useOpenCL = config->GetCoreUseOpenCL(); m_rprContextMetadata.pluginType = GetPluginType(m_currentRenderQuality); @@ -3963,9 +3866,6 @@ Don't show this message again? void InitAovs() { m_colorAov = std::static_pointer_cast(CreateAov(HdAovTokens->color)); - if (m_upscale) { - m_colorAov->InitUpscaleFilter(m_rifContext.get()); - } m_lpeAovPool.clear(); m_lpeAovPool.insert(m_lpeAovPool.begin(), { @@ -4241,7 +4141,7 @@ Don't show this message again? } } - if (m_isAlphaEnabled || m_upscale) { + if (m_isAlphaEnabled) { auto opacityAov = GetAov(HdRprAovTokens->opacity, m_viewportSize[0], m_viewportSize[1], HdFormatFloat32Vec4); if (opacityAov) { colorAov->SetOpacityAov(opacityAov); @@ -4302,7 +4202,7 @@ Don't show this message again? newAov = colorAov; } else if (aovName == HdAovTokens->normal) { - newAov = new HdRprApiNormalAov(aovSize(width), aovSize(height), format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiNormalAov(width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else if (aovName == HdAovTokens->depth) { auto worldCoordinateAov = GetAov(HdRprAovTokens->worldCoordinate, width, height, HdFormatFloat32Vec4); if (!worldCoordinateAov) { @@ -4315,7 +4215,7 @@ Don't show this message again? return nullptr; } - newAov = new HdRprApiDepthAov(aovSize(width), aovSize(height), format, std::move(worldCoordinateAov), std::move(opacityAov), 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, m_rifContext.get()); } else if (aovName == HdRprAovTokens->colorWithTransparency) { auto rawColorAov = GetAov(HdRprAovTokens->rawColor, width, height, HdFormatFloat32Vec4); @@ -4334,10 +4234,10 @@ Don't show this message again? return nullptr; } - newAov = new HdRprApiScCompositeAOV(aovSize(width), aovSize(height), format, std::move(rawColorAov), std::move(opacityAov), std::move(shadowCatcherAov), m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiScCompositeAOV(width, height, format, std::move(rawColorAov), std::move(opacityAov), std::move(shadowCatcherAov), m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else if (TfStringStartsWith(aovName.GetString(), "lpe")) { - newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), aovSize(width), aovSize(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, m_rifContext.get()); 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 @@ -4363,10 +4263,10 @@ Don't show this message again? return nullptr; } - newAov = new HdRprApiIdMaskAov(aovDesc, baseAov, aovSize(width), aovSize(height), format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); + newAov = new HdRprApiIdMaskAov(aovDesc, baseAov, width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); } else { if (!aovDesc.computed) { - newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), aovSize(width), aovSize(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, m_rifContext.get()); } else { TF_CODING_ERROR("Failed to create %s AOV: unprocessed computed AOV", aovName.GetText()); } @@ -4387,7 +4287,7 @@ Don't show this message again? m_aovRegistry[aovName] = aov; m_dirtyFlags |= ChangeTracker::DirtyAOVRegistry; } else { - aov->Resize(aovSize(width), aovSize(height), format, (width % 2 != 0)); + aov->Resize(width, height, format); } } catch (std::runtime_error const& e) { TF_RUNTIME_ERROR("Failed to create %s AOV: %s", aovName.GetText(), e.what()); @@ -4689,10 +4589,6 @@ Don't show this message again? } m_resolveMode = kResolveAfterRender; bool m_isFirstSample = true; - bool m_isDenoiseEnabled = false; - int m_denoiseMinIter; - int m_denoiseIterStep; - GfVec2i m_viewportSize = GfVec2i(0); GfMatrix4d m_cameraProjectionMatrix = GfMatrix4d(1.f); HdRprCamera const* m_hdCamera = nullptr; @@ -4712,7 +4608,6 @@ Don't show this message again? int m_minSamples = 0; float m_varianceThreshold = 0.0f; TfToken m_currentRenderQuality; - bool m_upscale; using Duration = std::chrono::high_resolution_clock::duration; Duration m_frameRenderTotalTime; diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index 2db30de79..f014e4c38 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -23,42 +23,41 @@ PXR_NAMESPACE_OPEN_SCOPE namespace { -bool ReadRifImage(rif_image image, void* dstBuffer, size_t dstBufferSize) { - if (!image || !dstBuffer) { - return false; - } + 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; - } + 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; - } + void* data = nullptr; + rifStatus = rifImageMap(image, RIF_IMAGE_MAP_READ, &data); + if (rifStatus != RIF_SUCCESS) { + return false; + } - std::memcpy(dstBuffer, data, size); + std::memcpy(dstBuffer, data, size); - rifStatus = rifImageUnmap(image, data); - if (rifStatus != RIF_SUCCESS) { - TF_WARN("Failed to unmap rif image"); - } + rifStatus = rifImageUnmap(image, data); + if (rifStatus != RIF_SUCCESS) { + TF_WARN("Failed to unmap rif image"); + } - return true; -} + 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, std::unique_ptr filter) : m_aovDescriptor(HdRprAovRegistry::GetInstance().GetAovDesc(rprAovType, false)) , m_filter(std::move(filter)) - , m_upscaleFilter(nullptr) - , m_format(format), m_width(width), m_height(height) { + , m_format(format) { if (rif::Image::GetDesc(0, 0, format).type == 0) { RIF_THROW_ERROR_MSG("Unsupported format: " + TfEnum::GetName(format)); } @@ -73,31 +72,32 @@ 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) + 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 + if (format == HdFormatFloat32Vec4) { + // RPR framebuffers by default with such format + return nullptr; + } + if (!rifContext) + { + if (format == HdFormatFloat32) { 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."); + 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"); - } + 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; +}()) { - filter->SetParam("interpOperator", (int) RIF_IMAGE_INTERPOLATION_NEAREST); - return filter; - }()) { } void HdRprApiAov::Resolve() { @@ -108,9 +108,6 @@ void HdRprApiAov::Resolve() { if (m_filter) { m_filter->Resolve(); } - if (m_upscaleFilter) { - m_upscaleFilter->Resolve(); - } } void HdRprApiAov::Clear() { @@ -133,48 +130,8 @@ bool HdRprApiAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { return resolvedFb->GetData(dstBuffer, dstBufferSize); } -bool HdRprApiAov::InitUpscaleFilter(rif::Context* rifContext) { - if (!rifContext) { - return false; - } - if (m_upscaleFilter) { - return true; - } - m_upscaleFilter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_AI_UPSCALE, rifContext); - if (!m_upscaleFilter) { - return false; - } - m_upscaleFilter->SetParam("mode", (int) RIF_AI_UPSCALE_MODE_FAST_2X); - m_upscaleFilter->SetParam("useHDR", 1); - m_upscaleFilter->SetParam("modelPath", rifContext->GetModelPath().c_str()); - m_upscaleFilter->Resize(m_width, m_height); - m_upscaleFilter->SetOutput(rif::Image::GetDesc(m_width * 2, m_height * 2, m_format)); - return true; -} - -bool HdRprApiAov::GetUpscaledDataImpl(void* dstBuffer, size_t dstBufferSize, rif::Context* rifContext) { - if (!m_upscaleFilter) { - if (!InitUpscaleFilter(rifContext)) { - return false; - } - } - - if (!ReadRifImage(m_upscaleFilter->GetOutput(), dstBuffer, dstBufferSize)) - { - return false; - } - - if (m_oddWidth) { - size_t pixelSize = HdDataSizeOfFormat(m_format); - for (size_t i = (size_t)m_height * 2 - 1; i > 0; --i) { - memmove((char*)dstBuffer + i * ((size_t)m_width * 2 + 1) * pixelSize, (char*)dstBuffer + i * (size_t)m_width * 2 * pixelSize, (size_t)m_width * 2 * pixelSize); - } - } - - return true; -} - -void HdRprApiAov::SetUpSizeAndBuffer(void*& getBuffer, size_t& dstBufferSize) { +bool HdRprApiAov::GetData(void* dstBuffer, size_t dstBufferSize) { + auto getBuffer = dstBuffer; if (!m_filter) { bool needTmpBuffer = true; @@ -203,81 +160,58 @@ void HdRprApiAov::SetUpSizeAndBuffer(void*& getBuffer, size_t& dstBufferSize) { getBuffer = m_tmpBuffer.data(); } } -} - -void HdRprApiAov::ApplyFormatToOutput(void* getBuffer, void* dstBuffer, size_t 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 (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) + if (m_format == HdFormatInt32) { + auto srcData = reinterpret_cast(getBuffer); + auto dstData = reinterpret_cast(dstBuffer); + for (size_t i = 0; i < dstBufferSize / sizeof(float); ++i) { - dstData[i] = 0; + if (i % 4 == 3) + { + dstData[i] = 0; + } + else + { + dstData[i] = (char)(srcData[i] * 255 + 0.5f); + } } - else + + auto primIdData = reinterpret_cast(dstBuffer); + for (size_t i = 0; i < dstBufferSize / sizeof(GfVec4f); ++i) { - dstData[i] = (char)(srcData[i] * 255 + 0.5f); + 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(GfVec4f); ++i) - { - primIdData[i] -= 1; + for (size_t i = 0; i < dstBufferSize / sizeof(int); ++i) { + primIdData[i] = (primIdData[i] & 0xFFFFFF) - 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; - } - } -} -bool HdRprApiAov::GetData(void* dstBuffer, size_t dstBufferSize) { - auto getBuffer = dstBuffer; - SetUpSizeAndBuffer(getBuffer, dstBufferSize); - if (GetDataImpl(getBuffer, dstBufferSize)) { - ApplyFormatToOutput(getBuffer, dstBuffer, dstBufferSize); return true; } return false; } -bool HdRprApiAov::GetUpscaledData(void* dstBuffer, size_t dstBufferSize, rif::Context* rifContext) { - auto getBuffer = dstBuffer; - SetUpSizeAndBuffer(getBuffer, dstBufferSize); - if (GetUpscaledDataImpl(dstBuffer, dstBufferSize, rifContext)) { - ApplyFormatToOutput(getBuffer, dstBuffer, dstBufferSize); - return true; - } - - return false; -} - -void HdRprApiAov::Resize(int width, int height, HdFormat format, bool oddWidth) { - m_width = width; - m_height = height; - m_oddWidth = oddWidth; - +void HdRprApiAov::Resize(int width, int height, HdFormat format) { if (m_format != format) { m_format = format; m_dirtyBits |= ChangeTracker::DirtyFormat; @@ -304,10 +238,6 @@ void HdRprApiAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { if (m_filter) { m_filter->Update(); } - - if (m_upscaleFilter) { - m_upscaleFilter->Update(); - } } HdRprApiFramebuffer* HdRprApiAov::GetResolvedFb() { @@ -318,7 +248,7 @@ 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); + m_filter->SetParam("interpOperator", (int)RIF_IMAGE_INTERPOLATION_NEAREST); // Reset inputs m_dirtyBits |= ChangeTracker::DirtySize; @@ -333,22 +263,12 @@ void HdRprApiAov::OnSizeChange(rif::Context* rifContext) { 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)); } - if (m_upscaleFilter) { - auto fbDesc = m_aov->GetDesc(); - m_upscaleFilter->Resize(fbDesc.fb_width, fbDesc.fb_height); - if (m_filter) { - m_upscaleFilter->SetInput(rif::Color, m_filter->GetOutput()); - } - else { - m_upscaleFilter->SetInput(rif::Color, GetResolvedFb()); - } - m_upscaleFilter->SetOutput(rif::Image::GetDesc(fbDesc.fb_width * 2, fbDesc.fb_height * 2, m_format)); - } } HdRprApiColorAov::HdRprApiColorAov(HdFormat format, std::shared_ptr rawColorAov, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) - : HdRprApiAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kColorAlpha), true), 0, 0, format) + : HdRprApiAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kColorAlpha), true), format) , m_retainedRawColor(std::move(rawColorAov)) { + } void HdRprApiColorAov::SetFilter(Filter filter, bool enable) { @@ -356,7 +276,8 @@ void HdRprApiColorAov::SetFilter(Filter filter, bool enable) { if (enable != isFilterEnabled) { if (enable) { m_enabledFilters |= filter; - } else { + } + else { m_enabledFilters &= ~filter; } m_isEnabledFiltersDirty = true; @@ -370,76 +291,6 @@ void HdRprApiColorAov::SetOpacityAov(std::shared_ptr opacity) { } } -void HdRprApiColorAov::InitAIDenoise( - std::shared_ptr albedo, - std::shared_ptr normal, - std::shared_ptr linearDepth) { - if (m_enabledFilters & kFilterAIDenoise) { - return; - } - if (!albedo || !normal || !linearDepth) { - TF_RUNTIME_ERROR("Failed to enable AI denoise: invalid parameters"); - return; - } - - for (auto& retainedInput : m_retainedDenoiseInputs) { - retainedInput = nullptr; - } - m_retainedDenoiseInputs[rif::Normal] = normal; - m_retainedDenoiseInputs[rif::LinearDepth] = linearDepth; - m_retainedDenoiseInputs[rif::Albedo] = albedo; - - m_denoiseFilterType = kFilterAIDenoise; -} - -void HdRprApiColorAov::InitEAWDenoise( - std::shared_ptr albedo, - std::shared_ptr normal, - std::shared_ptr linearDepth, - std::shared_ptr objectId, - std::shared_ptr worldCoordinate) { - if (m_enabledFilters & kFilterEAWDenoise) { - return; - } - if (!albedo || !normal || !linearDepth || !objectId || !worldCoordinate) { - TF_RUNTIME_ERROR("Failed to enable EAW denoise: invalid parameters"); - return; - } - - for (auto& retainedInput : m_retainedDenoiseInputs) { - retainedInput = nullptr; - } - m_retainedDenoiseInputs[rif::Normal] = normal; - m_retainedDenoiseInputs[rif::LinearDepth] = linearDepth; - m_retainedDenoiseInputs[rif::ObjectId] = objectId; - m_retainedDenoiseInputs[rif::Albedo] = albedo; - m_retainedDenoiseInputs[rif::WorldCoordinate] = worldCoordinate; - - m_denoiseFilterType = kFilterEAWDenoise; -} - -void HdRprApiColorAov::DeinitDenoise(rif::Context* rifContext) { - for (auto& retainedInput : m_retainedDenoiseInputs) { - retainedInput = nullptr; - } - - m_denoiseFilterType = kFilterNone; -} - -void HdRprApiColorAov::SetDenoise(bool enable, HdRprApi const* rprApi, rif::Context* rifContext) { - if (m_denoiseFilterType != kFilterNone) { - SetFilter(m_denoiseFilterType, enable); - SetFilter(m_denoiseFilterType == kFilterAIDenoise ? kFilterEAWDenoise : kFilterAIDenoise, false); - } else { - SetFilter(kFilterAIDenoise, false); - SetFilter(kFilterEAWDenoise, false); - } - - SetFilter(kFilterResample, m_format != HdFormatFloat32Vec4); - - Update(rprApi, rifContext); -} - void HdRprApiColorAov::SetTonemap(TonemapParams const& params) { bool isTonemapEnabled = m_enabledFilters & kFilterTonemap; bool tonemapEnableDirty = params.enable != isTonemapEnabled; @@ -452,7 +303,8 @@ void HdRprApiColorAov::SetTonemap(TonemapParams const& params) { if (!tonemapEnableDirty && isTonemapEnabled) { if (m_mainFilterType == kFilterTonemap) { SetTonemapFilterParams(m_filter.get()); - } else { + } + else { for (auto& entry : m_auxFilters) { if (entry.first == kFilterTonemap) { SetTonemapFilterParams(entry.second.get()); @@ -467,7 +319,7 @@ void HdRprApiColorAov::SetTonemap(TonemapParams const& params) { void HdRprApiColorAov::SetGamma(GammaParams const& params) { bool isGammaEnabled = m_enabledFilters & kFilterGamma; bool gammaEnableDirty = params.enable != isGammaEnabled; - + SetFilter(kFilterGamma, params.enable); if (m_gamma != params) { @@ -476,7 +328,8 @@ void HdRprApiColorAov::SetGamma(GammaParams const& params) { if (!gammaEnableDirty && isGammaEnabled) { if (m_mainFilterType == kFilterGamma) { m_filter.get()->SetParam("gamma", m_gamma.value); - } else { + } + else { for (auto& entry : m_auxFilters) { if (entry.first == kFilterGamma) { entry.second.get()->SetParam("gamma", m_gamma.value); @@ -500,12 +353,14 @@ bool HdRprApiColorAov::CanComposeAlpha() { return HdGetComponentCount(m_format) == 4 && m_retainedOpacity; } -void HdRprApiColorAov::Resize(int width, int height, HdFormat format, bool oddWidth) { +void HdRprApiColorAov::Resize(int width, int height, HdFormat format) { if (m_width != width || m_height != height) { + m_width = width; + m_height = height; m_dirtyBits |= ChangeTracker::DirtySize; } - HdRprApiAov::Resize(width, height, format, oddWidth); + HdRprApiAov::Resize(width, height, format); } void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { @@ -526,9 +381,7 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) filterPool.emplace_back(m_mainFilterType, std::move(m_filter)); } - if ((m_enabledFilters & kFilterAIDenoise) || - (m_enabledFilters & kFilterEAWDenoise) || - (m_enabledFilters & kFilterComposeOpacity) || + if ((m_enabledFilters & kFilterComposeOpacity) || (m_enabledFilters & kFilterTonemap) || (m_enabledFilters & kFilterGamma)) { @@ -538,7 +391,8 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) 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 { + } + else { filter = filterCreator(); } @@ -553,51 +407,39 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) if (m_enabledFilters & kFilterTonemap) { addFilter(kFilterTonemap, [rifContext]() { - return rif::Filter::CreateCustom(RIF_IMAGE_FILTER_PHOTO_LINEAR_TONEMAP, 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 & kFilterAIDenoise) || - (m_enabledFilters & kFilterEAWDenoise)) { - auto type = (m_enabledFilters & kFilterAIDenoise) ? kFilterAIDenoise : kFilterEAWDenoise; - addFilter(type, - [this, rifContext]() { - auto denoiseFilterType = (m_enabledFilters & kFilterAIDenoise) ? rif::FilterType::AIDenoise : rif::FilterType::EawDenoise; - auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); - auto filter = rif::Filter::Create(denoiseFilterType, rifContext, fbDesc.fb_width, fbDesc.fb_height); - return filter; - } + 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"( + 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; - } + filter->SetParam("code", opacityComposingKernelCode); + return filter; + } ); } - } else if (m_enabledFilters & kFilterResample) { + } + 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_filter->SetParam("interpOperator", (int)RIF_IMAGE_INTERPOLATION_NEAREST); m_mainFilterType = kFilterResample; } @@ -616,28 +458,18 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) if (m_filter) { m_filter->Update(); } - if (m_upscaleFilter) { - if (m_filter) { - m_upscaleFilter->SetInput(rif::Color, m_filter->GetOutput()); - } - else { - if (auto resolvedRawColorFb = m_retainedRawColor->GetResolvedFb()) { - m_upscaleFilter->SetInput(rif::Color, resolvedRawColorFb); - } - } - m_upscaleFilter->SetOutput(rif::Image::GetDesc(m_width * 2, m_height * 2, m_format)); - m_upscaleFilter->Update(); - } } bool HdRprApiColorAov::GetData(void* dstBuffer, size_t dstBufferSize) { if (!m_filter) { if (auto resolvedRawColorFb = m_retainedRawColor->GetResolvedFb()) { return resolvedRawColorFb->GetData(dstBuffer, dstBufferSize); - } else { + } + else { return false; } - } else { + } + else { return HdRprApiAov::GetData(dstBuffer, dstBufferSize); } } @@ -662,36 +494,33 @@ void HdRprApiColorAov::ResizeFilter(int width, int height, Filter filterType, ri filter->SetInput(rif::Color, input); filter->SetOutput(rif::Image::GetDesc(width, height, m_format)); - if (filterType == kFilterAIDenoise || filterType == kFilterEAWDenoise) { - for (int i = 0; i < rif::MaxInput; ++i) { - if (auto retainedInput = m_retainedDenoiseInputs[i].get()) { - filter->SetInput(static_cast(i), retainedInput->GetResolvedFb()); - } - } - } else if (filterType == kFilterComposeOpacity) { + if (filterType == kFilterComposeOpacity) { filter->SetInput("alphaImage", m_retainedOpacity->GetResolvedFb()); - } else if (filterType == kFilterResample) { + } + else if (filterType == kFilterResample) { filter->SetParam("outSize", GfVec2i(width, height)); - } else if (filterType == kFilterTonemap) { + } + else if (filterType == kFilterTonemap) { SetTonemapFilterParams(filter); - } else if (filterType == kFilterGamma) { + } + else if (filterType == kFilterGamma) { filter->SetParam("gamma", m_gamma.value); } } void HdRprApiColorAov::OnSizeChange(rif::Context* rifContext) { - auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); - 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 { + } + 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) { @@ -700,11 +529,6 @@ void HdRprApiColorAov::OnSizeChange(rif::Context* rifContext) { } ResizeFilter(fbDesc.fb_width, fbDesc.fb_height, m_mainFilterType, m_filter.get(), m_auxFilters.back().second->GetOutput()); } - - if (m_upscaleFilter) { - m_upscaleFilter->Resize(fbDesc.fb_width, fbDesc.fb_height); - m_upscaleFilter->SetOutput(rif::Image::GetDesc(fbDesc.fb_width * 2, fbDesc.fb_height * 2, m_format)); - } } HdRprApiNormalAov::HdRprApiNormalAov( @@ -729,25 +553,19 @@ void HdRprApiNormalAov::OnSizeChange(rif::Context* rifContext) { 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)); - - if (m_upscaleFilter) { - m_upscaleFilter->Resize(fbDesc.fb_width, fbDesc.fb_height); - m_upscaleFilter->SetInput(rif::Color, m_filter->GetOutput()); - m_upscaleFilter->SetOutput(rif::Image::GetDesc(fbDesc.fb_width * 2, fbDesc.fb_height * 2, m_format)); - } } -void HdRprApiComputedAov::Resize(int width, int height, HdFormat format, bool oddWidth) { +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, oddWidth); } HdRprApiDepthAov::HdRprApiDepthAov( @@ -757,7 +575,7 @@ HdRprApiDepthAov::HdRprApiDepthAov( rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext) : HdRprApiComputedAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kNdcDepth), true), width, height, format) , m_retainedWorldCoordinateAov(worldCoordinateAov) - , m_retainedOpacityAov(opacityAov){ + , m_retainedOpacityAov(opacityAov) { if (!rifContext) { RPR_THROW_ERROR_MSG("Can not create depth AOV: RIF context required"); @@ -766,7 +584,7 @@ HdRprApiDepthAov::HdRprApiDepthAov( 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); + m_filter = rif::Filter::CreateCustom(RIF_IMAGE_FILTER_USER_DEFINED, rifContext); auto opacityComposingKernelCode = std::string(R"( int2 coord; @@ -819,11 +637,6 @@ void HdRprApiDepthAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) if (m_remapFilter) { m_remapFilter->Update(); } - if (m_upscaleFilter) { - m_upscaleFilter->SetInput(rif::Color, m_filter->GetOutput()); - m_upscaleFilter->SetOutput(rif::Image::GetDesc(m_width * 2, m_height * 2, m_format)); - m_upscaleFilter->Update(); - } } void HdRprApiDepthAov::Resolve() { @@ -836,9 +649,6 @@ void HdRprApiDepthAov::Resolve() { if (m_remapFilter) { m_remapFilter->Resolve(); } - if (m_upscaleFilter) { - m_upscaleFilter->Resolve(); - } } HdRprApiIdMaskAov::HdRprApiIdMaskAov( @@ -897,12 +707,12 @@ HdRprApiScCompositeAOV::HdRprApiScCompositeAOV(int width, int height, HdFormat f 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), width, height, format) + : 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)) { @@ -928,61 +738,7 @@ bool HdRprApiScCompositeAOV::GetDataImpl(void* dstBuffer, size_t dstBufferSize) 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 }; - } - } - - return true; -} - -bool HdRprApiScCompositeAOV::InitUpscaleFilter(rif::Context* rifContext) { - if (!m_retainedRawColorAov || !m_retainedOpacityAov || !m_retainedScAov) { - return false; - } - return m_retainedRawColorAov->InitUpscaleFilter(rifContext) - && m_retainedOpacityAov->InitUpscaleFilter(rifContext) - && m_retainedScAov->InitUpscaleFilter(rifContext); -} - -bool HdRprApiScCompositeAOV::GetUpscaledDataImpl(void* dstBuffer, size_t dstBufferSize, rif::Context* rifContext) { - 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->GetUpscaledDataImpl((void*)m_tempColorBuffer.data(), dstBufferSize, rifContext)) { - return false; - } - if (!m_retainedOpacityAov->GetUpscaledDataImpl((void*)m_tempOpacityBuffer.data(), dstBufferSize, rifContext)) { - return false; - } - if (!m_retainedScAov->GetUpscaledDataImpl((void*)m_tempScBuffer.data(), dstBufferSize, rifContext)) { - return false; - } - - auto dstValue = reinterpret_cast(dstBuffer); - - // On this stage format is always HdFormatFloat32Vec4 - #pragma omp parallel for +#pragma omp parallel for for (int i = 0; i < dstBufferSize / sizeof(GfVec4f); i++) { float opacity = m_tempOpacityBuffer[i][0]; diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index 828a4c5ce..dc17d7ab3 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -33,12 +33,11 @@ class HdRprApiAov { rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); virtual ~HdRprApiAov() = default; - virtual void Resize(int width, int height, HdFormat format, bool oddWidth); + virtual void Resize(int width, int height, HdFormat format); virtual void Update(HdRprApi const* rprApi, rif::Context* rifContext); virtual void Resolve(); virtual bool GetData(void* dstBuffer, size_t dstBufferSize); - bool GetUpscaledData(void* dstBuffer, size_t dstBufferSize, rif::Context* rifContext); void Clear(); HdFormat GetFormat() const { return m_format; } @@ -47,20 +46,13 @@ class HdRprApiAov { HdRprApiFramebuffer* GetAovFb() { return m_aov.get(); }; HdRprApiFramebuffer* GetResolvedFb(); - virtual bool InitUpscaleFilter(rif::Context* rifContext); + virtual bool GetDataImpl(void* dstBuffer, size_t dstBufferSize); protected: - HdRprApiAov(HdRprAovDescriptor const& aovDescriptor, int width, int height, HdFormat format) - : m_aovDescriptor(aovDescriptor), m_width(width), m_height(height), m_format(format) {}; + HdRprApiAov(HdRprAovDescriptor const& aovDescriptor, HdFormat format) + : m_aovDescriptor(aovDescriptor), m_format(format) {}; virtual void OnFormatChange(rif::Context* rifContext); virtual void OnSizeChange(rif::Context* rifContext); - - void SetUpSizeAndBuffer(void*& dstBuffer, size_t& dstBufferSize); - void ApplyFormatToOutput(void* getBuffer, void* dstBuffer, size_t dstBufferSize); - virtual bool GetDataImpl(void* dstBuffer, size_t dstBufferSize); - virtual bool GetUpscaledDataImpl(void* dstBuffer, size_t dstBufferSize, rif::Context* rifContext); - - friend class HdRprApiScCompositeAOV; protected: HdRprAovDescriptor const& m_aovDescriptor; HdFormat m_format; @@ -69,11 +61,6 @@ class HdRprApiAov { std::unique_ptr m_resolved; std::unique_ptr m_filter; std::vector m_tmpBuffer; - std::unique_ptr m_upscaleFilter; - - int m_width = 0; - int m_height = 0; - bool m_oddWidth = false; // for upscaler enum ChangeTracker { Clean = 0, @@ -89,24 +76,13 @@ class HdRprApiColorAov : public HdRprApiAov { HdRprApiColorAov(HdFormat format, std::shared_ptr rawColorAov, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata); ~HdRprApiColorAov() override = default; - void Resize(int width, int height, HdFormat format, bool oddWidth) override; + 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); - void InitAIDenoise(std::shared_ptr albedo, - std::shared_ptr normal, - std::shared_ptr linearDepth); - void InitEAWDenoise(std::shared_ptr albedo, - std::shared_ptr normal, - std::shared_ptr linearDepth, - std::shared_ptr objectId, - std::shared_ptr worldCoordinate); - void DeinitDenoise(rif::Context* rifContext); - void SetDenoise(bool enable, HdRprApi const* rprApi, rif::Context* rifContext); - struct TonemapParams { bool enable; float exposureTime; @@ -146,8 +122,8 @@ class HdRprApiColorAov : public HdRprApiAov { enum Filter { kFilterNone = 0, kFilterResample = 1 << 0, - kFilterAIDenoise = 1 << 1, - kFilterEAWDenoise = 1 << 2, + //kFilterAIDenoise = 1 << 1, + //kFilterEAWDenoise = 1 << 2, kFilterComposeOpacity = 1 << 3, kFilterTonemap = 1 << 4, kFilterGamma = 1 << 5 @@ -164,8 +140,6 @@ class HdRprApiColorAov : public HdRprApiAov { private: std::shared_ptr m_retainedRawColor; std::shared_ptr m_retainedOpacity; - std::shared_ptr m_retainedDenoiseInputs[rif::MaxInput]; - Filter m_denoiseFilterType = kFilterNone; Filter m_mainFilterType = kFilterNone; std::vector>> m_auxFilters; @@ -175,6 +149,9 @@ class HdRprApiColorAov : public HdRprApiAov { TonemapParams m_tonemap; GammaParams m_gamma; + + int m_width = 0; + int m_height = 0; }; class HdRprApiNormalAov : public HdRprApiAov { @@ -190,10 +167,14 @@ class HdRprApiNormalAov : public HdRprApiAov { class HdRprApiComputedAov : public HdRprApiAov { public: HdRprApiComputedAov(HdRprAovDescriptor const& aovDescriptor, int width, int height, HdFormat format) - : HdRprApiAov(aovDescriptor, width, height, format) {} + : HdRprApiAov(aovDescriptor, format), m_width(width), m_height(height) {} ~HdRprApiComputedAov() override = default; - void Resize(int width, int height, HdFormat format, bool oddWidth) override final; + void Resize(int width, int height, HdFormat format) override final; + +protected: + int m_width = -1; + int m_height = -1; }; class HdRprApiDepthAov : public HdRprApiComputedAov { @@ -239,10 +220,7 @@ class HdRprApiScCompositeAOV : public HdRprApiAov { std::shared_ptr opacityAov, std::shared_ptr scAov, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); - bool InitUpscaleFilter(rif::Context* rifContext) override; -protected: bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; - bool GetUpscaledDataImpl(void* dstBuffer, size_t dstBufferSize, rif::Context* rifContext) override; private: std::shared_ptr m_retainedRawColorAov; std::shared_ptr m_retainedOpacityAov; From 38ecc3ac9cbfee3c813fecb2a6d6a4f8a129bf86 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Fri, 6 Oct 2023 03:07:41 +0300 Subject: [PATCH 02/16] hybrid upscaling and denoising synchronous setting --- .../plugin/hdRpr/python/generateRenderSettingFiles.py | 11 +---------- pxr/imaging/plugin/hdRpr/rprApi.cpp | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 2e733870e..e1912bd2e 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -800,15 +800,6 @@ def houdini_parm_name(name): 'help': '', 'defaultValue': False, }, - { - 'name': 'viewportUpscaling', - 'ui_name': 'Viewport Upscaling', - 'help': '', - 'defaultValue': False, - 'houdini': { - 'hidewhen': ['hybrid:denoising == "None"', lambda settings: hidewhen_render_quality('<', 'High', settings), lambda settings: hidewhen_render_quality('==', 'Northstar', settings)] - } - }, { 'name': 'viewportUpscalingQuality', 'ui_name': 'Viewport Upscaling Quality', @@ -822,7 +813,7 @@ def houdini_parm_name(name): SettingValue('Ultra Performance'), ], 'houdini': { - 'hidewhen': ['hybrid:denoising == "None"', 'rpr:viewportUpscaling == 0', lambda settings: hidewhen_render_quality('<', 'High', settings), lambda settings: hidewhen_render_quality('==', 'Northstar', settings)] + 'hidewhen': ['hybrid:denoising == "None"', lambda settings: hidewhen_render_quality('<', 'High', settings), lambda settings: hidewhen_render_quality('==', 'Northstar', settings)] } } ] diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index d6824955b..901af0d17 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -2124,7 +2124,7 @@ class HdRprApiImpl { } if (preferences.IsDirty(HdRprConfig::DirtyHybrid) || preferences.IsDirty(HdRprConfig::DirtyViewportSettings) || force) { - if (preferences.GetHybridDenoising() != HdRprHybridDenoisingTokens->None && preferences.GetViewportUpscaling()) { + if (preferences.GetHybridDenoising() != HdRprHybridDenoisingTokens->None) { RPR_ERROR_CHECK(m_rprContext->SetParameter(rpr::ContextInfo(RPR_CONTEXT_UPSCALER), RPR_UPSCALER_FSR2), "Failed to set upscaler"); rpr_uint upscaleQuality = RPR_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE; TfToken qualityToken = preferences.GetViewportUpscalingQuality(); From 11ee2547fa943602cc092527538580251fd1ee6a Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Tue, 10 Oct 2023 22:46:59 +0300 Subject: [PATCH 03/16] upscaling quality added to render settings node; tonemapping disabled --- .../python/generateRenderSettingFiles.py | 37 ++++++++++--------- pxr/imaging/plugin/hdRpr/rprApi.cpp | 17 +++++---- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index e1912bd2e..4dd5e3e53 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -505,7 +505,10 @@ def houdini_parm_name(name): SettingValue('Aces'), SettingValue('Reinhard'), SettingValue('Photolinear') - ] + ], + 'houdini': { + 'hidewhen': lambda settings: hidewhen_render_quality('==', 'HybridPro', settings) # Disabled until tonemapping implementation is finished + } }, { 'name': 'hybrid:denoising', @@ -517,6 +520,22 @@ def houdini_parm_name(name): SettingValue('ASVGF') ] }, + { + 'name': 'hybrid:upscalingQuality', + 'ui_name': 'Upscaling Quality', + 'help': '', + 'defaultValue': 'Ultra Performance', + 'values': [ + SettingValue('Ultra Quality'), + SettingValue('Quality'), + SettingValue('Balance'), + SettingValue('Performance'), + SettingValue('Ultra Performance'), + ], + 'houdini': { + 'hidewhen': 'hybrid:denoising == "None"' + } + }, { 'name': 'hybrid:accelerationMemorySizeMb', 'ui_name': 'Hybrid Acceleration Structure Memory Size (MB)', @@ -799,22 +818,6 @@ def houdini_parm_name(name): 'ui_name': 'OpenGL interoperability (Needs render restart)', 'help': '', 'defaultValue': False, - }, - { - 'name': 'viewportUpscalingQuality', - 'ui_name': 'Viewport Upscaling Quality', - 'help': '', - 'defaultValue': 'Ultra Performance', - 'values': [ - SettingValue('Ultra Quality'), - SettingValue('Quality'), - SettingValue('Balance'), - SettingValue('Performance'), - SettingValue('Ultra Performance'), - ], - 'houdini': { - 'hidewhen': ['hybrid:denoising == "None"', lambda settings: hidewhen_render_quality('<', 'High', settings), lambda settings: hidewhen_render_quality('==', 'Northstar', settings)] - } } ] } diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 901af0d17..3dc199fe5 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -2123,20 +2123,20 @@ class HdRprApiImpl { RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_DISPLAY_GAMMA, preferences.GetCoreDisplayGamma()), "Failed to set display gamma"); } - if (preferences.IsDirty(HdRprConfig::DirtyHybrid) || preferences.IsDirty(HdRprConfig::DirtyViewportSettings) || force) { + if (preferences.IsDirty(HdRprConfig::DirtyHybrid) || force) { if (preferences.GetHybridDenoising() != HdRprHybridDenoisingTokens->None) { RPR_ERROR_CHECK(m_rprContext->SetParameter(rpr::ContextInfo(RPR_CONTEXT_UPSCALER), RPR_UPSCALER_FSR2), "Failed to set upscaler"); rpr_uint upscaleQuality = RPR_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE; - TfToken qualityToken = preferences.GetViewportUpscalingQuality(); - if (qualityToken == HdRprViewportUpscalingQualityTokens->UltraQuality) { + TfToken qualityToken = preferences.GetHybridUpscalingQuality(); + if (qualityToken == HdRprHybridUpscalingQualityTokens->UltraQuality) { upscaleQuality = RPR_FSR2_QUALITY_ULTRA_QUALITY; - } else if (qualityToken == HdRprViewportUpscalingQualityTokens->Quality) { + } else if (qualityToken == HdRprHybridUpscalingQualityTokens->Quality) { upscaleQuality = RPR_FSR2_QUALITY_MODE_QUALITY; - } else if (qualityToken == HdRprViewportUpscalingQualityTokens->Balance) { + } else if (qualityToken == HdRprHybridUpscalingQualityTokens->Balance) { upscaleQuality = RPR_FSR2_QUALITY_MODE_BALANCE; - } else if (qualityToken == HdRprViewportUpscalingQualityTokens->Performance) { + } else if (qualityToken == HdRprHybridUpscalingQualityTokens->Performance) { upscaleQuality = RPR_FSR2_QUALITY_MODE_PERFORMANCE; - } else if (qualityToken == HdRprViewportUpscalingQualityTokens->UltraPerformance) { + } else if (qualityToken == HdRprHybridUpscalingQualityTokens->UltraPerformance) { upscaleQuality = RPR_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE; } RPR_ERROR_CHECK(m_rprContext->SetParameter(rpr::ContextInfo(RPR_CONTEXT_FSR2_QUALITY), upscaleQuality), "Failed to set upscaler quality"); @@ -2144,6 +2144,7 @@ class HdRprApiImpl { else { RPR_ERROR_CHECK(m_rprContext->SetParameter(rpr::ContextInfo(RPR_CONTEXT_UPSCALER), RPR_UPSCALER_NONE), "Failed to set upscaler"); } + m_dirtyFlags |= ChangeTracker::DirtyScene; } } @@ -2184,6 +2185,8 @@ class HdRprApiImpl { } else if (hybridDenoising == HdRprHybridDenoisingTokens->ASVGF) { RPR_ERROR_CHECK(m_rprContext->SetParameter(rpr::ContextInfo(RPR_CONTEXT_PT_DENOISER), RPR_DENOISER_ASVGF), "Failed to set denoiser"); } + + m_dirtyFlags |= ChangeTracker::DirtyScene; } if (preferences.IsDirty(HdRprConfig::DirtyQuality) || force) { From 40de93647f38a04c8d4604344d608d3b0be86afa Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Wed, 11 Oct 2023 14:19:19 +0300 Subject: [PATCH 04/16] max radiance soft max update --- pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index 4dd5e3e53..67d83fef6 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -361,7 +361,7 @@ def houdini_parm_name(name): 'help': 'Limits the intensity, or the maximum brightness, of samples in the scene. Greater clamp radiance values produce more brightness.', 'defaultValue': 0.0, 'minValue': 0.0, - 'maxValue': 1e6 + 'maxValue': 10 }, { 'name': 'quality:filterType', From 93e8341c14f44278b03ce0e563e14b9ede614726 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Sun, 22 Oct 2023 03:52:36 +0300 Subject: [PATCH 05/16] further removal --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 2 +- pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 261 +++++++++++++------------ pxr/imaging/plugin/hdRpr/rprApiAov.h | 35 ++-- 3 files changed, 155 insertions(+), 143 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 3dc199fe5..26051aca5 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -4218,7 +4218,7 @@ 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()); + newAov = new HdRprApiDepthAov(width, height, format, std::move(worldCoordinateAov), std::move(opacityAov), m_rprContext.get(), m_rprContextMetadata); } else if (aovName == HdRprAovTokens->colorWithTransparency) { auto rawColorAov = GetAov(HdRprAovTokens->rawColor, width, height, HdFormatFloat32Vec4); diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index f014e4c38..743500c7e 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -18,6 +18,7 @@ limitations under the License. #include "pxr/imaging/rprUsd/contextMetadata.h" #include "pxr/imaging/rprUsd/error.h" +#include "pxr/base/work/loops.h" PXR_NAMESPACE_OPEN_SCOPE @@ -53,6 +54,86 @@ namespace { } // namespace anonymous +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(float* src, float* dest, size_t length) { + WorkParallelForN(length, + [&](size_t begin, size_t end) { + for (int i = 0; i < length; ++i) { + dest[i * 3] = src[i * 4]; + dest[i * 3 + 1] = src[i * 4 + 1]; + dest[i * 3 + 2] = src[i * 4 + 2]; + } + }); +} + +void CpuNdcFilter(float* src, float* dest, size_t length, const GfMatrix4f& viewProjectionMatrix) { + WorkParallelForN(length, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + float norm = std::max(src[i * 4 + 3], 1.0f); + GfVec4f pos(src[i * 4] / norm, src[i * 4 + 1] / norm, src[i * 4 + 2] / norm, 1.0f); + GfVec4f posResult = viewProjectionMatrix * pos; + dest[i] = posResult[2] / posResult[3]; + } + }); +} + +void CpuOpacityFilter(float* opacity, float* srcdest, size_t length) { + WorkParallelForN(length, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + float op = opacity[i * 4]; + srcdest[i] *= op; + } + }); +} + +void CpuOpacityMaskFilter(float* opacity, float* srcdest, size_t length) { + WorkParallelForN(length, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + float op = opacity[i * 4]; + if (op == 0.0f) { + srcdest[i] = 1.0f; + } + } + }); +} + +void CpuFillMaskFilter(float* srcdest, size_t length) { + WorkParallelForN(length, + [&](size_t begin, size_t end) { + for (int i = begin; i < end; ++i) { + unsigned int idDecoded = (unsigned int)(srcdest[i * 4] * 256) + (unsigned int)(srcdest[i * 4 + 1] * 256 * 256) + (unsigned int)(srcdest[i * 4 + 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 * 4] = (v0 & 0xFFFF) / (float)(0xFFFF); + srcdest[i * 4 + 1] = (v0 >> 16) / (float)(0xFFFF); + srcdest[i * 4 + 2] = (v1 & 0xFFFF) / (float)(0xFFFF); + srcdest[i * 4 + 3] = 1.0f; + } + else { + srcdest[i * 4] = srcdest[i * 4 + 1] = srcdest[i * 4 + 2] = srcdest[i * 4 + 3] = 0; + } + } + }); +} + HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, std::unique_ptr filter) : m_aovDescriptor(HdRprAovRegistry::GetInstance().GetAovDesc(rprAovType, false)) @@ -78,15 +159,8 @@ HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat for // RPR framebuffers by default with such format return nullptr; } - if (!rifContext) - { - if (format == HdFormatFloat32) { - return nullptr; - } - if (format == HdFormatInt32) { + if (!rifContext) { 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); @@ -534,25 +608,32 @@ void HdRprApiColorAov::OnSizeChange(rif::Context* rifContext) { 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"); - } - - m_filter->SetParam("srcRangeAuto", 0); - m_filter->SetParam("dstLo", -1.0f); - m_filter->SetParam("dstHi", 1.0f); + : HdRprApiAov(RPR_AOV_SHADING_NORMAL, width, height, format, rprContext, rprContextMetadata, nullptr) { } void HdRprApiNormalAov::OnFormatChange(rif::Context* rifContext) { m_dirtyBits |= ChangeTracker::DirtySize; } -void HdRprApiNormalAov::OnSizeChange(rif::Context* rifContext) { +bool HdRprApiNormalAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { 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)); + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_cpuFilterBuffer.size()) { + m_cpuFilterBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); + } + static size_t numPixels = dstBufferSize / (3 * sizeof(float)); + if (m_cpuFilterBuffer.size() / 4 != numPixels) + { + return false; + } + + auto resolvedFb = GetResolvedFb(); + if (!resolvedFb || !resolvedFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { + return false; + } + + CpuVec4toVec3Filter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels); + CpuRemapFilter((float*)dstBuffer, (float*)dstBuffer, numPixels * 3, 0.0, 1.0, -1.0, 1.0); + return true; } void HdRprApiComputedAov::Resize(int width, int height, HdFormat format) { @@ -568,87 +649,47 @@ void HdRprApiComputedAov::Resize(int width, int height, HdFormat 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 + , m_retainedOpacityAov(opacityAov) + , m_viewProjectionMatrix(GfMatrix4f()) { + m_cpuFilterBuffer.resize(cpuFilterBufferSize()); } 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_ndcFilter->Update(); - m_opacityFilter->Update(); - if (m_remapFilter) { - m_remapFilter->Update(); - } + m_viewProjectionMatrix = GfMatrix4f(rprApi->GetCameraViewMatrix() * rprApi->GetCameraProjectionMatrix()).GetTranspose(); } -void HdRprApiDepthAov::Resolve() { - if (m_ndcFilter) { - m_ndcFilter->Resolve(); +bool HdRprApiDepthAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { + if (cpuFilterBufferSize() != m_cpuFilterBuffer.size()) { + m_cpuFilterBuffer.resize(cpuFilterBufferSize()); } - if (m_opacityFilter) { - m_opacityFilter->Resolve(); + static size_t numPixels = dstBufferSize / sizeof(float); + if (m_cpuFilterBuffer.size() / 4 != numPixels) + { + return false; } - if (m_remapFilter) { - m_remapFilter->Resolve(); + + auto coordinateFb = m_retainedWorldCoordinateAov->GetResolvedFb(); + if (!coordinateFb || !coordinateFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { + return false; } + + CpuNdcFilter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels, m_viewProjectionMatrix); + + auto opacityFb = m_retainedOpacityAov->GetResolvedFb(); + if (!opacityFb || !opacityFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { + return false; + } + + CpuOpacityMaskFilter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels); + CpuRemapFilter((float*)dstBuffer, (float*)dstBuffer, numPixels, -1, 1, 0, 1.0); + return true; } HdRprApiIdMaskAov::HdRprApiIdMaskAov( @@ -660,46 +701,18 @@ HdRprApiIdMaskAov::HdRprApiIdMaskAov( 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)); +bool HdRprApiIdMaskAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { + static size_t numPixels = dstBufferSize / (4 * sizeof(float)); + + auto resolvedFb = m_baseIdAov->GetResolvedFb(); + if (!resolvedFb || !resolvedFb->GetData(dstBuffer, dstBufferSize)) { + return false; } - m_dirtyBits = ChangeTracker::Clean; - if (m_filter) { - m_filter->Update(); - } + CpuFillMaskFilter((float*)dstBuffer, numPixels); + return true; } HdRprApiScCompositeAOV::HdRprApiScCompositeAOV(int width, int height, HdFormat format, diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index dc17d7ab3..3a91e1cc4 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -157,11 +157,13 @@ class HdRprApiColorAov : public HdRprApiAov { 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, rif::Context* rifContext); ~HdRprApiNormalAov() override = default; protected: void OnFormatChange(rif::Context* rifContext) override; - void OnSizeChange(rif::Context* rifContext) override; + bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; +private: + std::vector m_cpuFilterBuffer; }; class HdRprApiComputedAov : public HdRprApiAov { @@ -180,37 +182,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: + bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) 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, rif::Context* rifContext); ~HdRprApiIdMaskAov() override = default; - - void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; - +protected: + bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; private: std::shared_ptr m_baseIdAov; + std::vector m_cpuFilterBuffer; }; class HdRprApiScCompositeAOV : public HdRprApiAov { From 79c31bdede3638009374530124ec9ea5e1e7fd1a Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Tue, 21 Nov 2023 06:43:32 +0300 Subject: [PATCH 06/16] avoid_calc_in_get_data --- pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 173 ++++++++++++++++--------- pxr/imaging/plugin/hdRpr/rprApiAov.h | 26 ++-- 2 files changed, 126 insertions(+), 73 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index 743500c7e..2ad1a04dd 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -79,8 +79,20 @@ void CpuNdcFilter(float* src, float* dest, size_t length, const GfMatrix4f& view for (int i = begin; i < end; ++i) { float norm = std::max(src[i * 4 + 3], 1.0f); GfVec4f pos(src[i * 4] / norm, src[i * 4 + 1] / norm, src[i * 4 + 2] / norm, 1.0f); + GfVec4f posResult = viewProjectionMatrix.GetOrthonormalized() * pos; + dest[i * 4] = std::max(std::min(posResult[2] / posResult[3], 0.9f), -0.9f); + dest[i * 4 + 1] = 0;// posResult[2] / posResult[3]; + dest[i * 4 + 2] = 0;// posResult[2] / posResult[3]; + dest[i * 4 + 3] = 1.0f; + + /*float norm = std::max(src[i * 4 + 3], 1.0f); + GfVec4f pos(src[i * 4] / norm, src[i * 4 + 1] / norm, src[i * 4 + 2] / norm, 1.0f); GfVec4f posResult = viewProjectionMatrix * pos; - dest[i] = posResult[2] / posResult[3]; + float depth = posResult[2] / posResult[3]; + dest[i * 4] = depth; + dest[i * 4 + 1] = depth; + dest[i * 4 + 2] = depth; + dest[i * 4 + 3] = 1.0f;*/ } }); } @@ -90,7 +102,10 @@ void CpuOpacityFilter(float* opacity, float* srcdest, size_t length) { [&](size_t begin, size_t end) { for (int i = begin; i < end; ++i) { float op = opacity[i * 4]; - srcdest[i] *= op; + srcdest[i * 4] *= op; + srcdest[i * 4 + 1] *= op; + srcdest[i * 4 + 2] *= op; + srcdest[i * 4 + 3] = op; } }); } @@ -101,7 +116,10 @@ void CpuOpacityMaskFilter(float* opacity, float* srcdest, size_t length) { for (int i = begin; i < end; ++i) { float op = opacity[i * 4]; if (op == 0.0f) { - srcdest[i] = 1.0f; + srcdest[i * 4] = 1.0f; + srcdest[i * 4 + 1] = 1.0f; + srcdest[i * 4 + 1] = 1.0f; + srcdest[i * 4 + 1] = 1.0f; } } }); @@ -134,10 +152,31 @@ void CpuFillMaskFilter(float* srcdest, size_t length) { }); } +void CpuResampleNearest(float* src, size_t srcWidth, size_t srcHeight, float* 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 = xratio * y; + dest[(y * destWidth + x) * 4] = src[(cy * srcWidth + cx) * 4]; + dest[(y * destWidth + x) * 4 + 1] = src[(cy * srcWidth + cx) * 4 + 1]; + dest[(y * destWidth + x) * 4 + 2] = src[(cy * srcWidth + cx) * 4 + 2]; + dest[(y * destWidth + x) * 4 + 3] = src[(cy * srcWidth + cx) * 4 + 3]; + } + }}); +} + HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, std::unique_ptr filter) : 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)); @@ -179,8 +218,17 @@ void HdRprApiAov::Resolve() { m_aov->Resolve(m_resolved.get()); } - 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())) { + return; + } + + if (m_aov) { + auto fbDesc = m_aov->GetDesc(); + CpuResampleNearest((float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height, (float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height); + } } } @@ -192,8 +240,12 @@ void HdRprApiAov::Clear() { } bool HdRprApiAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { - if (m_filter) { - return ReadRifImage(m_filter->GetOutput(), dstBuffer, dstBufferSize); + if (m_outputBuffer.size() > 0) { + if (dstBufferSize != m_outputBuffer.size()) { + return false; + } + memcpy(dstBuffer, m_outputBuffer.data(), dstBufferSize); + return true; } auto resolvedFb = GetResolvedFb(); @@ -206,7 +258,7 @@ bool HdRprApiAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { bool HdRprApiAov::GetData(void* dstBuffer, size_t dstBufferSize) { auto getBuffer = dstBuffer; - if (!m_filter) + if (!m_filterEnabled) { bool needTmpBuffer = true; // Rpr always renders to HdFormatFloat32Vec4 @@ -235,7 +287,7 @@ bool HdRprApiAov::GetData(void* dstBuffer, size_t dstBufferSize) { } } if (GetDataImpl(getBuffer, dstBufferSize)) { - if (!m_filter) + if (!m_filterEnabled) { if (m_format == HdFormatFloat32) { auto srcData = reinterpret_cast(getBuffer); @@ -301,44 +353,25 @@ void HdRprApiAov::Resize(int width, int height, HdFormat format) { } void HdRprApiAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { - if (m_dirtyBits & ChangeTracker::DirtyFormat) { - OnFormatChange(rifContext); - } if (m_dirtyBits & ChangeTracker::DirtySize) { - OnSizeChange(rifContext); + m_filterEnabled = m_aov && m_format != HdFormatFloat32Vec4; + if (m_filterEnabled) { + auto fbDesc = m_aov->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float) != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + } + } + else { + m_outputBuffer.clear(); + } } 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 - 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)); - } -} - HdRprApiColorAov::HdRprApiColorAov(HdFormat format, std::shared_ptr rawColorAov, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) : HdRprApiAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kColorAlpha), true), format) , m_retainedRawColor(std::move(rawColorAov)) { @@ -522,7 +555,7 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) } if (m_dirtyBits & ChangeTracker::DirtySize) { - OnSizeChange(rifContext); + OnSizeChange(); } m_dirtyBits = ChangeTracker::Clean; @@ -582,7 +615,7 @@ void HdRprApiColorAov::ResizeFilter(int width, int height, Filter filterType, ri } } -void HdRprApiColorAov::OnSizeChange(rif::Context* rifContext) { +void HdRprApiColorAov::OnSizeChange() { if (!m_filter) { return; } @@ -615,25 +648,30 @@ void HdRprApiNormalAov::OnFormatChange(rif::Context* rifContext) { m_dirtyBits |= ChangeTracker::DirtySize; } -bool HdRprApiNormalAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { - auto fbDesc = m_aov->GetDesc(); - if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_cpuFilterBuffer.size()) { - m_cpuFilterBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); - } - static size_t numPixels = dstBufferSize / (3 * sizeof(float)); - if (m_cpuFilterBuffer.size() / 4 != numPixels) - { - return false; +void HdRprApiNormalAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { + if (m_dirtyBits & ChangeTracker::DirtySize) { + auto fbDesc = m_aov->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 3 * sizeof(float) != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 3 * sizeof(float)); + } + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_cpuFilterBuffer.size()) { + m_cpuFilterBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); + } } + m_dirtyBits = ChangeTracker::Clean; +} + +void HdRprApiNormalAov::Resolve() { + HdRprApiAov::Resolve(); auto resolvedFb = GetResolvedFb(); if (!resolvedFb || !resolvedFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { - return false; + return; } - CpuVec4toVec3Filter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels); - CpuRemapFilter((float*)dstBuffer, (float*)dstBuffer, numPixels * 3, 0.0, 1.0, -1.0, 1.0); - return true; + size_t numPixels = m_cpuFilterBuffer.size() / 4; + CpuVec4toVec3Filter(m_cpuFilterBuffer.data(), (float*)m_outputBuffer.data(), numPixels); + CpuRemapFilter((float*)m_outputBuffer.data(), (float*)m_outputBuffer.data(), numPixels * 3, 0.0, 1.0, -1.0, 1.0); } void HdRprApiComputedAov::Resize(int width, int height, HdFormat format) { @@ -669,7 +707,7 @@ bool HdRprApiDepthAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { if (cpuFilterBufferSize() != m_cpuFilterBuffer.size()) { m_cpuFilterBuffer.resize(cpuFilterBufferSize()); } - static size_t numPixels = dstBufferSize / sizeof(float); + static size_t numPixels = dstBufferSize / 4 / sizeof(float); if (m_cpuFilterBuffer.size() / 4 != numPixels) { return false; @@ -681,6 +719,7 @@ bool HdRprApiDepthAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { } CpuNdcFilter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels, m_viewProjectionMatrix); + //memcpy(dstBuffer, m_cpuFilterBuffer.data(), dstBufferSize); auto opacityFb = m_retainedOpacityAov->GetResolvedFb(); if (!opacityFb || !opacityFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { @@ -688,7 +727,7 @@ bool HdRprApiDepthAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { } CpuOpacityMaskFilter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels); - CpuRemapFilter((float*)dstBuffer, (float*)dstBuffer, numPixels, -1, 1, 0, 1.0); + CpuRemapFilter((float*)dstBuffer, (float*)dstBuffer, numPixels * 4, -1, 1, 0, 1.0f); return true; } @@ -703,16 +742,24 @@ HdRprApiIdMaskAov::HdRprApiIdMaskAov( } } -bool HdRprApiIdMaskAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { - static size_t numPixels = dstBufferSize / (4 * sizeof(float)); - +void HdRprApiIdMaskAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { + if (m_dirtyBits & ChangeTracker::DirtySize) { + auto fbDesc = m_baseIdAov->GetAovFb()->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float) != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + } + } + m_dirtyBits = ChangeTracker::Clean; +} + +void HdRprApiIdMaskAov::Resolve() { auto resolvedFb = m_baseIdAov->GetResolvedFb(); - if (!resolvedFb || !resolvedFb->GetData(dstBuffer, dstBufferSize)) { - return false; + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size())) { + return; } - CpuFillMaskFilter((float*)dstBuffer, numPixels); - return true; + size_t numPixels = m_outputBuffer.size() / 4 / sizeof(float); + CpuFillMaskFilter((float*)m_outputBuffer.data(), numPixels); } HdRprApiScCompositeAOV::HdRprApiScCompositeAOV(int width, int height, HdFormat format, diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index 3a91e1cc4..9274430ed 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -43,7 +43,7 @@ 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); @@ -51,16 +51,17 @@ class HdRprApiAov { 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 OnFormatChange(rif::Context* rifContext); + //virtual void OnSizeChange(); protected: HdRprAovDescriptor const& m_aovDescriptor; HdFormat m_format; std::unique_ptr m_aov; std::unique_ptr m_resolved; - std::unique_ptr m_filter; + bool m_filterEnabled = false; std::vector m_tmpBuffer; + std::vector m_outputBuffer; enum ChangeTracker { Clean = 0, @@ -116,8 +117,8 @@ class HdRprApiColorAov : public HdRprApiAov { void SetGamma(GammaParams const& params); protected: - void OnFormatChange(rif::Context* rifContext) override; - void OnSizeChange(rif::Context* rifContext) override; + void OnFormatChange(rif::Context* rifContext);// override; + void OnSizeChange();// override; private: enum Filter { kFilterNone = 0, @@ -138,6 +139,8 @@ class HdRprApiColorAov : public HdRprApiAov { bool CanComposeAlpha(); private: + std::unique_ptr m_filter; + std::shared_ptr m_retainedRawColor; std::shared_ptr m_retainedOpacity; @@ -159,9 +162,11 @@ class HdRprApiNormalAov : public HdRprApiAov { HdRprApiNormalAov(int width, int height, HdFormat format, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); ~HdRprApiNormalAov() override = default; + + void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; + void Resolve() override; protected: - void OnFormatChange(rif::Context* rifContext) override; - bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; + void OnFormatChange(rif::Context* rifContext);// override; private: std::vector m_cpuFilterBuffer; }; @@ -205,8 +210,9 @@ class HdRprApiIdMaskAov : public HdRprApiComputedAov { int width, int height, HdFormat format, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, rif::Context* rifContext); ~HdRprApiIdMaskAov() override = default; -protected: - bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; + + void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; + void Resolve() override; private: std::shared_ptr m_baseIdAov; std::vector m_cpuFilterBuffer; From f16f6831130db47dcdf7edff75a4647fb1229566 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Wed, 22 Nov 2023 01:57:52 +0100 Subject: [PATCH 07/16] further rif replacement --- pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 71 ++++++++++++++------------ pxr/imaging/plugin/hdRpr/rprApiAov.h | 12 ++--- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index 2ad1a04dd..b8b724be0 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -79,20 +79,12 @@ void CpuNdcFilter(float* src, float* dest, size_t length, const GfMatrix4f& view for (int i = begin; i < end; ++i) { float norm = std::max(src[i * 4 + 3], 1.0f); GfVec4f pos(src[i * 4] / norm, src[i * 4 + 1] / norm, src[i * 4 + 2] / norm, 1.0f); - GfVec4f posResult = viewProjectionMatrix.GetOrthonormalized() * pos; - dest[i * 4] = std::max(std::min(posResult[2] / posResult[3], 0.9f), -0.9f); - dest[i * 4 + 1] = 0;// posResult[2] / posResult[3]; - dest[i * 4 + 2] = 0;// posResult[2] / posResult[3]; - dest[i * 4 + 3] = 1.0f; - - /*float norm = std::max(src[i * 4 + 3], 1.0f); - GfVec4f pos(src[i * 4] / norm, src[i * 4 + 1] / norm, src[i * 4 + 2] / norm, 1.0f); GfVec4f posResult = viewProjectionMatrix * pos; float depth = posResult[2] / posResult[3]; - dest[i * 4] = depth; + dest[i * 4] = depth; dest[i * 4 + 1] = depth; dest[i * 4 + 2] = depth; - dest[i * 4 + 3] = 1.0f;*/ + dest[i * 4 + 3] = 1.0f; } }); } @@ -353,17 +345,19 @@ void HdRprApiAov::Resize(int width, int height, HdFormat format) { } void HdRprApiAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { + if (m_dirtyBits & ChangeTracker::DirtyFormat) { + m_filterEnabled = (rifContext && m_format != HdFormatFloat32Vec4); + if (m_filterEnabled) { + m_dirtyBits |= ChangeTracker::DirtySize; + } + } if (m_dirtyBits & ChangeTracker::DirtySize) { - m_filterEnabled = m_aov && m_format != HdFormatFloat32Vec4; if (m_filterEnabled) { auto fbDesc = m_aov->GetDesc(); if (fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float) != m_outputBuffer.size()) { m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); } } - else { - m_outputBuffer.clear(); - } } m_dirtyBits = ChangeTracker::Clean; } @@ -448,6 +442,13 @@ void HdRprApiColorAov::SetGamma(GammaParams const& params) { } } +bool HdRprApiColorAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { + if (m_filter) { + return ReadRifImage(m_filter->GetOutput(), dstBuffer, dstBufferSize); + } + return HdRprApiAov::GetDataImpl(dstBuffer, dstBufferSize); +} + void HdRprApiColorAov::SetTonemapFilterParams(rif::Filter* filter) { filter->SetParam("exposureTime", m_tonemap.exposureTime); filter->SetParam("sensitivity", m_tonemap.sensitivity); @@ -583,6 +584,9 @@ bool HdRprApiColorAov::GetData(void* dstBuffer, size_t dstBufferSize) { void HdRprApiColorAov::Resolve() { HdRprApiAov::Resolve(); + if (m_filter) { + m_filter->Resolve(); + } for (auto& auxFilter : m_auxFilters) { auxFilter.second->Resolve(); @@ -696,39 +700,42 @@ HdRprApiDepthAov::HdRprApiDepthAov(int width, int height, HdFormat format, , m_retainedOpacityAov(opacityAov) , m_viewProjectionMatrix(GfMatrix4f()) { - m_cpuFilterBuffer.resize(cpuFilterBufferSize()); + // m_cpuFilterBuffer.resize(cpuFilterBufferSize()); } void HdRprApiDepthAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { 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 * sizeof(float) != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + } + } + m_dirtyBits = ChangeTracker::Clean; } -bool HdRprApiDepthAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { - if (cpuFilterBufferSize() != m_cpuFilterBuffer.size()) { - m_cpuFilterBuffer.resize(cpuFilterBufferSize()); - } - static size_t numPixels = dstBufferSize / 4 / sizeof(float); - if (m_cpuFilterBuffer.size() / 4 != numPixels) - { - return false; - } +void HdRprApiDepthAov::Resolve() { + HdRprApiAov::Resolve(); + static size_t numPixels = m_cpuFilterBuffer.size() / 4; + auto coordinateFb = m_retainedWorldCoordinateAov->GetResolvedFb(); - if (!coordinateFb || !coordinateFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { - return false; + if (!coordinateFb || !coordinateFb->GetData(m_outputBuffer.data(), m_outputBuffer.size())) { + return; } - CpuNdcFilter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels, m_viewProjectionMatrix); - //memcpy(dstBuffer, m_cpuFilterBuffer.data(), dstBufferSize); + CpuNdcFilter((float*)m_outputBuffer.data(), (float*)m_outputBuffer.data(), numPixels, m_viewProjectionMatrix); auto opacityFb = m_retainedOpacityAov->GetResolvedFb(); if (!opacityFb || !opacityFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { - return false; + return; } - CpuOpacityMaskFilter(m_cpuFilterBuffer.data(), (float*)dstBuffer, numPixels); - CpuRemapFilter((float*)dstBuffer, (float*)dstBuffer, numPixels * 4, -1, 1, 0, 1.0f); - return true; + CpuOpacityMaskFilter(m_cpuFilterBuffer.data(), (float*)m_outputBuffer.data(), numPixels); + CpuRemapFilter((float*)m_outputBuffer.data(), (float*)m_outputBuffer.data(), numPixels * 4, -1, 1, 0, 1.0f); } HdRprApiIdMaskAov::HdRprApiIdMaskAov( diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index 9274430ed..b050bf870 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -50,9 +50,6 @@ class HdRprApiAov { protected: HdRprApiAov(HdRprAovDescriptor const& aovDescriptor, HdFormat format) : m_aovDescriptor(aovDescriptor), m_format(format) {}; - - //virtual void OnFormatChange(rif::Context* rifContext); - //virtual void OnSizeChange(); protected: HdRprAovDescriptor const& m_aovDescriptor; HdFormat m_format; @@ -116,6 +113,7 @@ class HdRprApiColorAov : public HdRprApiAov { }; void SetGamma(GammaParams const& params); + bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; protected: void OnFormatChange(rif::Context* rifContext);// override; void OnSizeChange();// override; @@ -139,12 +137,11 @@ class HdRprApiColorAov : public HdRprApiAov { bool CanComposeAlpha(); private: - std::unique_ptr m_filter; - std::shared_ptr m_retainedRawColor; std::shared_ptr m_retainedOpacity; Filter m_mainFilterType = kFilterNone; + std::unique_ptr m_filter; std::vector>> m_auxFilters; uint32_t m_enabledFilters = kFilterNone; @@ -193,8 +190,9 @@ class HdRprApiDepthAov : public HdRprApiComputedAov { ~HdRprApiDepthAov() override = default; void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; -protected: - bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; + void Resolve() override; +//protected: + //bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; private: inline size_t cpuFilterBufferSize() const { return m_width * m_height * 4; } // Vec4f for each pixel From 6c567210bdcc2670143d04d9bde0f5a99070c3f2 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Wed, 22 Nov 2023 18:27:55 +0100 Subject: [PATCH 08/16] further removal --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 101 ++++------------ pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 157 ++++++++++++++----------- pxr/imaging/plugin/hdRpr/rprApiAov.h | 26 +--- 3 files changed, 114 insertions(+), 170 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 26051aca5..7ad1db48a 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -56,6 +56,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" @@ -4343,92 +4344,34 @@ Don't show this message again? 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; + imageDesc.num_components = 4; + + size_t totalNumComponents = imageDesc.num_components * imageDesc.image_width * imageDesc.image_height; + size_t imageSize = bytesPerComponent * totalNumComponents; + std::vector mappedData(imageSize); + std::memcpy(mappedData.data(), textureData->GetData(), imageSize); + std::vector mappedDataFloat(totalNumComponents); + WorkParallelForN(imageDesc.num_components * imageDesc.image_width * imageDesc.image_height, + [&](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(mappedDataFloat.data(), imageDesc.image_width, imageDesc.image_height, (float*)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; diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index b8b724be0..b6100c4c9 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -62,10 +62,10 @@ void CpuRemapFilter(float* src, float* dest, size_t length, float srcLo, float s }}); } -void CpuVec4toVec3Filter(float* src, float* dest, size_t length) { - WorkParallelForN(length, +void CpuVec4toVec3Filter(float* src, float* dest, size_t numPixels) { + WorkParallelForN(numPixels, [&](size_t begin, size_t end) { - for (int i = 0; i < length; ++i) { + for (int i = 0; i < numPixels; ++i) { dest[i * 3] = src[i * 4]; dest[i * 3 + 1] = src[i * 4 + 1]; dest[i * 3 + 2] = src[i * 4 + 2]; @@ -73,8 +73,8 @@ void CpuVec4toVec3Filter(float* src, float* dest, size_t length) { }); } -void CpuNdcFilter(float* src, float* dest, size_t length, const GfMatrix4f& viewProjectionMatrix) { - WorkParallelForN(length, +void CpuNdcFilter(float* src, float* 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 * 4 + 3], 1.0f); @@ -89,8 +89,8 @@ void CpuNdcFilter(float* src, float* dest, size_t length, const GfMatrix4f& view }); } -void CpuOpacityFilter(float* opacity, float* srcdest, size_t length) { - WorkParallelForN(length, +void CpuOpacityFilter(float* opacity, float* srcdest, size_t numPixels) { + WorkParallelForN(numPixels, [&](size_t begin, size_t end) { for (int i = begin; i < end; ++i) { float op = opacity[i * 4]; @@ -102,8 +102,8 @@ void CpuOpacityFilter(float* opacity, float* srcdest, size_t length) { }); } -void CpuOpacityMaskFilter(float* opacity, float* srcdest, size_t length) { - WorkParallelForN(length, +void CpuOpacityMaskFilter(float* opacity, float* srcdest, size_t numPixels) { + WorkParallelForN(numPixels, [&](size_t begin, size_t end) { for (int i = begin; i < end; ++i) { float op = opacity[i * 4]; @@ -117,8 +117,8 @@ void CpuOpacityMaskFilter(float* opacity, float* srcdest, size_t length) { }); } -void CpuFillMaskFilter(float* srcdest, size_t length) { - WorkParallelForN(length, +void CpuFillMaskFilter(float* 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 * 4] * 256) + (unsigned int)(srcdest[i * 4 + 1] * 256 * 256) + (unsigned int)(srcdest[i * 4 + 2] * 256 * 256 * 256); @@ -157,7 +157,7 @@ void CpuResampleNearest(float* src, size_t srcWidth, size_t srcHeight, float* de for (int y = begin; y < end; ++y) { for (int x = 0; x < destWidth; ++x) { int cx = xratio * x; - int cy = xratio * y; + int cy = yratio * y; dest[(y * destWidth + x) * 4] = src[(cy * srcWidth + cx) * 4]; dest[(y * destWidth + x) * 4 + 1] = src[(cy * srcWidth + cx) * 4 + 1]; dest[(y * destWidth + x) * 4 + 2] = src[(cy * srcWidth + cx) * 4 + 2]; @@ -166,6 +166,39 @@ void CpuResampleNearest(float* src, size_t srcWidth, size_t srcHeight, float* de }}); } +void CpuGammaCorrection(float* 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 * 4] = std::powf(srcdest[i * 4], _1_g); + srcdest[i * 4 + 1] = std::powf(srcdest[i * 4 + 1], _1_g); + srcdest[i * 4 + 2] = std::powf(srcdest[i * 4 + 2], _1_g); + // skiping alpha + } + }); +} + +void CpuTonemap(float* srcdest, size_t numPixels, float gamma, float exposureTime, float sensitivity, float fstop) { + if (gamma == 0 || fstop == 0) { + return; + } + float h = (0.65f * 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 * 4] = std::powf(srcdest[i * 4] * h, _1_g); + srcdest[i * 4 + 1] = std::powf(srcdest[i * 4 + 1] * h, _1_g); + srcdest[i * 4 + 2] = std::powf(srcdest[i * 4 + 2] * h, _1_g); + // skiping alpha + } + }); +} + HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata, std::unique_ptr filter) : m_aovDescriptor(HdRprAovRegistry::GetInstance().GetAovDesc(rprAovType, false)) @@ -557,6 +590,19 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) if (m_dirtyBits & ChangeTracker::DirtySize) { OnSizeChange(); + + auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); + if (fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float) != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + } + 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 { + m_opacityBuffer.clear(); + } } m_dirtyBits = ChangeTracker::Clean; @@ -591,6 +637,36 @@ void HdRprApiColorAov::Resolve() { for (auto& auxFilter : m_auxFilters) { auxFilter.second->Resolve(); } + + auto resolvedFb = m_retainedRawColor->GetResolvedFb(); + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size())) { + return; + } + + size_t numPixels = m_outputBuffer.size() / 4 / sizeof(float); + if ((m_enabledFilters & kFilterComposeOpacity) || + (m_enabledFilters & kFilterTonemap) || + (m_enabledFilters & kFilterGamma)) { + + if (m_enabledFilters & kFilterTonemap) { + CpuTonemap((float*)m_outputBuffer.data(), numPixels, m_tonemap.gamma, m_tonemap.exposureTime, m_tonemap.sensitivity, m_tonemap.fstop); + } + if (m_enabledFilters & kFilterGamma) { + CpuGammaCorrection((float*)m_outputBuffer.data(), numPixels, m_gamma.value); + } + if (m_enabledFilters & kFilterComposeOpacity) { + auto resolvedOpFb = m_retainedOpacity->GetResolvedFb(); + if (!resolvedOpFb || !resolvedOpFb->GetData(m_opacityBuffer.data(), m_opacityBuffer.size() * sizeof(float))) { + return; + } + + CpuOpacityFilter(m_opacityBuffer.data(), (float*)m_outputBuffer.data(), numPixels); + } + } + else if (m_enabledFilters & kFilterResample) { + auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); + CpuResampleNearest((float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height, (float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height); + } } void HdRprApiColorAov::OnFormatChange(rif::Context* rifContext) { @@ -769,61 +845,4 @@ void HdRprApiIdMaskAov::Resolve() { CpuFillMaskFilter((float*)m_outputBuffer.data(), numPixels); } -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 }; - } - } - - return true; -} - PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index b050bf870..d48f704b0 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -25,6 +25,8 @@ PXR_NAMESPACE_OPEN_SCOPE class HdRprApi; struct RprUsdContextMetadata; +void CpuResampleNearest(float* src, size_t srcWidth, size_t srcHeight, float* dest, size_t destWidth, size_t destHeight); + class HdRprApiAov { public: HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, @@ -121,8 +123,6 @@ class HdRprApiColorAov : public HdRprApiAov { enum Filter { kFilterNone = 0, kFilterResample = 1 << 0, - //kFilterAIDenoise = 1 << 1, - //kFilterEAWDenoise = 1 << 2, kFilterComposeOpacity = 1 << 3, kFilterTonemap = 1 << 4, kFilterGamma = 1 << 5 @@ -152,6 +152,8 @@ class HdRprApiColorAov : public HdRprApiAov { int m_width = 0; int m_height = 0; + + std::vector m_opacityBuffer; }; class HdRprApiNormalAov : public HdRprApiAov { @@ -191,8 +193,6 @@ class HdRprApiDepthAov : public HdRprApiComputedAov { void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; void Resolve() override; -//protected: - //bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; private: inline size_t cpuFilterBufferSize() const { return m_width * m_height * 4; } // Vec4f for each pixel @@ -216,24 +216,6 @@ class HdRprApiIdMaskAov : public HdRprApiComputedAov { std::vector m_cpuFilterBuffer; }; -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; -}; - PXR_NAMESPACE_CLOSE_SCOPE #endif // HDRPR_RPR_API_AOV_H From 5307abffd8e1492803008b3e289397617be04566 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Thu, 23 Nov 2023 10:01:52 +0100 Subject: [PATCH 09/16] colorWithTransparency refs removal --- pxr/imaging/plugin/hdRpr/aovDescriptor.cpp | 1 - pxr/imaging/plugin/hdRpr/aovDescriptor.h | 1 - pxr/imaging/plugin/hdRpr/rprApi.cpp | 20 -------------------- 3 files changed, 22 deletions(-) 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/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 7ad1db48a..caffd6c46 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -4220,26 +4220,6 @@ Don't show this message again? } newAov = new HdRprApiDepthAov(width, height, format, std::move(worldCoordinateAov), std::move(opacityAov), m_rprContext.get(), m_rprContextMetadata); - } - 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()); - } else if (TfStringStartsWith(aovName.GetString(), "lpe")) { newAov = new HdRprApiAov(rpr::Aov(aovDesc.id), width, height, format, m_rprContext.get(), m_rprContextMetadata, m_rifContext.get()); aovCustomDestructor = [this](HdRprApiAov* aov) { From 3000cf6a241c6047b7a80e673c17eddc29272cf6 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Thu, 23 Nov 2023 20:57:54 +0100 Subject: [PATCH 10/16] filter refactor --- pxr/imaging/plugin/hdRpr/rprApi.cpp | 71 +-- pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 656 ++++++++----------------- pxr/imaging/plugin/hdRpr/rprApiAov.h | 77 ++- 3 files changed, 253 insertions(+), 551 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index caffd6c46..551035977 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -18,10 +18,6 @@ using json = nlohmann::json; #include "rprApiAov.h" #include "aovDescriptor.h" -#include "rifcpp/rifFilter.h" -#include "rifcpp/rifImage.h" -#include "rifcpp/rifError.h" - #include "config.h" #include "camera.h" #include "debugCodes.h" @@ -468,7 +464,6 @@ class HdRprApiImpl { try { m_cacheCreationRequired = !CacheCreated(); InitRpr(); - InitRif(); InitAovs(); { @@ -1752,10 +1747,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); @@ -2585,7 +2576,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(); } @@ -3839,35 +3830,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)); @@ -4206,7 +4168,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) { @@ -4221,7 +4183,7 @@ Don't show this message again? 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 @@ -4247,10 +4209,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()); } @@ -4304,10 +4266,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; @@ -4315,13 +4273,8 @@ 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(); if (textureMetadata.glType != GL_UNSIGNED_BYTE || textureMetadata.glFormat != GL_RGBA) { @@ -4329,14 +4282,14 @@ Don't show this message again? return false; } const uint8_t bytesPerComponent = 1; - imageDesc.num_components = 4; + const size_t numComponents = 4; - size_t totalNumComponents = imageDesc.num_components * imageDesc.image_width * imageDesc.image_height; + 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(imageDesc.num_components * imageDesc.image_width * imageDesc.image_height, + WorkParallelForN(numComponents * imageWidth * imageHeight, [&](size_t begin, size_t end) { for (int i = begin; i < end; ++i) { mappedDataFloat[i] = (float)mappedData[i] / 256.0f; @@ -4345,7 +4298,7 @@ Don't show this message again? auto colorRb = static_cast(colorOutputRb->aovBinding->renderBuffer); if (auto colorRbData = colorRb->GetPointerForWriting()) { - CpuResampleNearest(mappedDataFloat.data(), imageDesc.image_width, imageDesc.image_height, (float*)colorRbData, colorRb->GetWidth(), colorRb->GetHeight()); + CpuResampleNearest((GfVec4f*)mappedDataFloat.data(), imageWidth, imageHeight, (GfVec4f*)colorRbData, colorRb->GetWidth(), colorRb->GetHeight()); } else { return false; @@ -4406,8 +4359,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 b6100c4c9..46aceec7e 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -14,7 +14,6 @@ limitations under the License. #include "rprApiAov.h" #include "rprApi.h" #include "rprApiFramebuffer.h" -#include "rifcpp/rifError.h" #include "pxr/imaging/rprUsd/contextMetadata.h" #include "pxr/imaging/rprUsd/error.h" @@ -22,106 +21,124 @@ limitations under the License. PXR_NAMESPACE_OPEN_SCOPE -namespace { - - bool ReadRifImage(rif_image image, void* dstBuffer, size_t dstBufferSize) { - if (!image || !dstBuffer) { - return false; - } +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; + }}); +} - 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 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* data = nullptr; - rifStatus = rifImageMap(image, RIF_IMAGE_MAP_READ, &data); - if (rifStatus != RIF_SUCCESS) { - return false; +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]; } + }); +} - std::memcpy(dstBuffer, data, size); - - rifStatus = rifImageUnmap(image, data); - if (rifStatus != RIF_SUCCESS) { - TF_WARN("Failed to unmap rif image"); +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); + } } - - return true; - } - -} // namespace anonymous - -void CpuRemapFilter(float* src, float* dest, size_t length, float srcLo, float srcHi, float dstLo, float dstHi) { - WorkParallelForN(length, + }); + + int32_t* destAsInt = (int32_t*)dest; + WorkParallelForN(numPixels, [&](size_t begin, size_t end) { for (size_t i = begin; i < end; ++i) { - dest[i] = ((src[i] - srcLo) / (srcHi - srcLo)) * (dstHi - dstLo) + dstLo; - }}); + destAsInt[i] -= 1; + } + }); } -void CpuVec4toVec3Filter(float* src, float* dest, size_t numPixels) { - WorkParallelForN(numPixels, +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 (int i = 0; i < numPixels; ++i) { - dest[i * 3] = src[i * 4]; - dest[i * 3 + 1] = src[i * 4 + 1]; - dest[i * 3 + 2] = src[i * 4 + 2]; + for (size_t i = begin; i < end; ++i) { + dest[i] = (srcAsInt[i] & 0xFFFFFF) - 1; } }); } -void CpuNdcFilter(float* src, float* dest, size_t numPixels, const GfMatrix4f& viewProjectionMatrix) { +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 * 4 + 3], 1.0f); - GfVec4f pos(src[i * 4] / norm, src[i * 4 + 1] / norm, src[i * 4 + 2] / norm, 1.0f); + 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 * 4] = depth; - dest[i * 4 + 1] = depth; - dest[i * 4 + 2] = depth; - dest[i * 4 + 3] = 1.0f; + dest[i][0] = depth; + dest[i][1] = depth; + dest[i][2] = depth; + dest[i][3] = 1.0f; } }); } -void CpuOpacityFilter(float* opacity, float* srcdest, size_t numPixels) { +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 * 4]; - srcdest[i * 4] *= op; - srcdest[i * 4 + 1] *= op; - srcdest[i * 4 + 2] *= op; - srcdest[i * 4 + 3] = op; + float op = opacity[i][0]; + srcdest[i][0] *= op; + srcdest[i][1] *= op; + srcdest[i][2] *= op; + srcdest[i][3] = op; } }); } -void CpuOpacityMaskFilter(float* opacity, float* srcdest, size_t numPixels) { +void CpuOpacityMaskFilter(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 * 4]; - if (op == 0.0f) { - srcdest[i * 4] = 1.0f; - srcdest[i * 4 + 1] = 1.0f; - srcdest[i * 4 + 1] = 1.0f; - srcdest[i * 4 + 1] = 1.0f; + 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(float* srcdest, size_t numPixels) { +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 * 4] * 256) + (unsigned int)(srcdest[i * 4 + 1] * 256 * 256) + (unsigned int)(srcdest[i * 4 + 2] * 256 * 256 * 256); + 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; @@ -132,19 +149,19 @@ void CpuFillMaskFilter(float* srcdest, size_t numPixels) { v0 += ((v1 << 4) + 0xa341316c) ^ (v1 + s0) ^ ((v1 >> 5) + 0xc8013ea4); v1 += ((v0 << 4) + 0xad90777d) ^ (v0 + s0) ^ ((v0 >> 5) + 0x7e95761e); } - srcdest[i * 4] = (v0 & 0xFFFF) / (float)(0xFFFF); - srcdest[i * 4 + 1] = (v0 >> 16) / (float)(0xFFFF); - srcdest[i * 4 + 2] = (v1 & 0xFFFF) / (float)(0xFFFF); - srcdest[i * 4 + 3] = 1.0f; + 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 * 4] = srcdest[i * 4 + 1] = srcdest[i * 4 + 2] = srcdest[i * 4 + 3] = 0; + srcdest[i][0] = srcdest[i][1] = srcdest[i][2] = srcdest[i][3] = 0; } } }); } -void CpuResampleNearest(float* src, size_t srcWidth, size_t srcHeight, float* dest, size_t destWidth, size_t destHeight) { +void CpuResampleNearest(GfVec4f* src, size_t srcWidth, size_t srcHeight, GfVec4f* dest, size_t destWidth, size_t destHeight) { if (destWidth <= 1 || destHeight <= 1) { return; } @@ -158,15 +175,15 @@ void CpuResampleNearest(float* src, size_t srcWidth, size_t srcHeight, float* de for (int x = 0; x < destWidth; ++x) { int cx = xratio * x; int cy = yratio * y; - dest[(y * destWidth + x) * 4] = src[(cy * srcWidth + cx) * 4]; - dest[(y * destWidth + x) * 4 + 1] = src[(cy * srcWidth + cx) * 4 + 1]; - dest[(y * destWidth + x) * 4 + 2] = src[(cy * srcWidth + cx) * 4 + 2]; - dest[(y * destWidth + x) * 4 + 3] = src[(cy * srcWidth + cx) * 4 + 3]; + 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(float* srcdest, size_t numPixels, float gamma) { +void CpuGammaCorrection(GfVec4f* srcdest, size_t numPixels, float gamma) { if (gamma == 0) { return; } @@ -174,39 +191,36 @@ void CpuGammaCorrection(float* srcdest, size_t numPixels, float gamma) { WorkParallelForN(numPixels, [&](size_t begin, size_t end) { for (int i = begin; i < end; ++i) { - srcdest[i * 4] = std::powf(srcdest[i * 4], _1_g); - srcdest[i * 4 + 1] = std::powf(srcdest[i * 4 + 1], _1_g); - srcdest[i * 4 + 2] = std::powf(srcdest[i * 4 + 2], _1_g); + srcdest[i][0] = std::powf(srcdest[i][0], _1_g); + srcdest[i][1] = std::powf(srcdest[i][1], _1_g); + srcdest[i][2] = std::powf(srcdest[i][2], _1_g); // skiping alpha } }); } -void CpuTonemap(float* srcdest, size_t numPixels, float gamma, float exposureTime, float sensitivity, float fstop) { +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 * sensitivity * exposureTime) / (fstop * fstop); + 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 * 4] = std::powf(srcdest[i * 4] * h, _1_g); - srcdest[i * 4 + 1] = std::powf(srcdest[i * 4 + 1] * h, _1_g); - srcdest[i * 4 + 2] = std::powf(srcdest[i * 4 + 2] * h, _1_g); + srcdest[i][0] = std::powf(srcdest[i][0] * h, _1_g); + srcdest[i][1] = std::powf(srcdest[i][1] * h, _1_g); + srcdest[i][2] = std::powf(srcdest[i][2] * h, _1_g); // skiping alpha } }); } 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_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); @@ -216,43 +230,27 @@ 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) { - return nullptr; - } - - 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_filterEnabled) { assert(m_outputBuffer.size() > 0); auto resolvedFb = GetResolvedFb(); - if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size())) { + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { return; } if (m_aov) { auto fbDesc = m_aov->GetDesc(); - CpuResampleNearest((float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height, (float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height); + CpuResampleNearest((GfVec4f*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height, (GfVec4f*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height); } } } @@ -265,8 +263,16 @@ void HdRprApiAov::Clear() { } bool HdRprApiAov::GetDataImpl(void* dstBuffer, size_t 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()) { + if (dstBufferSize != m_outputBuffer.size() * sizeof(float)) { return false; } memcpy(dstBuffer, m_outputBuffer.data(), dstBufferSize); @@ -282,84 +288,7 @@ bool HdRprApiAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { } bool HdRprApiAov::GetData(void* dstBuffer, size_t dstBufferSize) { - auto getBuffer = dstBuffer; - if (!m_filterEnabled) - { - 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_filterEnabled) - { - 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) { @@ -375,11 +304,25 @@ 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) { - m_filterEnabled = (rifContext && m_format != HdFormatFloat32Vec4); + m_filterEnabled = (m_format != HdFormatFloat32Vec4); if (m_filterEnabled) { m_dirtyBits |= ChangeTracker::DirtySize; } @@ -387,8 +330,8 @@ void HdRprApiAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { if (m_dirtyBits & ChangeTracker::DirtySize) { if (m_filterEnabled) { auto fbDesc = m_aov->GetDesc(); - if (fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float) != m_outputBuffer.size()) { - m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); } } } @@ -399,6 +342,42 @@ HdRprApiFramebuffer* HdRprApiAov::GetResolvedFb() { return (m_resolved ? m_resolved : m_aov).get(); } +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::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()); + } +} + HdRprApiColorAov::HdRprApiColorAov(HdFormat format, std::shared_ptr rawColorAov, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) : HdRprApiAov(HdRprAovRegistry::GetInstance().GetAovDesc(rpr::Aov(kColorAlpha), true), format) , m_retainedRawColor(std::move(rawColorAov)) { @@ -430,24 +409,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) { @@ -455,38 +417,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; - } - } - } - } - } -} - -bool HdRprApiColorAov::GetDataImpl(void* dstBuffer, size_t dstBufferSize) { - if (m_filter) { - return ReadRifImage(m_filter->GetOutput(), dstBuffer, dstBufferSize); - } - return HdRprApiAov::GetDataImpl(dstBuffer, dstBufferSize); -} - -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() { @@ -504,96 +435,20 @@ 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; - } - - // 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_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; - } - ); - } - } - 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; - } - - // Signal to update inputs m_dirtyBits |= ChangeTracker::DirtySize; } if (m_dirtyBits & ChangeTracker::DirtySize) { - OnSizeChange(); - auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); - if (fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float) != m_outputBuffer.size()) { - m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + 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) { if (fbDesc.fb_width * fbDesc.fb_height * 4 != m_opacityBuffer.size()) { @@ -605,54 +460,24 @@ void HdRprApiColorAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) } } m_dirtyBits = ChangeTracker::Clean; - - for (auto& auxFilter : m_auxFilters) { - auxFilter.second->Update(); - } - if (m_filter) { - m_filter->Update(); - } } -bool HdRprApiColorAov::GetData(void* dstBuffer, size_t dstBufferSize) { - if (!m_filter) { - if (auto resolvedRawColorFb = m_retainedRawColor->GetResolvedFb()) { - return resolvedRawColorFb->GetData(dstBuffer, dstBufferSize); - } - else { - return false; - } - } - else { - return HdRprApiAov::GetData(dstBuffer, dstBufferSize); - } -} - -void HdRprApiColorAov::Resolve() { - HdRprApiAov::Resolve(); - if (m_filter) { - m_filter->Resolve(); - } - - for (auto& auxFilter : m_auxFilters) { - auxFilter.second->Resolve(); - } - +void HdRprApiColorAov::ResolveImpl() { auto resolvedFb = m_retainedRawColor->GetResolvedFb(); - if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size())) { + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { return; } - size_t numPixels = m_outputBuffer.size() / 4 / sizeof(float); + size_t numPixels = m_outputBuffer.size() / 4; if ((m_enabledFilters & kFilterComposeOpacity) || (m_enabledFilters & kFilterTonemap) || (m_enabledFilters & kFilterGamma)) { if (m_enabledFilters & kFilterTonemap) { - CpuTonemap((float*)m_outputBuffer.data(), numPixels, m_tonemap.gamma, m_tonemap.exposureTime, m_tonemap.sensitivity, m_tonemap.fstop); + CpuTonemap((GfVec4f*)m_outputBuffer.data(), numPixels, m_tonemap.gamma, m_tonemap.exposureTime, m_tonemap.sensitivity, m_tonemap.fstop); } if (m_enabledFilters & kFilterGamma) { - CpuGammaCorrection((float*)m_outputBuffer.data(), numPixels, m_gamma.value); + CpuGammaCorrection((GfVec4f*)m_outputBuffer.data(), numPixels, m_gamma.value); } if (m_enabledFilters & kFilterComposeOpacity) { auto resolvedOpFb = m_retainedOpacity->GetResolvedFb(); @@ -660,111 +485,55 @@ void HdRprApiColorAov::Resolve() { return; } - CpuOpacityFilter(m_opacityBuffer.data(), (float*)m_outputBuffer.data(), numPixels); + CpuOpacityFilter((GfVec4f*)m_opacityBuffer.data(), (GfVec4f*)m_outputBuffer.data(), numPixels); } } else if (m_enabledFilters & kFilterResample) { auto fbDesc = m_retainedRawColor->GetAovFb()->GetDesc(); - CpuResampleNearest((float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height, (float*)m_outputBuffer.data(), fbDesc.fb_width, fbDesc.fb_height); + 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); - } -} - -void HdRprApiColorAov::OnSizeChange() { - 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); - } - ResizeFilter(fbDesc.fb_width, fbDesc.fb_height, m_mainFilterType, m_filter.get(), m_auxFilters.back().second->GetOutput()); - } -} - 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, nullptr) { -} - -void HdRprApiNormalAov::OnFormatChange(rif::Context* rifContext) { - m_dirtyBits |= ChangeTracker::DirtySize; + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) + : HdRprApiAov(RPR_AOV_SHADING_NORMAL, width, height, format, rprContext, rprContextMetadata) { } -void HdRprApiNormalAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { +void HdRprApiNormalAov::UpdateImpl(HdRprApi const* rprApi) { if (m_dirtyBits & ChangeTracker::DirtySize) { auto fbDesc = m_aov->GetDesc(); - if (fbDesc.fb_width * fbDesc.fb_height * 3 * sizeof(float) != m_outputBuffer.size()) { - m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 3 * sizeof(float)); - } - 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 * 3 != m_outputBuffer.size()) { + m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4); } } m_dirtyBits = ChangeTracker::Clean; } -void HdRprApiNormalAov::Resolve() { - HdRprApiAov::Resolve(); - +void HdRprApiNormalAov::ResolveImpl() { auto resolvedFb = GetResolvedFb(); - if (!resolvedFb || !resolvedFb->GetData(m_cpuFilterBuffer.data(), m_cpuFilterBuffer.size() * sizeof(float))) { + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { return; } - size_t numPixels = m_cpuFilterBuffer.size() / 4; - CpuVec4toVec3Filter(m_cpuFilterBuffer.data(), (float*)m_outputBuffer.data(), numPixels); - CpuRemapFilter((float*)m_outputBuffer.data(), (float*)m_outputBuffer.data(), numPixels * 3, 0.0, 1.0, -1.0, 1.0); + 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, @@ -779,70 +548,65 @@ HdRprApiDepthAov::HdRprApiDepthAov(int width, int height, HdFormat format, // m_cpuFilterBuffer.resize(cpuFilterBufferSize()); } -void HdRprApiDepthAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { +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 * sizeof(float) != m_outputBuffer.size()) { - m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + 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() { - HdRprApiAov::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())) { + if (!coordinateFb || !coordinateFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { return; } - CpuNdcFilter((float*)m_outputBuffer.data(), (float*)m_outputBuffer.data(), numPixels, m_viewProjectionMatrix); + 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(m_cpuFilterBuffer.data(), (float*)m_outputBuffer.data(), numPixels); - CpuRemapFilter((float*)m_outputBuffer.data(), (float*)m_outputBuffer.data(), numPixels * 4, -1, 1, 0, 1.0f); + 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"); - } } -void HdRprApiIdMaskAov::Update(HdRprApi const* rprApi, rif::Context* rifContext) { +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 * sizeof(float) != m_outputBuffer.size()) { - m_outputBuffer.resize(fbDesc.fb_width * fbDesc.fb_height * 4 * sizeof(float)); + 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 HdRprApiIdMaskAov::Resolve() { +void HdRprApiIdMaskAov::ResolveImpl() { auto resolvedFb = m_baseIdAov->GetResolvedFb(); - if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size())) { + if (!resolvedFb || !resolvedFb->GetData(m_outputBuffer.data(), m_outputBuffer.size() * sizeof(float))) { return; } - size_t numPixels = m_outputBuffer.size() / 4 / sizeof(float); - CpuFillMaskFilter((float*)m_outputBuffer.data(), numPixels); + 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 d48f704b0..131131013 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" @@ -25,19 +24,17 @@ PXR_NAMESPACE_OPEN_SCOPE class HdRprApi; struct RprUsdContextMetadata; -void CpuResampleNearest(float* src, size_t srcWidth, size_t srcHeight, float* dest, size_t destWidth, size_t destHeight); +void CpuResampleNearest(GfVec4f* src, size_t srcWidth, size_t srcHeight, GfVec4f* dest, size_t destWidth, size_t destHeight); 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(); @@ -47,20 +44,16 @@ class HdRprApiAov { 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 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; - bool m_filterEnabled = false; - std::vector m_tmpBuffer; - std::vector m_outputBuffer; + std::vector m_outputBuffer; enum ChangeTracker { Clean = 0, @@ -69,6 +62,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 +80,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,12 +114,12 @@ class HdRprApiColorAov : public HdRprApiAov { } }; void SetGamma(GammaParams const& params); - - bool GetDataImpl(void* dstBuffer, size_t dstBufferSize) override; protected: - void OnFormatChange(rif::Context* rifContext);// override; - void OnSizeChange();// override; + void UpdateImpl(HdRprApi const* rprApi); + void ResolveImpl() override; private: + void OnFormatChange(); + enum Filter { kFilterNone = 0, kFilterResample = 1 << 0, @@ -128,22 +128,11 @@ class HdRprApiColorAov : public HdRprApiAov { 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::unique_ptr m_filter; - std::vector>> m_auxFilters; - uint32_t m_enabledFilters = kFilterNone; bool m_isEnabledFiltersDirty = true; @@ -159,15 +148,13 @@ class HdRprApiColorAov : public HdRprApiAov { 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; - - void Update(HdRprApi const* rprApi, rif::Context* rifContext) override; - void Resolve() override; protected: - void OnFormatChange(rif::Context* rifContext);// override; + void UpdateImpl(HdRprApi const* rprApi) override; + void ResolveImpl() override; private: - std::vector m_cpuFilterBuffer; + //std::vector m_cpuFilterBuffer; }; class HdRprApiComputedAov : public HdRprApiAov { @@ -190,9 +177,9 @@ class HdRprApiDepthAov : public HdRprApiComputedAov { 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: inline size_t cpuFilterBufferSize() const { return m_width * m_height * 4; } // Vec4f for each pixel @@ -206,11 +193,11 @@ 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); + rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata); ~HdRprApiIdMaskAov() 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::shared_ptr m_baseIdAov; std::vector m_cpuFilterBuffer; From e0299cb4106a879006b59919399c5e482c2fdb58 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Thu, 23 Nov 2023 22:17:28 +0100 Subject: [PATCH 11/16] filters moved to a file --- pxr/imaging/plugin/hdRpr/CMakeLists.txt | 1 + pxr/imaging/plugin/hdRpr/cpuFilters.cpp | 214 ++++++++++++++++++++++++ pxr/imaging/plugin/hdRpr/cpuFilters.h | 36 ++++ pxr/imaging/plugin/hdRpr/rprApi.cpp | 1 + pxr/imaging/plugin/hdRpr/rprApiAov.cpp | 197 +--------------------- pxr/imaging/plugin/hdRpr/rprApiAov.h | 2 - 6 files changed, 253 insertions(+), 198 deletions(-) create mode 100644 pxr/imaging/plugin/hdRpr/cpuFilters.cpp create mode 100644 pxr/imaging/plugin/hdRpr/cpuFilters.h diff --git a/pxr/imaging/plugin/hdRpr/CMakeLists.txt b/pxr/imaging/plugin/hdRpr/CMakeLists.txt index 9b5ddfeba..78f490519 100644 --- a/pxr/imaging/plugin/hdRpr/CMakeLists.txt +++ b/pxr/imaging/plugin/hdRpr/CMakeLists.txt @@ -146,6 +146,7 @@ pxr_plugin(hdRpr debugCodes primvarUtil points + cpuFilters ${OptClass} diff --git a/pxr/imaging/plugin/hdRpr/cpuFilters.cpp b/pxr/imaging/plugin/hdRpr/cpuFilters.cpp new file mode 100644 index 000000000..b688b0eec --- /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] = std::powf(srcdest[i][0], _1_g); + srcdest[i][1] = std::powf(srcdest[i][1], _1_g); + srcdest[i][2] = std::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] = std::powf(srcdest[i][0] * h, _1_g); + srcdest[i][1] = std::powf(srcdest[i][1] * h, _1_g); + srcdest[i][2] = std::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/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 551035977..031913665 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -17,6 +17,7 @@ using json = nlohmann::json; #include "rprApi.h" #include "rprApiAov.h" #include "aovDescriptor.h" +#include "cpuFilters.h" #include "config.h" #include "camera.h" diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp index 46aceec7e..c3dea7416 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.cpp @@ -14,208 +14,13 @@ limitations under the License. #include "rprApiAov.h" #include "rprApi.h" #include "rprApiFramebuffer.h" +#include "cpuFilters.h" #include "pxr/imaging/rprUsd/contextMetadata.h" #include "pxr/imaging/rprUsd/error.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] = std::powf(srcdest[i][0], _1_g); - srcdest[i][1] = std::powf(srcdest[i][1], _1_g); - srcdest[i][2] = std::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] = std::powf(srcdest[i][0] * h, _1_g); - srcdest[i][1] = std::powf(srcdest[i][1] * h, _1_g); - srcdest[i][2] = std::powf(srcdest[i][2] * h, _1_g); - // skiping alpha - } - }); -} - HdRprApiAov::HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, rpr::Context* rprContext, RprUsdContextMetadata const& rprContextMetadata) : m_aovDescriptor(HdRprAovRegistry::GetInstance().GetAovDesc(rprAovType, false)) diff --git a/pxr/imaging/plugin/hdRpr/rprApiAov.h b/pxr/imaging/plugin/hdRpr/rprApiAov.h index 131131013..28010571a 100644 --- a/pxr/imaging/plugin/hdRpr/rprApiAov.h +++ b/pxr/imaging/plugin/hdRpr/rprApiAov.h @@ -24,8 +24,6 @@ PXR_NAMESPACE_OPEN_SCOPE class HdRprApi; struct RprUsdContextMetadata; -void CpuResampleNearest(GfVec4f* src, size_t srcWidth, size_t srcHeight, GfVec4f* dest, size_t destWidth, size_t destHeight); - class HdRprApiAov { public: HdRprApiAov(rpr_aov rprAovType, int width, int height, HdFormat format, From aed57002a9671fb5cb0ddaa0ecf468ca27817863 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Thu, 23 Nov 2023 23:04:40 +0100 Subject: [PATCH 12/16] rif removed from project --- .gitmodules | 3 - cmake/defaults/Packages.cmake | 1 - cmake/modules/FindRif.cmake | 76 ---- deps/RIF | 1 - pxr/imaging/plugin/hdRpr/CMakeLists.txt | 17 +- .../plugin/hdRpr/rifcpp/CMakeLists.txt | 9 - .../plugin/hdRpr/rifcpp/rifContext.cpp | 400 ------------------ pxr/imaging/plugin/hdRpr/rifcpp/rifContext.h | 67 --- pxr/imaging/plugin/hdRpr/rifcpp/rifError.h | 100 ----- pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.cpp | 379 ----------------- pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.h | 138 ------ pxr/imaging/plugin/hdRpr/rifcpp/rifImage.cpp | 58 --- pxr/imaging/plugin/hdRpr/rifcpp/rifImage.h | 37 -- pxr/imaging/plugin/hdRpr/rifcpp/rifObject.h | 57 --- 14 files changed, 2 insertions(+), 1341 deletions(-) delete mode 100644 cmake/modules/FindRif.cmake delete mode 160000 deps/RIF delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/CMakeLists.txt delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifContext.cpp delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifContext.h delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifError.h delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.cpp delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifFilter.h delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifImage.cpp delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifImage.h delete mode 100644 pxr/imaging/plugin/hdRpr/rifcpp/rifObject.h 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 78f490519..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} @@ -157,7 +146,6 @@ pxr_plugin(hdRpr RESOURCE_FILES plugInfo.json ${RESTART_REQUIRED_RESOURCE_FILE} - ${RIF_MODEL_RESOURCE_FILES} ${SCRIPT_RESOURCE_FILES} CPPFILES @@ -189,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) @@ -210,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/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 From 3ca8fa2911431f49515132383f4790f6255b27b8 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Fri, 24 Nov 2023 01:35:04 +0100 Subject: [PATCH 13/16] RPR revert --- deps/RPR | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/RPR b/deps/RPR index 440580074..d3364d3f3 160000 --- a/deps/RPR +++ b/deps/RPR @@ -1 +1 @@ -Subproject commit 440580074009d48b18019da1331d2494a253a96d +Subproject commit d3364d3f36da0ac7fc19ae30701a1f256f21a26c From d89cf19ac39dd320a8dc40a53a4a2c4d00084b53 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Fri, 24 Nov 2023 01:41:07 +0100 Subject: [PATCH 14/16] merge --- cmake/defaults/Version.cmake | 6 +- cmake/modules/FindHoudiniUSD.cmake | 1 + deps/CMakeLists.txt | 2 - pxr/imaging/plugin/hdRpr/mesh.cpp | 43 +++++- pxr/imaging/plugin/hdRpr/mesh.h | 5 + .../plugin/hdRpr/package/generatePackage.py | 20 ++- pxr/imaging/plugin/hdRpr/points.cpp | 58 +++++-- pxr/imaging/plugin/hdRpr/points.h | 1 + pxr/imaging/plugin/hdRpr/primvarUtil.h | 11 +- .../python/generateRenderSettingFiles.py | 8 + pxr/imaging/plugin/hdRpr/rprApi.cpp | 142 ++++++++++++------ pxr/imaging/plugin/hdRpr/rprApi.h | 3 +- pxr/imaging/plugin/rprHoudini/CMakeLists.txt | 29 +++- .../hda/rpr_standard_rendervars.hda | Bin 32236 -> 32823 bytes .../rprHoudini/houdiniPluginActivator.cpp.in | 77 +++++++--- pxr/imaging/rprUsd/materialMappings.cpp | 3 + pxr/imaging/rprUsd/materialMappings.h | 4 + .../materialNodes/mtlxFiles/CMakeLists.txt | 1 + pxr/imaging/rprUsd/schema.usda | 7 + 19 files changed, 328 insertions(+), 93 deletions(-) diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 81e297d7b..28f39f29a 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -22,6 +22,6 @@ # language governing permissions and limitations under the Apache License. # # Versioning information -set(HD_RPR_MAJOR_VERSION "2") -set(HD_RPR_MINOR_VERSION "4") -set(HD_RPR_PATCH_VERSION "28") +set(HD_RPR_MAJOR_VERSION "3") +set(HD_RPR_MINOR_VERSION "0") +set(HD_RPR_PATCH_VERSION "2") diff --git a/cmake/modules/FindHoudiniUSD.cmake b/cmake/modules/FindHoudiniUSD.cmake index 454cf8c2f..b6e3fe061 100644 --- a/cmake/modules/FindHoudiniUSD.cmake +++ b/cmake/modules/FindHoudiniUSD.cmake @@ -86,6 +86,7 @@ foreach(python_major_minor "3;9" "3;7" "2;7") NO_DEFAULT_PATH) set(Houdini_Python_FOUND TRUE) + set(Houdini_Python_VERSION ${py_major}.${py_minor}) foreach(var ${Houdini_Python_VARS}) if(NOT ${var}) set(Houdini_Python_FOUND FALSE) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index f3454259b..8657e6d32 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -89,5 +89,3 @@ add_library(murmurhash STATIC ${MURMURHASH_DIR}/MurmurHash3.cpp) target_include_directories(murmurhash PUBLIC ${MURMURHASH_DIR}) set_target_properties(murmurhash PROPERTIES POSITION_INDEPENDENT_CODE ON) - -# ---------------------------------------------- diff --git a/pxr/imaging/plugin/hdRpr/mesh.cpp b/pxr/imaging/plugin/hdRpr/mesh.cpp index 121e102e7..03e180db1 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.cpp +++ b/pxr/imaging/plugin/hdRpr/mesh.cpp @@ -86,9 +86,9 @@ RprUsdMaterial const* HdRprMesh::GetFallbackMaterial( if (!m_fallbackMaterial) { // Means that vertex color primvar correctly set on mesh. Only Northstar supports this feature - if (m_colorsSet) + if (m_colorsSet || m_opacitySet) { - m_fallbackMaterial = rprApi->CreatePrimvarColorLookupMaterial(); + m_fallbackMaterial = rprApi->CreatePrimvarLookupMaterial(m_colorsSet, m_opacitySet); rprApi->SetName(m_fallbackMaterial, GetId().GetText()); return m_fallbackMaterial; } @@ -360,6 +360,17 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, m_colorsSet = false; } + if (HdChangeTracker::IsPrimvarDirty(*dirtyBits, id, HdTokens->displayOpacity)) { + HdRprFillPrimvarDescsPerInterpolation(sceneDelegate, id, &primvarDescsPerInterpolation); + m_authoredOpacity = HdRprSamplePrimvar(id, HdTokens->displayOpacity, sceneDelegate, primvarDescsPerInterpolation, m_numGeometrySamples, &m_opacitySamples, &m_opacityInterpolation); + if (!m_authoredOpacity) { + m_opacitySamples.clear(); + } + + newMesh = true; + m_opacitySet = false; + } + if (*dirtyBits & HdChangeTracker::DirtyMaterialId) { UpdateMaterialId(sceneDelegate, rprRenderParam); } @@ -491,6 +502,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, if (m_pointSamples.size() > 0) { if (auto rprMesh = rprApi->CreateMesh(m_pointSamples, m_faceVertexIndices, m_normalSamples, m_normalIndices, m_uvSamples, m_uvIndices, m_faceVertexCounts, m_topology.GetOrientation())) { m_colorsSet = rprApi->SetMeshVertexColor(rprMesh, m_colorSamples, m_colorInterpolation); + m_opacitySet = rprApi->SetMeshVertexOpacity(rprMesh, m_opacitySamples, m_opacityInterpolation); m_rprMeshes.push_back(rprMesh); } } @@ -520,6 +532,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, VtArray subsetPointSamples(m_pointSamples.size()); VtArray subsetNormalSamples(m_normalSamples.size()); VtArray subsetColorSamples(m_colorSamples.size()); + VtArray subsetOpacitySamples(m_opacitySamples.size()); VtArray subsetUvSamples(m_uvSamples.size()); VtIntArray subsetNormalIndices; VtIntArray subsetUvIndices; @@ -607,18 +620,31 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, if (newPoint) { for (int sampleIndex = 0; sampleIndex < m_uvSamples.size(); ++sampleIndex) { if (sampleIndex >= m_colorSamples.size() || pointIndex >= m_colorSamples[sampleIndex].size()) { - TF_WARN("Failed verification sampleIndex >= m_colorSamples.size() || pointIndex >= m_colorSamples[sampleIndex].size()"); + TF_WARN("Vertex index does not match displayColor primvar size"); continue; } subsetColorSamples[sampleIndex].push_back(m_colorSamples[sampleIndex][pointIndex]); } } } + + if (!m_opacitySamples.empty()) { + if (newPoint) { + for (int sampleIndex = 0; sampleIndex < m_uvSamples.size(); ++sampleIndex) { + if (sampleIndex >= m_opacitySamples.size() || pointIndex >= m_opacitySamples[sampleIndex].size()) { + TF_WARN("Vertex index does not match displayOpacity primvar size"); + continue; + } + subsetOpacitySamples[sampleIndex].push_back(m_opacitySamples[sampleIndex][pointIndex]); + } + } + } } } if (auto rprMesh = rprApi->CreateMesh(subsetPointSamples, subsetIndexes, subsetNormalSamples, subsetNormalIndices, subsetUvSamples, subsetUvIndices, subsetVertexPerFace, m_topology.GetOrientation())) { m_colorsSet = rprApi->SetMeshVertexColor(rprMesh, subsetColorSamples, m_colorInterpolation); + m_opacitySet = rprApi->SetMeshVertexOpacity(rprMesh, subsetOpacitySamples, m_opacityInterpolation); m_rprMeshes.push_back(rprMesh); ++it; } else { @@ -825,6 +851,17 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate, } } + if (!newMesh && (*dirtyBits & HdChangeTracker::DirtyMaterialId)) { + for (auto& rprMesh : m_rprMeshes) { + if (!m_colorSamples.empty()) { + m_colorsSet = rprApi->SetMeshVertexColor(rprMesh, m_colorSamples, m_colorInterpolation); + } + if (!m_opacitySamples.empty()) { + m_opacitySet = rprApi->SetMeshVertexOpacity(rprMesh, m_opacitySamples, m_opacityInterpolation); + } + } + } + if (updateTransform) { for (auto& rprMesh : m_rprMeshes) { rprApi->SetTransform(rprMesh, m_transformSamples.count, m_transformSamples.times.data(), m_transformSamples.values.data()); diff --git a/pxr/imaging/plugin/hdRpr/mesh.h b/pxr/imaging/plugin/hdRpr/mesh.h index 23a880903..df3989af6 100644 --- a/pxr/imaging/plugin/hdRpr/mesh.h +++ b/pxr/imaging/plugin/hdRpr/mesh.h @@ -88,6 +88,11 @@ class HdRprMesh final : public HdRprBaseRprim { bool m_authoredColors = false; bool m_colorsSet = false; + VtArray m_opacitySamples; + HdInterpolation m_opacityInterpolation; + bool m_authoredOpacity = false; + bool m_opacitySet = false; + VtArray m_uvSamples; VtIntArray m_uvIndices; diff --git a/pxr/imaging/plugin/hdRpr/package/generatePackage.py b/pxr/imaging/plugin/hdRpr/package/generatePackage.py index db74aaa9f..9932ab040 100644 --- a/pxr/imaging/plugin/hdRpr/package/generatePackage.py +++ b/pxr/imaging/plugin/hdRpr/package/generatePackage.py @@ -10,7 +10,7 @@ # limitations under the License. # import os -import re +import stat import sys import shlex import shutil @@ -44,6 +44,12 @@ def current_working_directory(dir): try: yield finally: os.chdir(curdir) +def on_rm_error(func, path, exc_info): + # path contains the path of the file that couldn't be removed + # let's just assume that it's read-only and unlink it. + os.chmod(path, stat.S_IWRITE) + os.unlink(path) + self_dir = os.path.abspath(self_path()) hdrpr_root_path = os.path.abspath(os.path.join(self_path(), '../../../../..')) @@ -53,6 +59,8 @@ def current_working_directory(dir): parser.add_argument('-c', '--config', type=str, default='Release') parser.add_argument('--cmake_options', type=str, default='') parser.add_argument('--disable_auto_cleanup', default=False, action='store_true') +parser.add_argument('--build_resolver', default=False, help="Windows only", action='store_true') +parser.add_argument('--resolver_cmake_options', type=str, default='', help="Windows only") args = parser.parse_args() output_dir = os.path.abspath(args.output_dir) @@ -60,11 +68,13 @@ def current_working_directory(dir): package_dir = '_package' cmake_configure_cmd = ['cmake', '-DCMAKE_INSTALL_PREFIX='+package_dir, '-DDUMP_PACKAGE_FILE_NAME=ON'] cmake_configure_cmd += shlex.split(args.cmake_options) +if args.build_resolver: + cmake_configure_cmd += ["-DRESOLVER_SUPPORT=ON"] cmake_configure_cmd += ['..'] build_dir = 'build_generatePackage_tmp_dir' if not args.disable_auto_cleanup and os.path.isdir(build_dir): - shutil.rmtree(build_dir) + shutil.rmtree(build_dir, onerror=on_rm_error) os.makedirs(build_dir, exist_ok=True) @@ -82,6 +92,10 @@ def current_working_directory(dir): if return_code != 0: exit(return_code) + if args.build_resolver: + from buildResolver import build_resolver + build_resolver(os.path.abspath(package_dir), args.resolver_cmake_options, format_multi_procs(get_cpu_count())) + with tarfile.open('tmpPackage.tar.gz', 'w:gz') as tar: tar.add(package_dir, package_name) output_package = os.path.join(output_dir, package_name+'.tar.gz') @@ -89,4 +103,4 @@ def current_working_directory(dir): print('{} has been created'.format(os.path.relpath(output_package))) if not args.disable_auto_cleanup: - shutil.rmtree(build_dir) + shutil.rmtree(build_dir, onerror=on_rm_error) diff --git a/pxr/imaging/plugin/hdRpr/points.cpp b/pxr/imaging/plugin/hdRpr/points.cpp index 8d64122df..421868fa9 100644 --- a/pxr/imaging/plugin/hdRpr/points.cpp +++ b/pxr/imaging/plugin/hdRpr/points.cpp @@ -16,6 +16,7 @@ limitations under the License. #include "primvarUtil.h" #include "renderParam.h" #include "material.h" +#include "instancer.h" #include "pxr/imaging/rprUsd/debugCodes.h" #include "pxr/imaging/hd/extComputationUtils.h" @@ -149,13 +150,37 @@ void HdRprPoints::Sync( } } + if (*dirtyBits & HdChangeTracker::DirtyInstancer){ + m_instanceTransforms.clear(); +#ifdef USE_DECOUPLED_INSTANCER + _UpdateInstancer(sceneDelegate, dirtyBits); + HdInstancer::_SyncInstancerAndParents(sceneDelegate->GetRenderIndex(), sceneDelegate->GetInstancerId(id)); +#endif + auto instancer = static_cast(sceneDelegate->GetRenderIndex().GetInstancer(sceneDelegate->GetInstancerId(id))); + if (instancer) { + auto instanceTransforms = instancer->SampleInstanceTransforms(id); + auto newNumInstances = (instanceTransforms.count > 0) ? instanceTransforms.values[0].size() : 0; + if(newNumInstances > 0){ + m_instanceTransforms.reserve(newNumInstances); + for (auto t : instanceTransforms.values[0]){ + m_instanceTransforms.emplace_back(GfMatrix4f(t)); + } + } + } + if(m_instanceTransforms.empty()){ + m_instanceTransforms.emplace_back(1.0); + } + } + + size_t numInstances = m_points.size() * m_instanceTransforms.size(); + bool dirtyPrototypeMesh = false; bool dirtyInstances = false; - if (m_instances.size() != m_points.size()) { + if (m_instances.size() != numInstances) { if (m_points.empty()) { rprApi->Release(m_prototypeMesh); m_prototypeMesh = nullptr; - } else { + } else if (!m_prototypeMesh){ auto& topology = UsdImagingGetUnitSphereMeshTopology(); auto& points = UsdImagingGetUnitSphereMeshPoints(); @@ -170,16 +195,16 @@ void HdRprPoints::Sync( } } - if (m_instances.size() > m_points.size()) { - for (size_t i = m_points.size(); i < m_instances.size(); ++i) { + if (m_instances.size() > numInstances) { + for (size_t i = numInstances; i < m_instances.size(); ++i) { rprApi->Release(m_instances[i]); } - m_instances.resize(m_points.size()); + m_instances.resize(numInstances); } else { - m_instances.reserve(m_points.size()); - for (size_t i = m_instances.size(); i < m_points.size(); ++i) { + m_instances.reserve(numInstances); + for (size_t i = m_instances.size(); i < numInstances; ++i) { if (auto instance = rprApi->CreateMeshInstance(m_prototypeMesh)) { - rprApi->SetMeshId(instance, i); + rprApi->SetMeshId(instance, i % m_points.size()); m_instances.push_back(instance); if (RprUsdIsLeakCheckEnabled()) { @@ -200,6 +225,7 @@ void HdRprPoints::Sync( if ((*dirtyBits & HdChangeTracker::DirtyTransform) || (*dirtyBits & HdChangeTracker::DirtyWidths) || + (*dirtyBits & HdChangeTracker::DirtyInstancer) || dirtyPoints || dirtyInstances) { std::function sampleWidth; @@ -212,12 +238,15 @@ void HdRprPoints::Sync( TF_WARN("[%s] Unsupported widths interpolation. Fallback value is 1.0f with a constant interpolation", id.GetText()); } - for (size_t i = 0; i < m_instances.size(); ++i) { - auto& position = m_points[i]; - auto width = sampleWidth(i); - auto transform = GfMatrix4f(1.0f).SetScale(GfVec3f(width)).SetTranslateOnly(position) * m_transform; + for (int i = 0; i < m_instanceTransforms.size(); ++i){ + for (size_t j = 0; j < m_points.size(); ++j) { + auto& position = m_points[j]; + auto width = sampleWidth(j); + auto transform = GfMatrix4f(1.0f).SetScale(GfVec3f(width)).SetTranslateOnly(position); + transform *= m_transform * m_instanceTransforms[i]; - rprApi->SetTransform(m_instances[i], transform); + rprApi->SetTransform(m_instances[j + m_points.size() * i], transform); + } } } @@ -276,7 +305,8 @@ HdDirtyBits HdRprPoints::GetInitialDirtyBitsMask() const { HdChangeTracker::DirtyWidths | HdChangeTracker::DirtyTransform | HdChangeTracker::DirtyPrimvar | - HdChangeTracker::DirtyVisibility; + HdChangeTracker::DirtyVisibility | + HdChangeTracker::DirtyInstancer; } HdDirtyBits HdRprPoints::_PropagateDirtyBits(HdDirtyBits bits) const { diff --git a/pxr/imaging/plugin/hdRpr/points.h b/pxr/imaging/plugin/hdRpr/points.h index 090bfe0fb..16ecaff3c 100644 --- a/pxr/imaging/plugin/hdRpr/points.h +++ b/pxr/imaging/plugin/hdRpr/points.h @@ -54,6 +54,7 @@ class HdRprPoints : public HdRprBaseRprim { RprUsdMaterial* m_material = nullptr; GfMatrix4f m_transform; + std::vector m_instanceTransforms; VtVec3fArray m_points; diff --git a/pxr/imaging/plugin/hdRpr/primvarUtil.h b/pxr/imaging/plugin/hdRpr/primvarUtil.h index fb0b5b21c..8ede329cf 100644 --- a/pxr/imaging/plugin/hdRpr/primvarUtil.h +++ b/pxr/imaging/plugin/hdRpr/primvarUtil.h @@ -88,12 +88,21 @@ bool HdRprSamplePrimvar( VtArray* sampleValuesPtr) { std::vector sampleTimes(maxSampleCount); std::vector sampleVtValues(maxSampleCount); - + size_t authoredSampleCount = sceneDelegate->SamplePrimvar(id, key, maxSampleCount, sampleTimes.data(), sampleVtValues.data()); if (!authoredSampleCount) { return false; } + // for maxSampleCount == 1 and animated scene SamplePrimvar returns 3 frames, and we have to get 2nd one + if (maxSampleCount == 1 && authoredSampleCount > 2) { + std::vector sampleTimesTmp(authoredSampleCount); + std::vector sampleVtValuesTmp(authoredSampleCount); + sceneDelegate->SamplePrimvar(id, key, authoredSampleCount, sampleTimesTmp.data(), sampleVtValuesTmp.data()); + sampleTimes[0] = sampleTimesTmp[1]; + sampleVtValues[0] = sampleVtValuesTmp[1]; + } + if (authoredSampleCount < maxSampleCount) { sampleTimes.resize(authoredSampleCount); sampleVtValues.resize(authoredSampleCount); diff --git a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py index ccb659447..fcc60c9c2 100644 --- a/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py +++ b/pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py @@ -82,6 +82,14 @@ def houdini_parm_name(name): 'houdini': { 'hidewhen': hidewhen_not_northstar } + }, + { + 'name': 'core:legacyToon', + 'ui_name': 'Use Legacy RPR Toon', + 'defaultValue': False, + 'houdini': { + 'hidewhen': hidewhen_not_northstar + } } ] }, diff --git a/pxr/imaging/plugin/hdRpr/rprApi.cpp b/pxr/imaging/plugin/hdRpr/rprApi.cpp index 1dbc4ae0f..39f413392 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.cpp +++ b/pxr/imaging/plugin/hdRpr/rprApi.cpp @@ -440,6 +440,9 @@ class CameraData { class HdRprApiImpl { public: + static const int colorPrimvarKey = 0; + static const int transparencyPrimvarKey = 1; + HdRprApiImpl(HdRprDelegate* delegate) : m_delegate(delegate) { // Postpone initialization as further as possible to allow Hydra user to set custom render settings before creating a context @@ -863,11 +866,33 @@ class HdRprApiImpl { } } - bool SetMeshVertexColor(rpr::Shape* mesh, VtArray const& primvarSamples, HdInterpolation interpolation) { + bool convertInterpolation(HdInterpolation interpolation, rpr::PrimvarInterpolationType& rprInterpolation) { + switch (interpolation) + { + case HdInterpolationConstant: + rprInterpolation = RPR_PRIMVAR_INTERPOLATION_CONSTANT; + break; + case HdInterpolationUniform: + rprInterpolation = RPR_PRIMVAR_INTERPOLATION_UNIFORM; + break; + case HdInterpolationVertex: + rprInterpolation = RPR_PRIMVAR_INTERPOLATION_VERTEX; + break; + case HdInterpolationVarying: + rprInterpolation = RPR_PRIMVAR_INTERPOLATION_FACEVARYING_NORMAL; + break; + case HdInterpolationFaceVarying: + rprInterpolation = RPR_PRIMVAR_INTERPOLATION_FACEVARYING_UV; + break; + default: + // Rpr does not support HdInterpolationInstance + return false; + } - // We use zero primvar channel to store vertex colors - const int colorPrimvarKey = 0; + return true; + } + bool SetMeshVertexColor(rpr::Shape* mesh, VtArray const& primvarSamples, HdInterpolation interpolation) { if (primvarSamples.empty()) { return false; } @@ -875,26 +900,7 @@ class HdRprApiImpl { LockGuard rprLock(m_rprContext->GetMutex()); rpr::PrimvarInterpolationType rprInterpolation; - - switch (interpolation) - { - case HdInterpolationConstant: - rprInterpolation = RPR_PRIMVAR_INTERPOLATION_CONSTANT; - break; - case HdInterpolationUniform: - rprInterpolation = RPR_PRIMVAR_INTERPOLATION_UNIFORM; - break; - case HdInterpolationVertex: - rprInterpolation = RPR_PRIMVAR_INTERPOLATION_VERTEX; - break; - case HdInterpolationVarying: - rprInterpolation = RPR_PRIMVAR_INTERPOLATION_FACEVARYING_NORMAL; - break; - case HdInterpolationFaceVarying: - rprInterpolation = RPR_PRIMVAR_INTERPOLATION_FACEVARYING_UV; - break; - default: - // Rpr does not support HdInterpolationInstance + if (!convertInterpolation(interpolation, rprInterpolation)) { return false; } try { @@ -911,6 +917,36 @@ class HdRprApiImpl { return false; } + bool SetMeshVertexOpacity(rpr::Shape* mesh, VtArray const& primvarSamples, HdInterpolation interpolation) { + if (primvarSamples.empty()) { + return false; + } + if (m_rprContextMetadata.pluginType == kPluginNorthstar) { + LockGuard rprLock(m_rprContext->GetMutex()); + + rpr::PrimvarInterpolationType rprInterpolation; + if (!convertInterpolation(interpolation, rprInterpolation)) { + return false; + } + try { + // converting opacity to transparency + VtFloatArray opacitySamples = primvarSamples[0]; + for (size_t i = 0; i < opacitySamples.size(); ++i) { + opacitySamples[i] = 1.0f - opacitySamples[i]; + } + RPR_ERROR_CHECK_THROW(mesh->SetPrimvar(transparencyPrimvarKey, (rpr_float const*)opacitySamples.cdata(), opacitySamples.size(), 1, rprInterpolation), "Failed to set color primvars"); + } + catch (RprUsdError& e) { + TF_RUNTIME_ERROR("Failed to set vertex opacity: %s", e.what()); + return false; + } + + m_dirtyFlags |= ChangeTracker::DirtyScene; + return true; + } + return false; + } + rpr::Curve* CreateCurve(VtVec3fArray const& points, VtIntArray const& indices, VtFloatArray const& radiuses, VtVec2fArray const& uvs, VtIntArray const& segmentPerCurve) { if (!m_rprContext) { return nullptr; @@ -1416,47 +1452,56 @@ class HdRprApiImpl { } } - RprUsdMaterial* CreatePrimvarColorLookupMaterial() { + RprUsdMaterial* CreatePrimvarColorLookupMaterial(bool isColorSet, bool isOpacitySet) { if (!m_rprContext) { return nullptr; } LockGuard rprLock(m_rprContext->GetMutex()); - class HdRprApiPrimvarColorLookupMaterial : public RprUsdMaterial { + class HdRprApiPrimvarLookupMaterial : public RprUsdMaterial { public: - HdRprApiPrimvarColorLookupMaterial(rpr::Context* context) { + HdRprApiPrimvarLookupMaterial(rpr::Context* context, bool isColorSet, bool isOpacitySet) { rpr::Status status; - - m_primvarLookupNode.reset(context->CreateMaterialNode(RPR_MATERIAL_NODE_PRIMVAR_LOOKUP, &status)); - if (!m_primvarLookupNode) { - RPR_ERROR_CHECK_THROW(status, "Failed to create primvar lookup node"); - } - - // we use zero primvar channel to store vertex color values - status = m_primvarLookupNode->SetInput(RPR_MATERIAL_INPUT_VALUE, (rpr_uint) 0); - if (status != RPR_SUCCESS) { - RPR_ERROR_CHECK_THROW(status, "Failed to set lookup node input value"); - } - m_uberNode.reset(context->CreateMaterialNode(RPR_MATERIAL_NODE_UBERV2, &status)); if (!m_uberNode) { RPR_ERROR_CHECK_THROW(status, "Failed to create uber node"); } - RPR_ERROR_CHECK_THROW(m_uberNode->SetInput(RPR_MATERIAL_INPUT_UBER_DIFFUSE_COLOR, m_primvarLookupNode.get()), "Failed to set root material diffuse color"); + + if (isColorSet) { + createLookupNode(context, m_primvarColorLookupNode, colorPrimvarKey); + RPR_ERROR_CHECK_THROW(m_uberNode->SetInput(RPR_MATERIAL_INPUT_UBER_DIFFUSE_COLOR, m_primvarColorLookupNode.get()), "Failed to set root material diffuse color"); + } + if (isOpacitySet) { + createLookupNode(context, m_primvarOpacityLookupNode, transparencyPrimvarKey); + RPR_ERROR_CHECK_THROW(m_uberNode->SetInput(RPR_MATERIAL_INPUT_UBER_TRANSPARENCY, m_primvarOpacityLookupNode.get()), "Failed to set root material transparancy"); + } m_surfaceNode = m_uberNode.get(); }; - ~HdRprApiPrimvarColorLookupMaterial() final = default; + ~HdRprApiPrimvarLookupMaterial() final = default; private: - std::unique_ptr m_primvarLookupNode; + void createLookupNode(rpr::Context* context, std::unique_ptr& lookupNode, rpr_uint key) { + rpr::Status status; + lookupNode.reset(context->CreateMaterialNode(RPR_MATERIAL_NODE_PRIMVAR_LOOKUP, &status)); + if (!lookupNode) { + RPR_ERROR_CHECK_THROW(status, "Failed to create primvar lookup node"); + } + status = lookupNode->SetInput(RPR_MATERIAL_INPUT_VALUE, key); + if (status != RPR_SUCCESS) { + RPR_ERROR_CHECK_THROW(status, "Failed to set lookup node input value"); + } + } + + std::unique_ptr m_primvarColorLookupNode; + std::unique_ptr m_primvarOpacityLookupNode; std::unique_ptr m_uberNode; }; try { - return new HdRprApiPrimvarColorLookupMaterial(m_rprContext.get()); + return new HdRprApiPrimvarLookupMaterial(m_rprContext.get(), isColorSet, isOpacitySet); } catch (RprUsdError& e) { TF_RUNTIME_ERROR("Failed to create points material: %s", e.what()); @@ -2063,6 +2108,11 @@ class HdRprApiImpl { #endif // RPR_EXR_EXPORT_ENABLED } } + if (preferences.IsDirty(HdRprConfig::DirtyRenderQuality) || force) { + int enableNormalization = preferences.GetCoreLegacyToon() ? 0 : 1; + RPR_ERROR_CHECK(m_rprContext->SetParameter(RPR_CONTEXT_NORMALIZE_LIGHT_INTENSITY_ENABLED, enableNormalization), "Failed to set toon mode"); + m_dirtyFlags |= ChangeTracker::DirtyScene; + } } void UpdateHybridSettings(HdRprConfig const& preferences, bool force) { @@ -4690,9 +4740,9 @@ RprUsdMaterial* HdRprApi::CreateDiffuseMaterial(GfVec3f const& color) { }); } -RprUsdMaterial* HdRprApi::CreatePrimvarColorLookupMaterial(){ +RprUsdMaterial* HdRprApi::CreatePrimvarLookupMaterial(bool isColorSet, bool isOpacitySet){ m_impl->InitIfNeeded(); - return m_impl->CreatePrimvarColorLookupMaterial(); + return m_impl->CreatePrimvarColorLookupMaterial(isColorSet, isOpacitySet); } void HdRprApi::SetMeshRefineLevel(rpr::Shape* mesh, int level, const float creaseWeight) { @@ -4723,6 +4773,10 @@ bool HdRprApi::SetMeshVertexColor(rpr::Shape* mesh, VtArray const& return m_impl->SetMeshVertexColor(mesh, primvarSamples, interpolation); } +bool HdRprApi::SetMeshVertexOpacity(rpr::Shape* mesh, VtArray const& primvarSamples, HdInterpolation interpolation) { + return m_impl->SetMeshVertexOpacity(mesh, primvarSamples, interpolation); +} + void HdRprApi::SetCurveMaterial(rpr::Curve* curve, RprUsdMaterial const* material) { m_impl->SetCurveMaterial(curve, material); } diff --git a/pxr/imaging/plugin/hdRpr/rprApi.h b/pxr/imaging/plugin/hdRpr/rprApi.h index 0b94b90e9..7b39ae1e8 100644 --- a/pxr/imaging/plugin/hdRpr/rprApi.h +++ b/pxr/imaging/plugin/hdRpr/rprApi.h @@ -118,7 +118,7 @@ class HdRprApi final { RprUsdMaterial* CreateMaterial(SdfPath const& materialId, HdSceneDelegate* sceneDelegate, HdMaterialNetworkMap const& materialNetwork); RprUsdMaterial* CreatePointsMaterial(VtVec3fArray const& colors); RprUsdMaterial* CreateDiffuseMaterial(GfVec3f const& color); - RprUsdMaterial* CreatePrimvarColorLookupMaterial(); + RprUsdMaterial* CreatePrimvarLookupMaterial(bool isColorSet, bool isOpacitySet); void Release(RprUsdMaterial* material); rpr::Shape* CreateMesh(VtVec3fArray const& points, VtIntArray const& pointIndexes, VtVec3fArray const& normals, VtIntArray const& normalIndexes, VtVec2fArray const& uvs, VtIntArray const& uvIndexes, VtIntArray const& vpf, TfToken const& polygonWinding); @@ -131,6 +131,7 @@ class HdRprApi final { void SetMeshId(rpr::Shape* mesh, uint32_t id); void SetMeshIgnoreContour(rpr::Shape* mesh, bool ignoreContour); bool SetMeshVertexColor(rpr::Shape* mesh, VtArray const& primvarSamples, HdInterpolation interpolation); + bool SetMeshVertexOpacity(rpr::Shape* mesh, VtArray const& primvarSamples, HdInterpolation interpolation); void Release(rpr::Shape* shape); rpr::Curve* CreateCurve(VtVec3fArray const& points, VtIntArray const& indices, VtFloatArray const& radiuses, VtVec2fArray const& uvs, VtIntArray const& segmentPerCurve); diff --git a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt index 2167c2ae1..d50800ece 100644 --- a/pxr/imaging/plugin/rprHoudini/CMakeLists.txt +++ b/pxr/imaging/plugin/rprHoudini/CMakeLists.txt @@ -62,6 +62,7 @@ install( ${CMAKE_CURRENT_SOURCE_DIR}/hda/rpr_exportRpr1.hda ${CMAKE_CURRENT_SOURCE_DIR}/hda/rpr_standard_rendervars.hda DESTINATION "houdini/otls") + install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/python/houRpr/__init__.py @@ -81,7 +82,33 @@ install( houdini/config/Icons) install( FILES - ui/MainMenuCommon.xml UsdRenderers.json DESTINATION houdini) + +if(RESOLVER_SUPPORT) + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/scripts/python/houRpr/resolver.py + DESTINATION + houdini/scripts/python/houRpr) + install( + FILES + ui/MainMenuCommon_resolver.xml + DESTINATION + houdini + RENAME + MainMenuCommon.xml) + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/hda/rpr_exportToRenderStudio.hda + DESTINATION + houdini/otls) + target_compile_definitions(activateHoudiniPlugin PRIVATE RESOLVER_SUPPORT) +else () + install( + FILES + ui/MainMenuCommon.xml + DESTINATION + houdini) +endif () diff --git a/pxr/imaging/plugin/rprHoudini/hda/rpr_standard_rendervars.hda b/pxr/imaging/plugin/rprHoudini/hda/rpr_standard_rendervars.hda index d6632a7fa7126e6f01b1a58354f77153324fbe79..6f2bea6c70487996ccf8429a77a4d228e9a02bf7 100644 GIT binary patch delta 17566 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 LI+uI6+F<-216o@6 delta 17130 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 G-v0ptx|qrU diff --git a/pxr/imaging/plugin/rprHoudini/houdiniPluginActivator.cpp.in b/pxr/imaging/plugin/rprHoudini/houdiniPluginActivator.cpp.in index 9c630d769..9d860aa81 100644 --- a/pxr/imaging/plugin/rprHoudini/houdiniPluginActivator.cpp.in +++ b/pxr/imaging/plugin/rprHoudini/houdiniPluginActivator.cpp.in @@ -271,9 +271,13 @@ fs::path GetHoudiniUserPrefDir(const char* hver) { return {}; } -fs::path GetLopScriptsDir(const char* hver) { +std::vector GetLopScriptsDir(const char* hver) { + std::vector foundPaths; #if defined(__linux__) - auto scriptsPath = fs::path("/opt/hfs" + std::string(hver) + "/houdini/scripts/lop"); + auto linuxScriptsPath = fs::path("/opt/hfs" + std::string(hver) + "/houdini/scripts/lop"); + if (exists(linuxScriptsPath)) { + foundPaths.push_back(linuxScriptsPath); + } #elif defined(__APPLE__) auto searchPath = fs::path("/Applications/Houdini"); std::string searchPattern = "Houdini" + std::string(hver); @@ -282,31 +286,55 @@ fs::path GetLopScriptsDir(const char* hver) { std::string searchPattern = "Houdini " + std::string(hver); #endif #if defined(__APPLE__) || defined(_WIN32) || defined(_WIN64) - std::vector subdirs; std::error_code ec; for (auto& p : fs::directory_iterator(searchPath, fs::directory_options::skip_permission_denied, ec)) { if (p.path().stem().string() == searchPattern) { - subdirs.push_back(p.path()); + auto scriptsPath = p.path() / "houdini" / "scripts" / "lop"; + if(fs::exists(scriptsPath)){ + foundPaths.push_back(scriptsPath); + } } } - if (subdirs.size() != 1) { - return {}; - } - auto scriptsPath = subdirs[0] / "houdini" / "scripts" / "lop"; #endif - if (exists(scriptsPath)) { - return scriptsPath; + if (!foundPaths.empty()) { + return foundPaths; } std::cout << "Can not determine houdini installation. To copy render settings update script enter the path to houdini directory" << std::endl << ">"; std::string userInput; std::getline(std::cin, userInput); - scriptsPath = fs::path(userInput) / "houdini" / "scripts" / "lop"; + auto scriptsPath = fs::path(userInput) / "houdini" / "scripts" / "lop"; if (!exists(scriptsPath)) { std::cout << "Path not found: " << scriptsPath << std::endl; return {}; } - return scriptsPath; + foundPaths.push_back(scriptsPath); + return foundPaths; +} + +void updateRenderStudioServerScript(const fs::path& houdiniScriptsDir, const fs::path& packageDir){ + auto houdiniBinDir = houdiniScriptsDir / ".." / ".." / ".." / "bin"; + auto serverDir = packageDir / "RenderStudioServer"; + auto usdPluginDir = packageDir / "plugin"; +#if defined(_WIN32) || defined(_WIN64) + auto serverScriptPath = serverDir / "Run.bat"; + std::ofstream serverScript(serverScriptPath); + if (!serverScript.is_open()) { + std::cout << "Failed to open output file: " << serverScriptPath << ", Render Studio server launch is unavailable" << "\n" << std::endl; + return; + } + serverScript << "@echo off" << "\n"; + serverScript << "setlocal" << "\n"; + serverScript << R"(set SCRIPT_DIR="%~dp0")" << "\n"; + serverScript << "set USD_DIR=%~dp0.." << "\n"; + serverScript << R"(set USD_PATH=%USD_DIR%\lib;;%USD_DIR%\plugin\usd)" << "\n"; + serverScript << "set PATH=%PATH%;%USD_PATH%;" << houdiniBinDir.string() << "\n"; + serverScript << "set PXR_PLUGINPATH_NAME=" << usdPluginDir.string() << "\n"; + serverScript << R"("%~dp0\RenderStudioServer.exe" %*)" << "\n"; + if (serverScript.fail()) { + std::cout << "Failed to write output file: " << serverScriptPath <<", Render Studio server launch is unavailable" << "\n" << std::endl; + } +#endif } int ActivateHoudiniPlugin(std::string const& pluginName, std::vector> const& env, const char* version=nullptr) { @@ -367,16 +395,23 @@ int ActivateHoudiniPlugin(std::string const& pluginName, std::vectorchecker_texture, RPR_MATERIAL_NODE_CHECKER_TEXTURE}, {RprUsdMaterialNodeTypeTokens->constant_texture, RPR_MATERIAL_NODE_CONSTANT_TEXTURE}, {RprUsdMaterialNodeTypeTokens->input_lookup, RPR_MATERIAL_NODE_INPUT_LOOKUP}, + {RprUsdMaterialNodeTypeTokens->primvar_lookup, RPR_MATERIAL_NODE_PRIMVAR_LOOKUP}, {RprUsdMaterialNodeTypeTokens->blend_value, RPR_MATERIAL_NODE_BLEND_VALUE}, {RprUsdMaterialNodeTypeTokens->passthrough, RPR_MATERIAL_NODE_PASSTHROUGH}, {RprUsdMaterialNodeTypeTokens->orennayar, RPR_MATERIAL_NODE_ORENNAYAR}, @@ -207,6 +208,8 @@ bool ToRpr(TfToken const& id, uint32_t* out, bool pedantic) { {RprUsdMaterialInputModeTokens->cylindical, RPR_MATERIAL_NODE_UVTYPE_CYLINDICAL}, {RprUsdMaterialInputModeTokens->spherical, RPR_MATERIAL_NODE_UVTYPE_SPHERICAL}, {RprUsdMaterialInputModeTokens->project, RPR_MATERIAL_NODE_UVTYPE_PROJECT}, + {RprUsdMaterialInputModeTokens->displayColor, 0}, + {RprUsdMaterialInputModeTokens->displayOpacity, 1}, }; auto it = s_mapping.find(id); diff --git a/pxr/imaging/rprUsd/materialMappings.h b/pxr/imaging/rprUsd/materialMappings.h index 60ebf902d..9e547dc40 100644 --- a/pxr/imaging/rprUsd/materialMappings.h +++ b/pxr/imaging/rprUsd/materialMappings.h @@ -141,6 +141,7 @@ bool ToRpr(TfToken const& id, uint32_t* out, bool pedantic = true); (checker_texture) \ (constant_texture) \ (input_lookup) \ + (primvar_lookup) \ (blend_value) \ (passthrough) \ (orennayar) \ @@ -182,6 +183,9 @@ bool ToRpr(TfToken const& id, uint32_t* out, bool pedantic = true); ((localPosition, "Local Position")) \ ((shapeRandomColor, "Shape Random Color")) \ ((objectId, "Object Id")) \ + /* Lookup primvar */ \ + ((displayColor, "displayColor")) \ + ((displayOpacity, "displayOpacity")) \ /* UV Type */ \ ((planar, "Flat Plane")) \ ((cylindical, "Cylinder (in xy direction)")) \ diff --git a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/CMakeLists.txt b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/CMakeLists.txt index 83a27691d..988537799 100644 --- a/pxr/imaging/rprUsd/materialNodes/mtlxFiles/CMakeLists.txt +++ b/pxr/imaging/rprUsd/materialNodes/mtlxFiles/CMakeLists.txt @@ -14,6 +14,7 @@ set(MTLX_FILES Utilities/rpr_hsv_to_rgb.mtlx Utilities/rpr_input_lookup.mtlx + Utilities/rpr_primvar_lookup.mtlx Utilities/rpr_uv_triplanar.mtlx Utilities/rpr_uv_procedural.mtlx diff --git a/pxr/imaging/rprUsd/schema.usda b/pxr/imaging/rprUsd/schema.usda index ad643c630..cb5536424 100644 --- a/pxr/imaging/rprUsd/schema.usda +++ b/pxr/imaging/rprUsd/schema.usda @@ -77,6 +77,13 @@ class "RprRendererSettingsAPI" ( doc = "Use OpenCL Northstar backed instead of HIP/CUDA" ) + # northstar only + uniform bool rpr:core:legacyToon = false ( + displayName = "Use Legacy RPR Toon" + displayGroup = "General" + doc = "Enable backward compatibility of RPR Toon shader appearance" + ) + # tahoe only uniform float rpr:ambientOcclusion:radius = 1.0 ( displayName = "Ambient Occlusion Radius" From ef241950bce1ae773f67c4ba70d9fe7544e2c8a5 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Fri, 24 Nov 2023 01:57:24 +0100 Subject: [PATCH 15/16] rpr switch --- deps/RPR | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/RPR b/deps/RPR index d3364d3f3..440580074 160000 --- a/deps/RPR +++ b/deps/RPR @@ -1 +1 @@ -Subproject commit d3364d3f36da0ac7fc19ae30701a1f256f21a26c +Subproject commit 440580074009d48b18019da1331d2494a253a96d From f046e2f0e88804c93b7096305728ce166df9c1c2 Mon Sep 17 00:00:00 2001 From: dmitrii-z Date: Fri, 24 Nov 2023 11:47:15 +0100 Subject: [PATCH 16/16] ubuntu build fix --- pxr/imaging/plugin/hdRpr/cpuFilters.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pxr/imaging/plugin/hdRpr/cpuFilters.cpp b/pxr/imaging/plugin/hdRpr/cpuFilters.cpp index b688b0eec..0bc99de73 100644 --- a/pxr/imaging/plugin/hdRpr/cpuFilters.cpp +++ b/pxr/imaging/plugin/hdRpr/cpuFilters.cpp @@ -186,9 +186,9 @@ void CpuGammaCorrection(GfVec4f* srcdest, size_t numPixels, float gamma) { WorkParallelForN(numPixels, [&](size_t begin, size_t end) { for (int i = begin; i < end; ++i) { - srcdest[i][0] = std::powf(srcdest[i][0], _1_g); - srcdest[i][1] = std::powf(srcdest[i][1], _1_g); - srcdest[i][2] = std::powf(srcdest[i][2], _1_g); + 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 } }); @@ -203,9 +203,9 @@ void CpuTonemap(GfVec4f* srcdest, size_t numPixels, float gamma, float exposureT WorkParallelForN(numPixels, [&](size_t begin, size_t end) { for (int i = begin; i < end; ++i) { - srcdest[i][0] = std::powf(srcdest[i][0] * h, _1_g); - srcdest[i][1] = std::powf(srcdest[i][1] * h, _1_g); - srcdest[i][2] = std::powf(srcdest[i][2] * h, _1_g); + 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 } });