diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 57b8b0930..dbec4d889 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -347,7 +347,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -392,6 +392,7 @@ namespace dxvk { &devExtensions.khrExternalMemory, &devExtensions.khrExternalSemaphore, &devExtensions.khrExternalSemaphoreWin32, + &devExtensions.extShaderAtomicFloat, }}; // Only enable Cuda interop extensions in 64-bit builds in @@ -588,6 +589,13 @@ namespace dxvk { enabledFeatures.extVertexAttributeDivisor.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extVertexAttributeDivisor); } + // NV-DXVK start: + if (devExtensions.extShaderAtomicFloat) { + enabledFeatures.extShaderAtomicFloat.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT; + enabledFeatures.extShaderAtomicFloat.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderAtomicFloat); + } + // NV-DXVK end + // NV-DXVK start: Integrate Aftermath if (devExtensions.nvDeviceDiagnostics && instance->options().enableAftermath) { enabledFeatures.nvDeviceDiagnosticsConfig.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index e00aa11a4..ae6bbb304 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -361,6 +361,10 @@ namespace dxvk { DxvkExt extBufferDeviceAddress = { VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, DxvkExtMode::Optional }; // NV-DXVK end + + // NV-DXVK start: + DxvkExt extShaderAtomicFloat = { VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME, DxvkExtMode::Optional }; + // NV-DXVK end }; /** diff --git a/src/dxvk/rtx_render/rtx_debug_view.cpp b/src/dxvk/rtx_render/rtx_debug_view.cpp index 41122ca26..447755aaf 100644 --- a/src/dxvk/rtx_render/rtx_debug_view.cpp +++ b/src/dxvk/rtx_render/rtx_debug_view.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,6 +36,7 @@ #include "rtx_terrain_baker.h" #include +#include #include #include "rtx_options.h" @@ -243,6 +244,14 @@ namespace dxvk { {DEBUG_VIEW_NOISY_DEMODULATED_SECONDARY_COMBINED_SPECULAR_RADIANCE,"Secondary Combined Specular: Demodulated Noisy Color"}, {DEBUG_VIEW_DENOISED_SECONDARY_COMBINED_SPECULAR_RADIANCE, "Secondary Combined Specular: Denoised Color"}, + { DEBUG_VIEW_NOISY_PRIMARY_DIRECT_RADIANCE, "Primary Direct: Noisy Color" }, + { DEBUG_VIEW_NOISY_PRIMARY_INDIRECT_RADIANCE, "Primary Indirect: Noisy Color" }, + { DEBUG_VIEW_NOISY_PRIMARY_RADIANCE, "Primary: Noisy Color" }, + { DEBUG_VIEW_NOISY_SECONDARY_DIRECT_RADIANCE, "Secondary Direct: Noisy Color" }, + { DEBUG_VIEW_NOISY_SECONDARY_INDIRECT_RADIANCE, "Secondary Indirect: Noisy Color" }, + { DEBUG_VIEW_NOISY_SECONDARY_RADIANCE, "Secondary: Noisy Color" }, + { DEBUG_VIEW_NOISY_RADIANCE, "Primary + Secondary: Noisy Color" }, + {DEBUG_VIEW_INSTRUMENTATION_THREAD_DIVERGENCE, "Thread Divergence(Debug Knob.x)"}, {DEBUG_VIEW_NAN, "Inf/NaN Check"}, {DEBUG_SURFACE_LOBE_CONSISTENCY, "Surface/Lobe Consistency Check"}, @@ -286,11 +295,16 @@ namespace dxvk { {PseudoColorMode::Alpha, "Alpha"}, } }); + ImGui::ComboWithKey outputStatisticsCombo = ImGui::ComboWithKey( + "Output Statistics Mode", + ImGui::ComboWithKey::ComboEntries { { + {DebugViewOutputStatisticsMode::Mean, "Mean"}, + {DebugViewOutputStatisticsMode::Sum, "Sum"}, + } }); + // Defined within an unnamed namespace to ensure unique definition across binary namespace { class DebugViewShader : public ManagedShader { - SHADER_SOURCE(DebugViewShader, VK_SHADER_STAGE_COMPUTE_BIT, debug_view) - BEGIN_PARAMETER() TEXTURE2D(DEBUG_VIEW_BINDING_DENOISED_PRIMARY_DIRECT_DIFFUSE_RADIANCE_HIT_T_INPUT) TEXTURE2D(DEBUG_VIEW_BINDING_DENOISED_PRIMARY_DIRECT_SPECULAR_RADIANCE_HIT_T_INPUT) @@ -305,24 +319,25 @@ namespace dxvk { TEXTURE2D(DEBUG_VIEW_BINDING_FINAL_SHADING_INPUT) TEXTURE2D(DEBUG_VIEW_BINDING_INSTRUMENTATION_INPUT) TEXTURE2D(DEBUG_VIEW_BINDING_TERRAIN_INPUT) + TEXTURE2D(DEBUG_VIEW_BINDING_INPUT) RW_TEXTURE2D(DEBUG_VIEW_BINDING_HDR_WAVEFORM_RED_INPUT_OUTPUT) RW_TEXTURE2D(DEBUG_VIEW_BINDING_HDR_WAVEFORM_GREEN_INPUT_OUTPUT) RW_TEXTURE2D(DEBUG_VIEW_BINDING_HDR_WAVEFORM_BLUE_INPUT_OUTPUT) RW_TEXTURE2D(DEBUG_VIEW_BINDING_COMPOSITE_OUTPUT_INPUT_OUTPUT) - RW_TEXTURE2D(DEBUG_VIEW_BINDING_INPUT_OUTPUT) RW_TEXTURE2D(DEBUG_VIEW_BINDING_PREVIOUS_FRAME_INPUT_OUTPUT) SAMPLER(DEBUG_VIEW_BINDING_NEAREST_SAMPLER) SAMPLER(DEBUG_VIEW_BINDING_LINEAR_SAMPLER) CONSTANT_BUFFER(DEBUG_VIEW_BINDING_CONSTANTS_INPUT) + + RW_STRUCTURED_BUFFER(DEBUG_VIEW_BINDING_STATISTICS_BUFFER_OUTPUT) + RW_TEXTURE2D(DEBUG_VIEW_BINDING_OUTPUT) END_PARAMETER() }; - PREWARM_SHADER_PIPELINE(DebugViewShader); - class DebugViewWaveformRenderShader : public ManagedShader { SHADER_SOURCE(DebugViewWaveformRenderShader, VK_SHADER_STAGE_COMPUTE_BIT, debug_view_waveform_render) @@ -347,6 +362,16 @@ namespace dxvk { initSettings(device->instance()->config()); } + void DebugView::prewarmShaders(DxvkPipelineManager& pipelineManager) const { + DxvkComputePipelineShaders shaders; + shaders.cs = getDebugViewShader(); + pipelineManager.createComputePipeline(shaders); + } + + bool DebugView::areDebugViewStatisticsSupported() const { + return m_device->extensions().extShaderAtomicFloat; + } + void DebugView::initSettings(const dxvk::Config& config) { // Note: Set the last debug view index only if the debug view index was specified to be enabled to something (not disabled). if (debugViewIdx() != DEBUG_VIEW_DISABLED) { @@ -359,6 +384,23 @@ namespace dxvk { } displayTypeRef() = static_cast(std::min(static_cast(displayType()), static_cast(DebugViewDisplayType::Count) - 1)); + + const uint32_t bufferLength = kMaxFramesInFlight; + + DxvkBufferCreateInfo statisticsBufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + statisticsBufferInfo.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + statisticsBufferInfo.stages = VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR; + statisticsBufferInfo.access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_HOST_READ_BIT | VK_ACCESS_HOST_WRITE_BIT; + statisticsBufferInfo.size = bufferLength * sizeof(m_outputStatistics); + m_statisticsBuffer = m_device->createBuffer(statisticsBufferInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, DxvkMemoryStats::Category::RTXBuffer); + + if (areDebugViewStatisticsSupported()) { + // Zero init the whole buffer + vec4* gpuMappedVec4 = reinterpret_cast(m_statisticsBuffer->mapPtr(0)); + for (uint32_t i = 0; i < kMaxFramesInFlight; i++) { + gpuMappedVec4[i] = vec4(0.f, 0.f, 0.f, 0.f); + } + } } void getDebugViewCombo(std::string searchWord, uint32_t& lastView) { @@ -446,6 +488,52 @@ namespace dxvk { } } + void DebugView::processOutputStatistics(Rc& ctx) { + + if (m_showOutputStatistics) { + const uint32_t frameIdx = ctx->getDevice()->getCurrentFrameId(); + + // Read from the oldest element as it is guaranteed to be written out to by the GPU by now + VkDeviceSize offset = ((frameIdx + 1) % kMaxFramesInFlight) * sizeof(m_outputStatistics); + vec4* gpuMappedVec4 = reinterpret_cast(m_statisticsBuffer->mapPtr(offset)); + + m_outputStatistics = *gpuMappedVec4; + + // Zero out the backing memory + *gpuMappedVec4 = vec4(0.f, 0.f, 0.f, 0.f); + } + } + + void DebugView::showOutputStatistics() { + + if (areDebugViewStatisticsSupported()) { + ImGui::Checkbox("Show Output Statistics", &m_showOutputStatistics); + } + + if (m_showOutputStatistics) { + ImGui::Indent(); + + ImGui::Checkbox("Print Output Statistics", &m_printOutputStatistics); + + outputStatisticsCombo.getKey(&m_outputStatisticsMode); + + const std::string statisticsString = str::format( + "RGBA ", + m_outputStatistics.x, ", ", + m_outputStatistics.y, ", ", + m_outputStatistics.z, ", ", + m_outputStatistics.w); + + ImGui::Text(statisticsString.c_str()); + + if (m_printOutputStatistics) { + Logger::info("Debug View Statistics: " + statisticsString); + } + + ImGui::Unindent(); + } + } + void DebugView::showImguiSettings() { // Dealias same widget names from the rest of RTX @@ -500,6 +588,8 @@ namespace dxvk { ImGui::Checkbox("Accumulation", &enableAccumulationObject()); + showOutputStatistics(); + if (enableAccumulation()) { showAccumulationImguiSettings("Accumulation (Aliased with Reference Denoiser's Settings)"); } @@ -763,6 +853,8 @@ namespace dxvk { ctx->clearColorImage(m_instrumentation.image, clearColor, subRange); } } + + processOutputStatistics(ctx); } DebugViewArgs DebugView::getCommonDebugViewArgs( @@ -868,6 +960,11 @@ namespace dxvk { debugViewArgs.enableFp16Accumulation = enableFp16Accumulation(); debugViewArgs.copyOutputToCompositeOutput = shouldRunDispatchPostCompositePass() || replaceCompositeOutput(); + // Statistics params + debugViewArgs.statisticsMode = m_outputStatisticsMode; + debugViewArgs.rcpNumOutputPixels = 1.f / + (debugViewArgs.debugViewResolution.x * debugViewArgs.debugViewResolution.y); + return debugViewArgs; } @@ -881,6 +978,16 @@ namespace dxvk { : RtxOptions::useDenoiserReferenceMode(); } + Rc DebugView::getDebugViewShader() const { + const bool areOptionalExtensionsSupported = m_device->extensions().extShaderAtomicFloat; + + if (areOptionalExtensionsSupported) { + return GET_SHADER_VARIANT(VK_SHADER_STAGE_COMPUTE_BIT, DebugViewShader, debug_view_using_optional_extensions); + } else { + return GET_SHADER_VARIANT(VK_SHADER_STAGE_COMPUTE_BIT, DebugViewShader, debug_view); + } + } + void DebugView::dispatchDebugViewInternal( Rc ctx, Rc nearestSampler, @@ -911,6 +1018,7 @@ namespace dxvk { ReplacementMaterialTextureType::Count - 1)); Resources::Resource terrain = m_device->getCommon()->getSceneManager().getTerrainBaker().getTerrainTexture(terrainTextureType); ctx->bindResourceView(DEBUG_VIEW_BINDING_TERRAIN_INPUT, terrain.view, nullptr); + ctx->bindResourceView(DEBUG_VIEW_BINDING_INPUT, m_debugView.view, nullptr); // Inputs / Outputs @@ -920,14 +1028,21 @@ namespace dxvk { assert(rtOutput.m_compositeOutput.ownsResource() && "Composite output is expected to be valid at this point by default"); ctx->bindResourceView(DEBUG_VIEW_BINDING_COMPOSITE_OUTPUT_INPUT_OUTPUT, rtOutput.m_compositeOutput.view(Resources::AccessType::ReadWrite), nullptr); - ctx->bindResourceView(DEBUG_VIEW_BINDING_INPUT_OUTPUT, m_debugView.view, nullptr); + ctx->bindResourceView(DEBUG_VIEW_BINDING_PREVIOUS_FRAME_INPUT_OUTPUT, m_previousFrameDebugView.view, nullptr); ctx->bindResourceBuffer(DEBUG_VIEW_BINDING_CONSTANTS_INPUT, DxvkBufferSlice(debugViewConstantBuffer, 0, debugViewConstantBuffer->info().size)); ctx->bindResourceSampler(DEBUG_VIEW_BINDING_NEAREST_SAMPLER, nearestSampler); ctx->bindResourceSampler(DEBUG_VIEW_BINDING_LINEAR_SAMPLER, linearSampler); - ctx->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, DebugViewShader::getShader()); + // Outputs + + const uint32_t frameIdx = ctx->getDevice()->getCurrentFrameId(); + VkDeviceSize statisticsBufferOffset = (frameIdx % kMaxFramesInFlight) * sizeof(m_outputStatistics); + ctx->bindResourceBuffer(DEBUG_VIEW_BINDING_STATISTICS_BUFFER_OUTPUT, DxvkBufferSlice(m_statisticsBuffer, statisticsBufferOffset, m_statisticsBuffer->info().size)); + ctx->bindResourceView(DEBUG_VIEW_BINDING_OUTPUT, m_postprocessedDebugView.view, nullptr); + + ctx->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, getDebugViewShader()); const VkExtent3D outputExtent = VkExtent3D { debugViewArgs.debugViewResolution.x, debugViewArgs.debugViewResolution.y, 1 }; @@ -991,12 +1106,12 @@ namespace dxvk { ctx->bindResourceView(DEBUG_VIEW_WAVEFORM_RENDER_BINDING_HDR_WAVEFORM_RED_INPUT, m_hdrWaveformRed.view, nullptr); ctx->bindResourceView(DEBUG_VIEW_WAVEFORM_RENDER_BINDING_HDR_WAVEFORM_GREEN_INPUT, m_hdrWaveformGreen.view, nullptr); ctx->bindResourceView(DEBUG_VIEW_WAVEFORM_RENDER_BINDING_HDR_WAVEFORM_BLUE_INPUT, m_hdrWaveformBlue.view, nullptr); - ctx->bindResourceView(DEBUG_VIEW_WAVEFORM_RENDER_BINDING_INPUT_OUTPUT, m_debugView.view, nullptr); + ctx->bindResourceView(DEBUG_VIEW_WAVEFORM_RENDER_BINDING_INPUT_OUTPUT, m_postprocessedDebugView.view, nullptr); ctx->bindResourceBuffer(DEBUG_VIEW_WAVEFORM_RENDER_BINDING_CONSTANTS_INPUT, DxvkBufferSlice(cb, 0, cb->info().size)); ctx->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, DebugViewWaveformRenderShader::getShader()); - VkExtent3D waveformResolution = m_debugView.view->imageInfo().extent; + VkExtent3D waveformResolution = m_postprocessedDebugView.view->imageInfo().extent; waveformResolution.width /= m_hdrWaveformResolutionScaleFactor; waveformResolution.height /= m_hdrWaveformResolutionScaleFactor; @@ -1006,7 +1121,7 @@ namespace dxvk { } // Replace RT - outputImage = m_debugView.image; + outputImage = m_postprocessedDebugView.image; // Generate a composite image generateCompositeImage(ctx, outputImage); @@ -1076,7 +1191,7 @@ namespace dxvk { } // Lookup src & dest image properties - DxvkImageCreateInfo srcDesc = m_debugView.image->info(); + DxvkImageCreateInfo srcDesc = m_postprocessedDebugView.image->info(); DxvkImageCreateInfo dstDesc = m_composite.compositeView.image->info(); const VkExtent3D srcExtent = srcDesc.extent; const VkExtent3D dstExtent = srcDesc.extent; @@ -1131,7 +1246,7 @@ namespace dxvk { // Blit debug view image to the composite image // Using nearest filter as linear interpolation may produce invalid values for some debug view data (i.e. geometry hash) - ctx->blitImage(m_composite.compositeView.image, identityMap, m_debugView.image, identityMap, region, VK_FILTER_NEAREST); + ctx->blitImage(m_composite.compositeView.image, identityMap, m_postprocessedDebugView.image, identityMap, region, VK_FILTER_NEAREST); outputImage = m_composite.compositeView.image; @@ -1146,6 +1261,7 @@ namespace dxvk { void DebugView::createDownscaledResource(Rc& ctx, const VkExtent3D& downscaledExtent) { // Debug m_debugView = Resources::createImageResource(ctx, "debug view", downscaledExtent, VK_FORMAT_R32G32B32A32_SFLOAT); + m_postprocessedDebugView = Resources::createImageResource(ctx, "postprocessed debug view", downscaledExtent, VK_FORMAT_R32G32B32A32_SFLOAT); m_previousFrameDebugView = Resources::createImageResource(ctx, "previous frame debug view", downscaledExtent, VK_FORMAT_R32G32B32A32_SFLOAT); // Note: Only allocate half resolution for HDR waveform buffers, this is the default view size @@ -1162,6 +1278,7 @@ namespace dxvk { void DebugView::releaseDownscaledResource() { m_debugView.reset(); + m_postprocessedDebugView.reset(); m_previousFrameDebugView.reset(); m_hdrWaveformRed.reset(); m_hdrWaveformBlue.reset(); diff --git a/src/dxvk/rtx_render/rtx_debug_view.h b/src/dxvk/rtx_render/rtx_debug_view.h index 0a92bda58..5dbdcf87f 100644 --- a/src/dxvk/rtx_render/rtx_debug_view.h +++ b/src/dxvk/rtx_render/rtx_debug_view.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -50,6 +50,7 @@ namespace dxvk { void dispatch(Rc ctx, Rc nearestSampler, Rc linearSampler, Rc& outputImage, const Resources::RaytracingOutput& rtOutput, DxvkObjects& common); void dispatchAfterCompositionPass(Rc ctx, Rc nearestSampler, Rc linearSampler, const Resources::RaytracingOutput& rtOutput, DxvkObjects& common); void initSettings(const dxvk::Config& config); + void prewarmShaders(DxvkPipelineManager& pipelineManager) const; void showAccumulationImguiSettings(const char* tabName); void showImguiSettings(); @@ -62,7 +63,7 @@ namespace dxvk { const Rc& getFinalDebugOutput() { return static_cast(m_composite.compositeViewIdx()) != CompositeDebugView::Disabled ? m_composite.compositeView.view - : m_debugView.view; + : m_postprocessedDebugView.view; } const Rc& getInstrumentation() { @@ -84,8 +85,12 @@ namespace dxvk { virtual void onFrameBegin(Rc& ctx, const VkExtent3D& downscaledExtent, const VkExtent3D& targetExtent) override; private: + void processOutputStatistics(Rc& ctx); + void showOutputStatistics(); + bool shouldDebugViewDispatch() const; void createConstantsBuffer(); Rc getDebugViewConstantsBuffer(); + bool areDebugViewStatisticsSupported() const; DebugViewArgs getCommonDebugViewArgs(RtxContext& ctx, const Resources::RaytracingOutput& rtOutput, DxvkObjects& common); @@ -101,6 +106,7 @@ namespace dxvk { void dispatchDebugViewInternal(Rc ctx, Rc nearestSampler, Rc linearSampler, DebugViewArgs& debugViewArgs, Rc& debugViewConstantBuffer, const Resources::RaytracingOutput& rtOutput); bool shouldRunDispatchPostCompositePass() const; bool shouldEnableAccumulation() const; + Rc getDebugViewShader() const; Rc m_debugViewConstants; Rc m_vkd; @@ -199,13 +205,25 @@ namespace dxvk { bool m_cacheCurrentImage = false; bool m_showCachedImage = false; + bool m_showOutputStatistics = false; + bool m_printOutputStatistics = false; Resources::Resource m_cachedImage; Resources::Resource m_debugView; + // Postprocess debug view is transformed input debug view from prior passes. + // It is a separate resource to support gather memory operations on the input buffer, + // while transforming it at per-pixel level + Resources::Resource m_postprocessedDebugView; + // Some non-debug view passes directly write to m_debugView, hence we need a separate resource to retain accumulated result Resources::Resource m_previousFrameDebugView; + // Statistics + DebugViewOutputStatisticsMode m_outputStatisticsMode = DebugViewOutputStatisticsMode::Mean; + Rc m_statisticsBuffer; + vec4 m_outputStatistics; + Resources::Resource m_hdrWaveformRed; Resources::Resource m_hdrWaveformGreen; Resources::Resource m_hdrWaveformBlue; diff --git a/src/dxvk/rtx_render/rtx_initializer.cpp b/src/dxvk/rtx_render/rtx_initializer.cpp index 3a5f311be..5269e7d3c 100644 --- a/src/dxvk/rtx_render/rtx_initializer.cpp +++ b/src/dxvk/rtx_render/rtx_initializer.cpp @@ -139,6 +139,9 @@ namespace dxvk { pCommon->metaPathtracerIntegrateDirect().prewarmShaders(pCommon->pipelineManager()); pCommon->metaPathtracerIntegrateIndirect().prewarmShaders(pCommon->pipelineManager()); + + pCommon->metaDebugView().prewarmShaders(pCommon->pipelineManager()); + // Prewarm the rest of the pipelines that can be done automatically AutoShaderPipelinePrewarmer::prewarmComputePipelines(pCommon->pipelineManager()); } diff --git a/src/dxvk/rtx_render/rtx_pathtracer_integrate_direct.cpp b/src/dxvk/rtx_render/rtx_pathtracer_integrate_direct.cpp index 8dfaa26ab..b5559e5b2 100644 --- a/src/dxvk/rtx_render/rtx_pathtracer_integrate_direct.cpp +++ b/src/dxvk/rtx_render/rtx_pathtracer_integrate_direct.cpp @@ -149,6 +149,8 @@ namespace dxvk { ctx->bindResourceView(INTEGRATE_DIRECT_BINDING_SECONDARY_CONE_RADIUS_INPUT, rtOutput.m_secondaryConeRadius.view(Resources::AccessType::Read), nullptr); ctx->bindResourceView(INTEGRATE_DIRECT_BINDING_SECONDARY_WORLD_POSITION_WORLD_TRIANGLE_NORMAL_INPUT, rtOutput.m_secondaryWorldPositionWorldTriangleNormal.view(Resources::AccessType::Read), nullptr); + // Inputs / Outputs + ctx->bindResourceView(INTEGRATE_DIRECT_BINDING_SHARED_FLAGS_INPUT_OUTPUT, rtOutput.m_sharedFlags.view, nullptr); ctx->bindResourceView(INTEGRATE_DIRECT_BINDING_SHARED_MEDIUM_MATERIAL_INDEX_INPUT_OUTPUT, rtOutput.m_sharedMediumMaterialIndex.view, nullptr); ctx->bindResourceView(INTEGRATE_DIRECT_BINDING_PRIMARY_BASE_REFLECTIVITY_INPUT_OUTPUT, rtOutput.m_primaryBaseReflectivity.view(Resources::AccessType::ReadWrite), nullptr); diff --git a/src/dxvk/rtx_render/rtx_pathtracer_integrate_indirect.cpp b/src/dxvk/rtx_render/rtx_pathtracer_integrate_indirect.cpp index efb4fd02a..ad4988961 100644 --- a/src/dxvk/rtx_render/rtx_pathtracer_integrate_indirect.cpp +++ b/src/dxvk/rtx_render/rtx_pathtracer_integrate_indirect.cpp @@ -91,6 +91,8 @@ namespace dxvk { TEXTURE2D(INTEGRATE_INDIRECT_BINDING_SECONDARY_HIT_DISTANCE_INPUT) TEXTURE2D(INTEGRATE_INDIRECT_BINDING_LAST_COMPOSITE_INPUT) + TEXTURE2DARRAY(INTEGRATE_INDIRECT_BINDING_GRADIENTS_INPUT) + RW_TEXTURE2D(INTEGRATE_INDIRECT_BINDING_INDIRECT_RADIANCE_HIT_DISTANCE_OUTPUT) RW_STRUCTURED_BUFFER(INTEGRATE_INDIRECT_BINDING_RESTIR_GI_RESERVOIR_OUTPUT) RW_TEXTURE2D(INTEGRATE_INDIRECT_BINDING_RESTIR_GI_RADIANCE_OUTPUT) @@ -102,7 +104,6 @@ namespace dxvk { RW_STRUCTURED_BUFFER(INTEGRATE_INDIRECT_BINDING_NEE_CACHE_TASK) RW_TEXTURE2D(INTEGRATE_INDIRECT_BINDING_NEE_CACHE_THREAD_TASK) - TEXTURE2DARRAY(INTEGRATE_INDIRECT_BINDING_GRADIENTS_INPUT) RW_TEXTURE2D(INTEGRATE_INSTRUMENTATION) @@ -149,7 +150,6 @@ namespace dxvk { TEXTURE2D(INTEGRATE_NEE_BINDING_HIT_GEOMETRY_INPUT) TEXTURE2D(INTEGRATE_NEE_BINDING_RADIANCE_INPUT) - RW_TEXTURE2D(INTEGRATE_NEE_BINDING_PRIMARY_BASE_REFLECTIVITY_INPUT_OUTPUT) RW_TEXTURE2D(INTEGRATE_NEE_BINDING_PRIMARY_INDIRECT_DIFFUSE_RADIANCE_HIT_DISTANCE_OUTPUT) @@ -197,7 +197,6 @@ namespace dxvk { TEXTURE2D(INTEGRATE_NEE_BINDING_HIT_GEOMETRY_INPUT) TEXTURE2D(INTEGRATE_NEE_BINDING_RADIANCE_INPUT) - RW_TEXTURE2D(INTEGRATE_NEE_BINDING_PRIMARY_BASE_REFLECTIVITY_INPUT_OUTPUT) RW_TEXTURE2D(INTEGRATE_NEE_BINDING_PRIMARY_INDIRECT_DIFFUSE_RADIANCE_HIT_DISTANCE_OUTPUT) @@ -352,6 +351,8 @@ namespace dxvk { ScopedGpuProfileZone(ctx, "Integrate NEE"); ctx->bindCommonRayTracingResources(rtOutput); + // Inputs + ctx->bindResourceView(INTEGRATE_NEE_BINDING_SHARED_FLAGS_INPUT, rtOutput.m_sharedFlags.view, nullptr); ctx->bindResourceView(INTEGRATE_NEE_BINDING_SHARED_MATERIAL_DATA0_INPUT, rtOutput.m_sharedMaterialData0.view, nullptr); ctx->bindResourceView(INTEGRATE_NEE_BINDING_SHARED_MATERIAL_DATA1_INPUT, rtOutput.m_sharedMaterialData1.view, nullptr); @@ -372,8 +373,12 @@ namespace dxvk { ctx->bindResourceView(INTEGRATE_NEE_BINDING_HIT_GEOMETRY_INPUT, rtOutput.m_restirGIHitGeometry.view, nullptr); ctx->bindResourceView(INTEGRATE_NEE_BINDING_RADIANCE_INPUT, rtOutput.m_restirGIRadiance.view(Resources::AccessType::Read), nullptr); + // Inputs / Outputs + ctx->bindResourceView(INTEGRATE_NEE_BINDING_PRIMARY_BASE_REFLECTIVITY_INPUT_OUTPUT, rtOutput.m_primaryBaseReflectivity.view(Resources::AccessType::ReadWrite), nullptr); + // Outputs + ctx->bindResourceView(INTEGRATE_NEE_BINDING_PRIMARY_INDIRECT_DIFFUSE_RADIANCE_HIT_DISTANCE_OUTPUT, rtOutput.m_primaryIndirectDiffuseRadiance.view(Resources::AccessType::Write), nullptr); ctx->bindResourceView(INTEGRATE_NEE_BINDING_PRIMARY_INDIRECT_SPECULAR_RADIANCE_HIT_DISTANCE_OUTPUT, rtOutput.m_primaryIndirectSpecularRadiance.view(Resources::AccessType::Write), nullptr); diff --git a/src/dxvk/rtx_render/rtx_restir_gi_rayquery.cpp b/src/dxvk/rtx_render/rtx_restir_gi_rayquery.cpp index 9aaf584d0..57036b8a2 100644 --- a/src/dxvk/rtx_render/rtx_restir_gi_rayquery.cpp +++ b/src/dxvk/rtx_render/rtx_restir_gi_rayquery.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -259,8 +259,9 @@ namespace dxvk { void DxvkReSTIRGIRayQuery::dispatch(RtxContext* ctx, const Resources::RaytracingOutput& rtOutput) { - if (!shouldDispatch()) + if (!shouldDispatch()) { return; + } ScopedGpuProfileZone(ctx, "ReSTIR GI"); diff --git a/src/dxvk/rtx_render/rtx_rtxdi_rayquery.cpp b/src/dxvk/rtx_render/rtx_rtxdi_rayquery.cpp index f6b53af43..1acfd6108 100644 --- a/src/dxvk/rtx_render/rtx_rtxdi_rayquery.cpp +++ b/src/dxvk/rtx_render/rtx_rtxdi_rayquery.cpp @@ -66,7 +66,7 @@ namespace dxvk { TEXTURE2D(RTXDI_REUSE_BINDING_PREV_WORLD_POSITION_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_VIEW_DIRECTION_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_CONE_RADIUS_INPUT) - TEXTURE2D(RTXDI_REUSE_BINDING_WS_MVEC_INPUT_OUTPUT) + TEXTURE2D(RTXDI_REUSE_BINDING_WS_MVEC_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_SS_MVEC_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_POSITION_ERROR_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_SHARED_SURFACE_INDEX_INPUT) @@ -102,7 +102,7 @@ namespace dxvk { TEXTURE2D(RTXDI_REUSE_BINDING_PREV_WORLD_POSITION_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_VIEW_DIRECTION_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_CONE_RADIUS_INPUT) - TEXTURE2D(RTXDI_REUSE_BINDING_WS_MVEC_INPUT_OUTPUT) + TEXTURE2D(RTXDI_REUSE_BINDING_WS_MVEC_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_SS_MVEC_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_POSITION_ERROR_INPUT) TEXTURE2D(RTXDI_REUSE_BINDING_SHARED_SURFACE_INDEX_INPUT) @@ -245,6 +245,8 @@ namespace dxvk { { ScopedGpuProfileZone(ctx, "RTXDI Initial & Temporal Reuse"); + // Inputs + // Note: Primary buffers bound as these exhibit coherency for RTXDI and denoising. ctx->bindResourceBuffer(RTXDI_REUSE_BINDING_RTXDI_RESERVOIR, DxvkBufferSlice(rtOutput.m_rtxdiReservoirBuffer, 0, rtOutput.m_rtxdiReservoirBuffer->info().size)); ctx->bindResourceView(RTXDI_REUSE_BINDING_WORLD_SHADING_NORMAL_INPUT, rtOutput.m_primaryWorldShadingNormal.view, nullptr); @@ -255,19 +257,22 @@ namespace dxvk { ctx->bindResourceView(RTXDI_REUSE_BINDING_BASE_REFLECTIVITY_INPUT, rtOutput.m_primaryBaseReflectivity.view(Resources::AccessType::Read), nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_WORLD_POSITION_INPUT, rtOutput.getCurrentPrimaryWorldPositionWorldTriangleNormal().view(Resources::AccessType::Read), nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_PREV_WORLD_POSITION_INPUT, rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().view(Resources::AccessType::Read, rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().matchesWriteFrameIdx(frameIdx - 1)), nullptr); - ctx->bindResourceView(RTXDI_REUSE_BINDING_WS_MVEC_INPUT_OUTPUT, rtOutput.m_primaryVirtualMotionVector.view, nullptr); + ctx->bindResourceView(RTXDI_REUSE_BINDING_WS_MVEC_INPUT, rtOutput.m_primaryVirtualMotionVector.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SS_MVEC_INPUT, rtOutput.m_primaryScreenSpaceMotionVector.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_VIEW_DIRECTION_INPUT, rtOutput.m_primaryViewDirection.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_CONE_RADIUS_INPUT, rtOutput.m_primaryConeRadius.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_POSITION_ERROR_INPUT, rtOutput.m_primaryPositionError.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_LAST_GBUFFER, rtOutput.m_gbufferLast.view, nullptr); - ctx->bindResourceView(RTXDI_REUSE_BINDING_REPROJECTION_CONFIDENCE_OUTPUT, rtOutput.m_reprojectionConfidence.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SHARED_SURFACE_INDEX_INPUT, rtOutput.m_sharedSurfaceIndex.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SUBSURFACE_DATA_INPUT, rtOutput.m_sharedSubsurfaceData.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SHARED_FLAGS_INPUT, rtOutput.m_sharedFlags.view, nullptr); + ctx->bindResourceView(RTXDI_REUSE_BINDING_BEST_LIGHTS_INPUT, rtOutput.m_rtxdiBestLights.view(Resources::AccessType::Read, rtOutput.m_raytraceArgs.enableRtxdiBestLightSampling) , nullptr); + + // Outputs + + ctx->bindResourceView(RTXDI_REUSE_BINDING_REPROJECTION_CONFIDENCE_OUTPUT, rtOutput.m_reprojectionConfidence.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_BSDF_FACTOR_OUTPUT, rtOutput.m_bsdfFactor.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_TEMPORAL_POSITION_OUTPUT, rtOutput.m_primaryRtxdiTemporalPosition.view, nullptr); - ctx->bindResourceView(RTXDI_REUSE_BINDING_BEST_LIGHTS_INPUT, rtOutput.m_rtxdiBestLights.view(Resources::AccessType::Read, rtOutput.m_raytraceArgs.enableRtxdiBestLightSampling) , nullptr); ctx->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, RTXDITemporalReuseShader::getShader()); ctx->dispatch(workgroups.width, workgroups.height, workgroups.depth); @@ -275,6 +280,9 @@ namespace dxvk { { ScopedGpuProfileZone(ctx, "RTXDI Spatial Reuse"); + + // Inputs + // Note: Primary buffers bound as these exhibit coherency for RTXDI and denoising. ctx->bindResourceBuffer(RTXDI_REUSE_BINDING_RTXDI_RESERVOIR, DxvkBufferSlice(rtOutput.m_rtxdiReservoirBuffer, 0, rtOutput.m_rtxdiReservoirBuffer->info().size)); ctx->bindResourceView(RTXDI_REUSE_BINDING_WORLD_SHADING_NORMAL_INPUT, rtOutput.m_primaryWorldShadingNormal.view, nullptr); @@ -284,16 +292,19 @@ namespace dxvk { ctx->bindResourceView(RTXDI_REUSE_BINDING_BASE_REFLECTIVITY_INPUT, rtOutput.m_primaryBaseReflectivity.view(Resources::AccessType::Read), nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_WORLD_POSITION_INPUT, rtOutput.getCurrentPrimaryWorldPositionWorldTriangleNormal().view(Resources::AccessType::Read), nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_PREV_WORLD_POSITION_INPUT, rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().view(Resources::AccessType::Read, rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().matchesWriteFrameIdx(frameIdx - 1)), nullptr); - ctx->bindResourceView(RTXDI_REUSE_BINDING_WS_MVEC_INPUT_OUTPUT, rtOutput.m_primaryVirtualMotionVector.view, nullptr); + ctx->bindResourceView(RTXDI_REUSE_BINDING_WS_MVEC_INPUT, rtOutput.m_primaryVirtualMotionVector.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SS_MVEC_INPUT, rtOutput.m_primaryScreenSpaceMotionVector.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_VIEW_DIRECTION_INPUT, rtOutput.m_primaryViewDirection.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_CONE_RADIUS_INPUT, rtOutput.m_primaryConeRadius.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_POSITION_ERROR_INPUT, rtOutput.m_primaryPositionError.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_LAST_GBUFFER, rtOutput.m_gbufferLast.view, nullptr); - ctx->bindResourceView(RTXDI_REUSE_BINDING_REPROJECTION_CONFIDENCE_OUTPUT, rtOutput.m_reprojectionConfidence.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SHARED_SURFACE_INDEX_INPUT, rtOutput.m_sharedSurfaceIndex.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SUBSURFACE_DATA_INPUT, rtOutput.m_sharedSubsurfaceData.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_SHARED_FLAGS_INPUT, rtOutput.m_sharedFlags.view, nullptr); + + // Outputs + + ctx->bindResourceView(RTXDI_REUSE_BINDING_REPROJECTION_CONFIDENCE_OUTPUT, rtOutput.m_reprojectionConfidence.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_BSDF_FACTOR_OUTPUT, rtOutput.m_bsdfFactor.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_TEMPORAL_POSITION_OUTPUT, rtOutput.m_primaryRtxdiTemporalPosition.view, nullptr); ctx->bindResourceView(RTXDI_REUSE_BINDING_BEST_LIGHTS_INPUT, rtOutput.m_rtxdiBestLights.view(Resources::AccessType::Read, rtOutput.m_raytraceArgs.enableRtxdiBestLightSampling), nullptr); @@ -320,6 +331,8 @@ namespace dxvk { { ScopedGpuProfileZone(ctx, "Compute Gradients"); + // Inputs + ctx->bindResourceBuffer(RTXDI_COMPUTE_GRADIENTS_BINDING_RTXDI_RESERVOIR, DxvkBufferSlice(rtOutput.m_rtxdiReservoirBuffer, 0, rtOutput.m_rtxdiReservoirBuffer->info().size)); ctx->bindResourceView(RTXDI_COMPUTE_GRADIENTS_BINDING_CURRENT_WORLD_POSITION_INPUT, rtOutput.getCurrentPrimaryWorldPositionWorldTriangleNormal().view(Resources::AccessType::Read), nullptr); ctx->bindResourceView(RTXDI_COMPUTE_GRADIENTS_BINDING_PREVIOUS_WORLD_POSITION_INPUT, rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().view(Resources::AccessType::Read, rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().matchesWriteFrameIdx(frameIdx - 1)), nullptr); @@ -334,6 +347,9 @@ namespace dxvk { ctx->bindResourceView(RTXDI_COMPUTE_GRADIENTS_BINDING_HIT_DISTANCE_INPUT, rtOutput.m_primaryHitDistance.view, nullptr); ctx->bindResourceView(RTXDI_COMPUTE_GRADIENTS_BINDING_SHARED_FLAGS_INPUT, rtOutput.m_sharedFlags.view, nullptr); + + // Outputs + ctx->bindResourceView(RTXDI_COMPUTE_GRADIENTS_BINDING_GRADIENTS_OUTPUT, rtOutput.m_rtxdiGradients.view, nullptr); ctx->bindResourceView(RTXDI_COMPUTE_GRADIENTS_BINDING_BEST_LIGHTS_OUTPUT, rtOutput.m_rtxdiBestLights.view(Resources::AccessType::Write), nullptr); @@ -351,8 +367,9 @@ namespace dxvk { void DxvkRtxdiRayQuery::dispatchConfidence(RtxContext* ctx, const Resources::RaytracingOutput& rtOutput) { if (!RtxOptions::Get()->useRTXDI() || - !getEnableDenoiserConfidence()) + !getEnableDenoiserConfidence()) { return; + } ScopedGpuProfileZone(ctx, "RTXDI Confidence"); @@ -389,12 +406,17 @@ namespace dxvk { { ScopedGpuProfileZone(ctx, "Compute Confidence"); + // Inputs + ctx->bindResourceView(RTXDI_COMPUTE_CONFIDENCE_BINDING_GRADIENTS_INPUT, rtOutput.m_rtxdiGradients.view, nullptr); ctx->bindResourceView(RTXDI_COMPUTE_CONFIDENCE_BINDING_MVEC_INPUT, rtOutput.m_primaryScreenSpaceMotionVector.view, nullptr); ctx->bindResourceView(RTXDI_COMPUTE_CONFIDENCE_BINDING_HIT_DISTANCE_INPUT, rtOutput.m_primaryHitDistance.view, nullptr); const bool isPreviousConfidenceValid = rtOutput.getPreviousRtxdiConfidence().matchesWriteFrameIdx(frameIdx - 1); ctx->bindResourceView(RTXDI_COMPUTE_CONFIDENCE_BINDING_PREVIOUS_CONFIDENCE_INPUT, rtOutput.getPreviousRtxdiConfidence().view(Resources::AccessType::Read, isPreviousConfidenceValid), nullptr); + + // Outputs + ctx->bindResourceView(RTXDI_COMPUTE_CONFIDENCE_BINDING_CURRENT_CONFIDENCE_OUTPUT, rtOutput.getCurrentRtxdiConfidence().view(Resources::AccessType::Write), nullptr); ctx->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, RTXDIComputeConfidenceShader::getShader()); diff --git a/src/dxvk/shaders/rtx/algorithm/geometry_resolver.slangh b/src/dxvk/shaders/rtx/algorithm/geometry_resolver.slangh index 7c27a5e32..cad2498ac 100644 --- a/src/dxvk/shaders/rtx/algorithm/geometry_resolver.slangh +++ b/src/dxvk/shaders/rtx/algorithm/geometry_resolver.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -1261,8 +1261,8 @@ void geometryResolverVertex( // Output a miss if (!rayInteractionHasHit(rayInteraction)) { - // Note: Alwrays write to primary surface for initial misses, always will be the selected surface - // in this case as well. + // Note: Always write to primary surface for initial misses, + // it always will be the selected integrated surface in this case as well. geometryResolverOutputMiss(true, true, geometryResolverState.pixelCoordinate); SharedRadianceRG[geometryResolverState.pixelCoordinate] = geometryResolverState.radiance.rg; @@ -1749,7 +1749,7 @@ void geometryPSRResolverVertex( else { // Note: Assume infinite hit distance on miss. This wouldn't be true with things that have a practical tMax - // value (such as NEE rays), but for the geometey resolver this is a fine assumption. + // value (such as NEE rays), but for the geometry resolver this is a fine assumption. volumeTransmittance = translucentSurfaceMaterialEvalInfiniteVolumeTransmittance( translucentSurfaceMaterial); } diff --git a/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh b/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh index b66ebe526..d2eef86fa 100644 --- a/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh +++ b/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -256,7 +256,9 @@ void sampleAndStoreIndirectRayPathSample( // Serialize out the Medium Material Index if it changed if (mediumChanged) + { imageStore(SharedMediumMaterialIndex, pixelCoordinate, mediumMaterialIndex); + } // Output the sampled lobe information for the Indirect integration pass aliasedData0.IndirectRayOriginDirection[pixelCoordinate] = vec4( @@ -441,6 +443,16 @@ void integratorDirectPathOutputDebugView( storeInDebugView(pixelCoordinate, 0); break; } + case DEBUG_VIEW_NOISY_SECONDARY_DIRECT_RADIANCE: + { + if (!geometryFlags.primarySelectedIntegrationSurface) + { + storeInDebugView(pixelCoordinate, + directPathTextures.SecondaryCombinedDiffuseLobeRadianceHitDistance[pixelCoordinate].xyz + + directPathTextures.SecondaryCombinedSpecularLobeRadianceHitDistance[pixelCoordinate].xyz); + } + break; + } case DEBUG_VIEW_PERCEPTUAL_ROUGHNESS: storeInDebugView(pixelCoordinate, directPathTextures.IndirectFirstHitPerceptualRoughness[pixelCoordinate]); break; diff --git a/src/dxvk/shaders/rtx/algorithm/integrator_indirect.slangh b/src/dxvk/shaders/rtx/algorithm/integrator_indirect.slangh index 3a3ccda25..d3d702a2c 100644 --- a/src/dxvk/shaders/rtx/algorithm/integrator_indirect.slangh +++ b/src/dxvk/shaders/rtx/algorithm/integrator_indirect.slangh @@ -392,7 +392,7 @@ void integratePathVertex( else { // Note: Assume infinite hit distance on miss. This wouldn't be true with things that have a practical tMax - // value (such as NEE rays), but for the geometey resolver this is a fine assumption. + // value (such as NEE rays), but for the geometry resolver this is a fine assumption. volumeTransmittance = translucentSurfaceMaterialEvalInfiniteVolumeTransmittance( translucentSurfaceMaterial); } @@ -407,7 +407,8 @@ void integratePathVertex( float lightSelectionPDF = 0.0; #if (SURFACE_MATERIAL_RESOLVE_TYPE_ACTIVE_MASK & SURFACE_MATERIAL_RESOLVE_TYPE_RAY_PORTAL) != 0 - if(materialType == surfaceMaterialTypeOpaque || materialType == surfaceMaterialTypeTranslucent) { + if (materialType == surfaceMaterialTypeOpaque || materialType == surfaceMaterialTypeTranslucent) + { #endif // SURFACE_MATERIAL_RESOLVE_TYPE_RAY_PORTAL if (NEE_CACHE_ENABLE && cb.neeCacheArgs.enable && isNeeEnabledOnBounce && any(emissiveLight > 0)) @@ -454,7 +455,8 @@ void integratePathVertex( // We don't need to sample lights or surface rays in the portal closest hit shader #if (SURFACE_MATERIAL_RESOLVE_TYPE_ACTIVE_MASK & SURFACE_MATERIAL_RESOLVE_TYPE_RAY_PORTAL) != 0 - if(materialType == surfaceMaterialTypeOpaque || materialType == surfaceMaterialTypeTranslucent) { + if (materialType == surfaceMaterialTypeOpaque || materialType == surfaceMaterialTypeTranslucent) + { #endif // SURFACE_MATERIAL_RESOLVE_TYPE_RAY_PORTAL // Construct RNG @@ -587,7 +589,9 @@ void integratePathVertex( uint lightTask = lightIdx; - if(NEE_CACHE_ENABLE && cb.neeCacheArgs.enable && cb.neeCacheArgs.enableModeAfterFirstBounce != NeeEnableMode::None && pathState.enableNeeCacheAfterFirstBounce) + if (NEE_CACHE_ENABLE && cb.neeCacheArgs.enable && + cb.neeCacheArgs.enableModeAfterFirstBounce != NeeEnableMode::None && + pathState.enableNeeCacheAfterFirstBounce) { NEECell cell = NEECache.getCell(pathState.neeCacheCellOffset); if (cell.isValid() && cell.getCandidateCount() > 0) @@ -638,15 +642,18 @@ void integratePathVertex( // Create a NEE Cache task for lights with non-zero contributions. // Both light task and emissive triangle task are using the same buffer, skip some pixels so that triangle tasks on them won't be overwritten by light tasks. - if (NEE_CACHE_ENABLE && cb.neeCacheArgs.enable && any(diffuseLight + specularLight > 0) && all((pathState.pixelCoordinate & 0x3) != 1)) + const vec3 neeLight = diffuseLight + specularLight; + if (NEE_CACHE_ENABLE && cb.neeCacheArgs.enable && + any(neeLight > 0) && + all((pathState.pixelCoordinate & 0x3) != 1)) { NEECell cell = NEECache.getCell(pathState.neeCacheCellOffset); - cell.insertSlotTask(lightTask, diffuseLight + specularLight, lightIdx != kInvalidLightIdx); + cell.insertSlotTask(lightTask, neeLight, lightIdx != kInvalidLightIdx); } - vec3 neeLight = diffuseLight + specularLight; float16_t specularPortion = calcBt709Luminance(specularLight) / calcBt709Luminance(neeLight); - pathState.radiance += pathState.throughput * neeLight; + + accumulateRadiance(pathState, neeLight); float hitT = pathState.accumulatedHitDistance; if (opaqueSurfaceMaterialInteraction.isotropicRoughness <= cb.reSTIRGIVirtualSampleRoughnessThreshold @@ -834,6 +841,7 @@ void integratePathVertex( } accumulateThroughput(pathState, continuationThroughput); + #if (SURFACE_MATERIAL_RESOLVE_TYPE_ACTIVE_MASK & SURFACE_MATERIAL_RESOLVE_TYPE_RAY_PORTAL) != 0 } #endif // SURFACE_MATERIAL_RESOLVE_TYPE_RAY_PORTAL @@ -1097,6 +1105,13 @@ void integratorIndirectPathOutputDebugView( storeInDebugView(ivec2(pixelCoordinate), 0); } break; + case DEBUG_VIEW_NOISY_SECONDARY_INDIRECT_RADIANCE: + if (!geometryFlags.primarySelectedIntegrationSurface) + { + storeInDebugView(ivec2(pixelCoordinate), pathState.radiance); + } + break; + case DEBUG_VIEW_NAN: { bool isValid = true; diff --git a/src/dxvk/shaders/rtx/algorithm/path_state.slangh b/src/dxvk/shaders/rtx/algorithm/path_state.slangh index 06ec0f469..e78145a62 100644 --- a/src/dxvk/shaders/rtx/algorithm/path_state.slangh +++ b/src/dxvk/shaders/rtx/algorithm/path_state.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -108,23 +108,30 @@ struct PathState struct MemoryPathState : IPayload { vec3 origin; - uint data0; // bounceIteration(uint:4b), restirGiHasHitGeometry(bool:1b), restirGiHasHitOpaque(bool:1b), coneSpreadAngle(float16), mediumMaterialIndexLow(uint:8b) + uint data0; // bounceIteration(uint:4b) + // restirGiHasHitGeometry(bool:1b) + // restirGiHasHitOpaque(bool:1b) + // unused(2b) + // coneSpreadAngle(float16) + // unused (1b - coneSpreadAngle sign bit) + // mediumMaterialIndexLow(uint:8b) uvec3 encodedRadiance; // unused (x:1b, z:1b) uint encodedDirection; uvec3 encodedThroughput; - uint data1; // unused(7b), + uint data1; // unused (7b), // restirGiHasFoundRoughSurface(bool:1b) // RayMask(uint8_t:8b), // PortalSpace(uint:2b), // indirectLightPortalID(uint:2b), // mediumMaterialIndexHigh(uint:8b), - // Unused (4b) + // unused (4b) uint coneRadiusAndHitDistance; // float16_t, float16_t - float accumulatedHitDistance; - uint solidAnglePdfAndNeeCacheCellOffset; + // unused (2b - sign bits) + float accumulatedHitDistance; // unused (1b - sign bit) + uint solidAnglePdfAndNeeCacheCellOffset; // unused (1b - solidAnglePdf sign bit) float segmentHitDistance; static MemoryPathState pack(PathState pathState) @@ -269,5 +276,4 @@ struct IndirectPathTextures RWTexture2D IndirectRadianceHitDistance; REORDER_COHERENT RWTexture2D RestirGIRadiance; RWTexture2D RestirGIHitGeometry; - Texture2D GBufferLast; -}; \ No newline at end of file +}; diff --git a/src/dxvk/shaders/rtx/algorithm/resolve.slangh b/src/dxvk/shaders/rtx/algorithm/resolve.slangh index b5b4e1a69..034460bda 100644 --- a/src/dxvk/shaders/rtx/algorithm/resolve.slangh +++ b/src/dxvk/shaders/rtx/algorithm/resolve.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -739,7 +739,7 @@ uint8_t convertPrimaryRayMaskToUnordered(uint8_t primaryRayMask, uint8_t unorder } // Handles unordered Resolve operations within the resolve loop which do not depend on the typical ordered execution -// fo the resolve logic. +// for the resolve logic. void resolveVertexUnordered( uint8_t resolveMode, Ray ray, uint rayMask, PortalSpace2BitsType portalSpace, diff --git a/src/dxvk/shaders/rtx/pass/debug_view/debug_view.comp.slang b/src/dxvk/shaders/rtx/pass/debug_view/debug_view.comp.slang index fbc8ced9a..fbe352763 100644 --- a/src/dxvk/shaders/rtx/pass/debug_view/debug_view.comp.slang +++ b/src/dxvk/shaders/rtx/pass/debug_view/debug_view.comp.slang @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,8 +19,18 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ + +//!variant debug_view.comp +//!> ENABLE_DEBUG_VIEW_OPTIONAL_FEATURES=0 + +//!variant debug_view_using_optional_extensions.comp +//!> ENABLE_DEBUG_VIEW_OPTIONAL_FEATURES=1 + +//!end-variants + #include "rtx/pass/debug_view/debug_view_args.h" #include "rtx/pass/debug_view/debug_view_binding_indices.h" +#include "rtx/utility/debug_view_indices.h" #include "rtx/utility/geometry_flags.slangh" // Inputs @@ -51,8 +61,11 @@ layout(r32ui, binding = DEBUG_VIEW_BINDING_INSTRUMENTATION_INPUT) Texture2D Instrumentation; layout(rgba16f, binding = DEBUG_VIEW_BINDING_TERRAIN_INPUT) Texture2D TerrainTexture; +layout(rgba32f, binding = DEBUG_VIEW_BINDING_INPUT) +Texture2D DebugView; + +// Inputs / Outputs -// Inputs / Output layout(r32ui, binding = DEBUG_VIEW_BINDING_HDR_WAVEFORM_RED_INPUT_OUTPUT) RWTexture2D HDRWaveformRedInputOutput; layout(r32ui, binding = DEBUG_VIEW_BINDING_HDR_WAVEFORM_GREEN_INPUT_OUTPUT) @@ -63,8 +76,8 @@ RWTexture2D HDRWaveformBlueInputOutput; layout(rgba16f, binding = DEBUG_VIEW_BINDING_COMPOSITE_OUTPUT_INPUT_OUTPUT) RWTexture2D CompositeOutput; -layout(rgba32f, binding = DEBUG_VIEW_BINDING_INPUT_OUTPUT) -RWTexture2D DebugView; +layout(rgba32f, binding = DEBUG_VIEW_BINDING_OUTPUT) +RWTexture2D DebugViewOutput; layout(rgba32f, binding = DEBUG_VIEW_BINDING_PREVIOUS_FRAME_INPUT_OUTPUT) RWTexture2D PreviousFrameDebugView; @@ -78,11 +91,14 @@ SamplerState LinearSampler; layout(binding = DEBUG_VIEW_BINDING_CONSTANTS_INPUT) ConstantBuffer cb; +// Outputs + +layout(binding = DEBUG_VIEW_BINDING_STATISTICS_BUFFER_OUTPUT) +RWStructuredBuffer DebugViewStatistics; + #include "rtx/utility/common.slangh" #include "rtx/utility/color.slangh" #include "rtx/utility/packing.slangh" -#include "rtx/utility/debug_view_helpers.slangh" -//#include "rtx/utility/gbuffer_helpers.slangh" #include "rtx/external/NRD.slangh" float4 sampleTexture(Texture2D texture, ivec2 threadId) @@ -123,8 +139,8 @@ vec4 nrdDenoisedHitTtoColor(ivec2 threadId) float normalizedHitT; float primaryHitPerceptualRoughness; - switch (cb.debugViewIdx) { - + switch (cb.debugViewIdx) + { case DEBUG_VIEW_DENOISED_PRIMARY_DIRECT_DIFFUSE_HIT_T: normalizedHitT = DenoisedPrimaryDirectDiffuseRadianceHitT[threadId].w; primaryHitPerceptualRoughness = 1.0; @@ -162,6 +178,40 @@ vec4 unormVectorToColor(vec3 unormVector) return vec4(unormVector * 2.0 - 1.0, 1.0); } +// Color codes a value into BGR, with only one channel being used to color code at a time +// Black: 0 value +// Red: values >= than max value +// Blue/Green (0,1]: the remaining values, with blue representing the lower half of valid range and green the rest +vec3 colorCodeIntoBGRexclusive(uint value, uint maxValue) +{ + if (value == 0) + { + return vec3(0); + } + else if (value >= maxValue) + { + return vec3(1, 0, 0); + } + + // Color code the rest, [1, maxValue-1], to a non-black BG color, one channel at a time + + value -= 1; + const uint numValues = maxValue - 1; + + const float numChannels = 2; + const uint ceilValuesPerChannel = ceil(numValues / numChannels); + + vec3 color = 0; + const uint channel = value / ceilValuesPerChannel; + const uint numValuesInCurrentChannel = min(numValues - channel * ceilValuesPerChannel, ceilValuesPerChannel); + + // Color code as (0,1] + color[channel] = (float(value % numValuesInCurrentChannel) + 1) / numValuesInCurrentChannel; + + // Reswizzle to show lowest values in Blue and highest in Red + return color.bgr; +} + vec4 loadInput(ivec2 threadId) { vec4 value; @@ -182,7 +232,8 @@ vec4 loadInput(ivec2 threadId) // Get the respective input based on the debug index - switch (cb.debugViewIdx) { + switch (cb.debugViewIdx) + { case DEBUG_VIEW_VIRTUAL_SHADING_NORMAL: value = unormVectorToColor(PrimaryVirtualWorldNormalPerceptualRoughness[threadId].xyz); break; @@ -271,7 +322,9 @@ vec4 loadInput(ivec2 threadId) } } else - value = FinalShading[upscaledPixelCoordinate]; + { + value = FinalShading[upscaledPixelCoordinate]; + } break; case DEBUG_VIEW_INSTRUMENTATION_THREAD_DIVERGENCE: value = float4(Instrumentation[threadId], 0, 0, 0); @@ -290,10 +343,12 @@ vec4 loadInput(ivec2 threadId) case DEBUG_VIEW_SCROLLING_LINE: value = FinalShading[upscaledPixelCoordinate]; if (threadId.x == (cb.frameIdx + 10) % cb.debugViewResolution.x) + { value = float4(0, 1, 1, 1); + } break; case DEBUG_VIEW_NAN: - bool isValid = readInDebugView(threadId).x != 0.0; + bool isValid = DebugView[threadId].x != 0.0; // DEBUG_VIEW_VIRTUAL_SHADING_NORMAL isValid &= isValidValue(unormVectorToColor(PrimaryVirtualWorldNormalPerceptualRoughness[threadId].xyz)); // DEBUG_VIEW_VIRTUAL_MOTION_VECTOR @@ -351,7 +406,8 @@ vec4 loadInput(ivec2 threadId) // quantize with a step size of 1/255) primarily to visualize banding artifacts better without the often times larger floating point precision of the input // textures hiding them. - if (cb.enableInputQuantization) { + if (cb.enableInputQuantization) + { value = round(value * cb.quantizationInverseStepSize) * cb.quantizationStepSize; } @@ -502,11 +558,37 @@ f16vec4 lerpFp16(f16vec4 a, f16vec4 b, float16_t lerpFactor) return a * (1.h - lerpFactor) + b * lerpFactor; } +void storeDebugViewOutputStatistics(vec4 value) +{ +#if ENABLE_DEBUG_VIEW_OPTIONAL_FEATURES + // Optional features guarantees float atomics support + +#define INTERLOCKED_OP_VEC4(INTERLOCKED_OP, STRUCTURED_BUFFER_FLOAT, vec4Value) \ + INTERLOCKED_OP(STRUCTURED_BUFFER_FLOAT[0], vec4Value.x); \ + INTERLOCKED_OP(STRUCTURED_BUFFER_FLOAT[1], vec4Value.y); \ + INTERLOCKED_OP(STRUCTURED_BUFFER_FLOAT[2], vec4Value.z); \ + INTERLOCKED_OP(STRUCTURED_BUFFER_FLOAT[3], vec4Value.w) + + switch (cb.statisticsMode) + { + case DebugViewOutputStatisticsMode::Sum: + default: + INTERLOCKED_OP_VEC4(InterlockedAddFloat, DebugViewStatistics, value); + break; + case DebugViewOutputStatisticsMode::Mean: + value *= cb.rcpNumOutputPixels; + INTERLOCKED_OP_VEC4(InterlockedAddFloat, DebugViewStatistics, value); + break; + }; +#endif +} + void storeToDebugView(uint2 threadId, vec4 value) { vec4 output; - switch (cb.accumulationMode) { + switch (cb.accumulationMode) + { case DebugViewAccumulationMode::WriteNewOutput: default: output = value; @@ -531,13 +613,15 @@ void storeToDebugView(uint2 threadId, vec4 value) } } - DebugView[threadId] = output; + DebugViewOutput[threadId] = output; PreviousFrameDebugView[threadId] = output; if (cb.copyOutputToCompositeOutput) { CompositeOutput[threadId] = output; } + + storeDebugViewOutputStatistics(output); } [shader("compute")] @@ -545,7 +629,9 @@ void storeToDebugView(uint2 threadId, vec4 value) void main(uint2 threadId : SV_DispatchThreadID) { if (any(threadId >= cb.debugViewResolution)) + { return; + } vec4 outValue = loadInput(threadId); diff --git a/src/dxvk/shaders/rtx/pass/debug_view/debug_view_args.h b/src/dxvk/shaders/rtx/pass/debug_view/debug_view_args.h index dc9e1b2ad..39afd2c62 100644 --- a/src/dxvk/shaders/rtx/pass/debug_view/debug_view_args.h +++ b/src/dxvk/shaders/rtx/pass/debug_view/debug_view_args.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -60,6 +60,13 @@ enum class DebugViewAccumulationMode : uint32_t { CarryOverPreviousOutput }; +enum class DebugViewOutputStatisticsMode : uint32_t { + Mean = 0, + Sum, + + Count +}; + struct DebugViewArgs { uint debugViewIdx; int colorCodeRadius; @@ -120,4 +127,7 @@ struct DebugViewArgs { uint enableFp16Accumulation; uint copyOutputToCompositeOutput; DebugViewAccumulationMode accumulationMode; + + DebugViewOutputStatisticsMode statisticsMode; + float rcpNumOutputPixels; }; diff --git a/src/dxvk/shaders/rtx/pass/debug_view/debug_view_binding_indices.h b/src/dxvk/shaders/rtx/pass/debug_view/debug_view_binding_indices.h index 34fce1998..a9e748030 100644 --- a/src/dxvk/shaders/rtx/pass/debug_view/debug_view_binding_indices.h +++ b/src/dxvk/shaders/rtx/pass/debug_view/debug_view_binding_indices.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -44,6 +44,8 @@ #define DEBUG_VIEW_BINDING_TERRAIN_INPUT 17 #define DEBUG_VIEW_BINDING_UPSCALED_RESOLVED_COLOR 18 +#define DEBUG_VIEW_BINDING_INPUT 20 + // Inputs / Outputs #define DEBUG_VIEW_BINDING_HDR_WAVEFORM_RED_INPUT_OUTPUT 50 #define DEBUG_VIEW_BINDING_HDR_WAVEFORM_GREEN_INPUT_OUTPUT 51 @@ -51,11 +53,12 @@ #define DEBUG_VIEW_BINDING_COMPOSITE_OUTPUT_INPUT_OUTPUT 60 -#define DEBUG_VIEW_BINDING_INPUT_OUTPUT 70 #define DEBUG_VIEW_BINDING_PREVIOUS_FRAME_INPUT_OUTPUT 71 // Samplers #define DEBUG_VIEW_BINDING_NEAREST_SAMPLER 80 #define DEBUG_VIEW_BINDING_LINEAR_SAMPLER 81 -// Outputs \ No newline at end of file +// Outputs +#define DEBUG_VIEW_BINDING_STATISTICS_BUFFER_OUTPUT 90 +#define DEBUG_VIEW_BINDING_OUTPUT 95 diff --git a/src/dxvk/shaders/rtx/pass/debug_view/debug_view_waveform_render.comp.slang b/src/dxvk/shaders/rtx/pass/debug_view/debug_view_waveform_render.comp.slang index 130bb464b..591fe3ba2 100644 --- a/src/dxvk/shaders/rtx/pass/debug_view/debug_view_waveform_render.comp.slang +++ b/src/dxvk/shaders/rtx/pass/debug_view/debug_view_waveform_render.comp.slang @@ -40,8 +40,10 @@ ConstantBuffer cb; void main(uint2 threadId : SV_DispatchThreadID) { if (any(threadId >= cb.hdrWaveformResolution)) + { return; - + } + // Normalize the accumulated HDR Waveform values for display const uvec2 flippedCoordinate = uvec2(threadId.x, cb.hdrWaveformResolution.y - threadId.y - 1); diff --git a/src/dxvk/shaders/rtx/pass/demodulate/demodulate.comp.slang b/src/dxvk/shaders/rtx/pass/demodulate/demodulate.comp.slang index 70ae1a978..3b0dc08db 100644 --- a/src/dxvk/shaders/rtx/pass/demodulate/demodulate.comp.slang +++ b/src/dxvk/shaders/rtx/pass/demodulate/demodulate.comp.slang @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -434,6 +434,30 @@ void outputToDebugViewAtTheEnd( case DEBUG_VIEW_NOISY_DEMODULATED_SECONDARY_COMBINED_SPECULAR_RADIANCE: storeInDebugView(ivec2(pixelCoordinate), secondaryCombinedSpecularOutput.xyz); break; + case DEBUG_VIEW_NOISY_PRIMARY_DIRECT_RADIANCE: + storeInDebugView(ivec2(pixelCoordinate), + primaryDirectDiffuseInput.xyz + primaryDirectSpecularInput.xyz); + break; + case DEBUG_VIEW_NOISY_PRIMARY_INDIRECT_RADIANCE: + storeInDebugView(ivec2(pixelCoordinate), + primaryIndirectDiffuseInput.xyz + primaryIndirectSpecularInput.xyz); + break; + case DEBUG_VIEW_NOISY_PRIMARY_RADIANCE: + storeInDebugView(ivec2(pixelCoordinate), + primaryDirectDiffuseInput.xyz + primaryDirectSpecularInput.xyz + + primaryIndirectDiffuseInput.xyz + primaryIndirectSpecularInput.xyz); + break; + case DEBUG_VIEW_NOISY_SECONDARY_RADIANCE: + storeInDebugView(ivec2(pixelCoordinate), + secondaryCombinedDiffuseInput.xyz + secondaryCombinedSpecularInput.xyz); + break; + case DEBUG_VIEW_NOISY_RADIANCE: + storeInDebugView(ivec2(pixelCoordinate), + primaryDirectDiffuseInput.xyz + primaryDirectSpecularInput.xyz + + primaryIndirectDiffuseInput.xyz + primaryIndirectSpecularInput.xyz + + secondaryCombinedDiffuseInput.xyz + secondaryCombinedSpecularInput.xyz); + break; + case DEBUG_VIEW_NAN: { bool isValid = true; @@ -585,6 +609,7 @@ void main(uint2 pixelCoordinate : SV_DispatchThreadID, uint2 localIndex : SV_Gro primaryIndirectDiffuseInput = PrimaryIndirectDiffuseRadiance[pixelCoordinate]; primaryIndirectSpecularInput = PrimaryIndirectSpecularRadiance[pixelCoordinate]; } + // Load the secondary combined signals if (geometryFlags.secondarySurfaceMask && !geometryFlags.primarySelectedIntegrationSurface) { diff --git a/src/dxvk/shaders/rtx/pass/gbuffer/gbuffer.slang b/src/dxvk/shaders/rtx/pass/gbuffer/gbuffer.slang index b3bfb8461..097d4452a 100644 --- a/src/dxvk/shaders/rtx/pass/gbuffer/gbuffer.slang +++ b/src/dxvk/shaders/rtx/pass/gbuffer/gbuffer.slang @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -100,7 +100,9 @@ void main() void main(uint2 ipos : SV_DispatchThreadID) { if (any(ipos >= cb.camera.resolution)) + { return; + } #ifdef GBUFFER_PSR geometryPSRResolverPass(ipos); diff --git a/src/dxvk/shaders/rtx/pass/integrate/integrate_direct.slangh b/src/dxvk/shaders/rtx/pass/integrate/integrate_direct.slangh index 9327cf719..956ab205f 100644 --- a/src/dxvk/shaders/rtx/pass/integrate/integrate_direct.slangh +++ b/src/dxvk/shaders/rtx/pass/integrate/integrate_direct.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -71,7 +71,9 @@ void deserializeInteractions( void integrate_direct_pass(ivec2 threadIndex) { if (any(threadIndex >= cb.camera.resolution)) + { return; + } RNG rng = createRNG(uvec2(threadIndex), cb.frameIdx); @@ -94,7 +96,8 @@ void integrate_direct_pass(ivec2 threadIndex) imageStore(PrimaryDirectSpecularLobeRadianceHitDistance, threadIndex, vec4(0.0f, 0.0f, 0.0f, 0.0f)); // Note: Early out if no more work on the primary surface is needed. - if (geometryFlags.primarySelectedIntegrationSurface) { + if (geometryFlags.primarySelectedIntegrationSurface) + { return; } } @@ -105,10 +108,11 @@ void integrate_direct_pass(ivec2 threadIndex) imageStore(SecondaryCombinedSpecularLobeRadianceHitDistance, threadIndex, vec4(0.0f, 0.0f, 0.0f, 0.0f)); // Note: Early out if no more work on the secondary surface is needed. - if (!geometryFlags.primarySelectedIntegrationSurface) { + if (!geometryFlags.primarySelectedIntegrationSurface) + { return; } - } + } // Read the integration surface PDF diff --git a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect.slangh b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect.slangh index a50404693..fd0ad05ec 100644 --- a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect.slangh +++ b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -34,7 +34,9 @@ void integrate_indirect_pass(ivec2 threadIndex) { if (any(threadIndex >= cb.camera.resolution)) + { return; + } // Deserialize flags @@ -49,24 +51,17 @@ void integrate_indirect_pass(ivec2 threadIndex) // Note: This should hopefully prevent any weird undefined data from bleeding into pixels actually being denoised, but // may not be needed depending on how the denoiser works. - if (primaryGBufferMiss) - { - // Note: Early out if no more work on the primary surface is needed. - if (geometryFlags.primarySelectedIntegrationSurface) - { - aliasedData0.IndirectRadianceHitDistance[threadIndex] = vec4(vec3(0), kEmptyPixelHitDistance); - return; - } - } + bool gbufferMissOfASelectedIntegrationSurface = + geometryFlags.primarySelectedIntegrationSurface + ? primaryGBufferMiss + : secondaryGBufferMiss; - if (secondaryGBufferMiss) + // Note: Early out if no more work on the active surface is needed. + if (gbufferMissOfASelectedIntegrationSurface) { - // Note: Early out if no more work on the secondary surface is needed. - if (!geometryFlags.primarySelectedIntegrationSurface) - { - aliasedData0.IndirectRadianceHitDistance[threadIndex] = vec4(vec3(0), kEmptyPixelHitDistance); - return; - } + aliasedData0.IndirectRadianceHitDistance[threadIndex] = vec4(vec3(0), kEmptyPixelHitDistance); + + return; } // Read the medium material index @@ -102,7 +97,6 @@ void integrate_indirect_pass(ivec2 threadIndex) indirectPathTextures.IndirectRadianceHitDistance = aliasedData0.IndirectRadianceHitDistance; indirectPathTextures.RestirGIRadiance = RestirGIRadiance; indirectPathTextures.RestirGIHitGeometry = RestirGIHitGeometry; - indirectPathTextures.GBufferLast = GBufferLast; integrateIndirectPath( threadIndex, INTEGRATE_INDIRECT_SBT_OFFSET_STANDARD, indirectPathTextures, diff --git a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_binding_indices.h b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_binding_indices.h index 8a8f33cc8..253ca5b8e 100644 --- a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_binding_indices.h +++ b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_binding_indices.h @@ -64,7 +64,6 @@ #define INTEGRATE_INDIRECT_BINDING_RESTIR_GI_RADIANCE_OUTPUT 71 #define INTEGRATE_INDIRECT_BINDING_RESTIR_GI_HIT_GEOMETRY_OUTPUT 72 - // Aliased Inputs/Outputs #define INTEGRATE_INDIRECT_BINDING_ALIASED_DATA_0 90 diff --git a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_closesthit.rchit.slang b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_closesthit.rchit.slang index 95bf4a156..f010a68f1 100644 --- a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_closesthit.rchit.slang +++ b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_closesthit.rchit.slang @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -92,7 +92,6 @@ void main(inout MemoryPathState rayPayload : SV_RayPayload, in float2 barycentri indirectPathTextures.IndirectRadianceHitDistance = aliasedData0.IndirectRadianceHitDistance; indirectPathTextures.RestirGIRadiance = RestirGIRadiance; indirectPathTextures.RestirGIHitGeometry = RestirGIHitGeometry; - indirectPathTextures.GBufferLast = GBufferLast; PathState pathState = rayPayload.unpack(); diff --git a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_miss.rmiss.slang b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_miss.rmiss.slang index f4b8980f6..b3b21e67e 100644 --- a/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_miss.rmiss.slang +++ b/src/dxvk/shaders/rtx/pass/integrate/integrate_indirect_miss.rmiss.slang @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -61,7 +61,6 @@ void main(inout MemoryPathState rayPayload : SV_RayPayload) indirectPathTextures.IndirectRadianceHitDistance = aliasedData0.IndirectRadianceHitDistance; indirectPathTextures.RestirGIRadiance = RestirGIRadiance; indirectPathTextures.RestirGIHitGeometry = RestirGIHitGeometry; - indirectPathTextures.GBufferLast = GBufferLast; PathState pathState = rayPayload.unpack(); diff --git a/src/dxvk/shaders/rtx/pass/integrate/integrate_nee_binding_indices.h b/src/dxvk/shaders/rtx/pass/integrate/integrate_nee_binding_indices.h index 835d77b98..399c59cbf 100644 --- a/src/dxvk/shaders/rtx/pass/integrate/integrate_nee_binding_indices.h +++ b/src/dxvk/shaders/rtx/pass/integrate/integrate_nee_binding_indices.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -30,33 +30,33 @@ struct VisualizeNeeArgs // Inputs -#define INTEGRATE_NEE_BINDING_SHARED_FLAGS_INPUT 40 -#define INTEGRATE_NEE_BINDING_SHARED_MATERIAL_DATA0_INPUT 41 -#define INTEGRATE_NEE_BINDING_SHARED_MATERIAL_DATA1_INPUT 42 -#define INTEGRATE_NEE_BINDING_SHARED_TEXTURE_COORD_INPUT 43 -#define INTEGRATE_NEE_BINDING_SHARED_SURFACE_INDEX_INPUT 44 -#define INTEGRATE_NEE_BINDING_SHARED_SUBSURFACE_DATA_INPUT 45 +#define INTEGRATE_NEE_BINDING_SHARED_FLAGS_INPUT 40 +#define INTEGRATE_NEE_BINDING_SHARED_MATERIAL_DATA0_INPUT 41 +#define INTEGRATE_NEE_BINDING_SHARED_MATERIAL_DATA1_INPUT 42 +#define INTEGRATE_NEE_BINDING_SHARED_TEXTURE_COORD_INPUT 43 +#define INTEGRATE_NEE_BINDING_SHARED_SURFACE_INDEX_INPUT 44 +#define INTEGRATE_NEE_BINDING_SHARED_SUBSURFACE_DATA_INPUT 45 -#define INTEGRATE_NEE_BINDING_PRIMARY_WORLD_SHADING_NORMAL_INPUT 46 -#define INTEGRATE_NEE_BINDING_PRIMARY_PERCEPTUAL_ROUGHNESS_INPUT 47 -#define INTEGRATE_NEE_BINDING_PRIMARY_ALBEDO_INPUT 48 -#define INTEGRATE_NEE_BINDING_PRIMARY_VIEW_DIRECTION_INPUT 49 -#define INTEGRATE_NEE_BINDING_PRIMARY_CONE_RADIUS_INPUT 50 -#define INTEGRATE_NEE_BINDING_PRIMARY_WORLD_POSITION_INPUT 51 +#define INTEGRATE_NEE_BINDING_PRIMARY_WORLD_SHADING_NORMAL_INPUT 46 +#define INTEGRATE_NEE_BINDING_PRIMARY_PERCEPTUAL_ROUGHNESS_INPUT 47 +#define INTEGRATE_NEE_BINDING_PRIMARY_ALBEDO_INPUT 48 +#define INTEGRATE_NEE_BINDING_PRIMARY_VIEW_DIRECTION_INPUT 49 +#define INTEGRATE_NEE_BINDING_PRIMARY_CONE_RADIUS_INPUT 50 +#define INTEGRATE_NEE_BINDING_PRIMARY_WORLD_POSITION_INPUT 51 -#define INTEGRATE_NEE_BINDING_PRIMARY_POSITION_ERROR_INPUT 52 -#define INTEGRATE_NEE_BINDING_PRIMARY_HIT_DISTANCE_INPUT 53 -#define INTEGRATE_NEE_BINDING_PRIMARY_WORLD_INTERPOLATED_NORMAL_INPUT 54 -#define INTEGRATE_NEE_BINDING_INDIRECT_RADIANCE_HIT_DISTANCE_INPUT 55 +#define INTEGRATE_NEE_BINDING_PRIMARY_POSITION_ERROR_INPUT 52 +#define INTEGRATE_NEE_BINDING_PRIMARY_HIT_DISTANCE_INPUT 53 +#define INTEGRATE_NEE_BINDING_PRIMARY_WORLD_INTERPOLATED_NORMAL_INPUT 54 +#define INTEGRATE_NEE_BINDING_INDIRECT_RADIANCE_HIT_DISTANCE_INPUT 55 -#define INTEGRATE_NEE_BINDING_NEE_CACHE 56 -#define INTEGRATE_NEE_BINDING_NEE_CACHE_TASK 57 -#define INTEGRATE_NEE_BINDING_NEE_CACHE_SAMPLE 58 -#define INTEGRATE_NEE_BINDING_NEE_CACHE_THREAD_TASK 59 -#define INTEGRATE_NEE_BINDING_PRIMITIVE_ID_PREFIX_SUM 60 +#define INTEGRATE_NEE_BINDING_NEE_CACHE 56 +#define INTEGRATE_NEE_BINDING_NEE_CACHE_TASK 57 +#define INTEGRATE_NEE_BINDING_NEE_CACHE_SAMPLE 58 +#define INTEGRATE_NEE_BINDING_NEE_CACHE_THREAD_TASK 59 +#define INTEGRATE_NEE_BINDING_PRIMITIVE_ID_PREFIX_SUM 60 -#define INTEGRATE_NEE_BINDING_RADIANCE_INPUT 61 -#define INTEGRATE_NEE_BINDING_HIT_GEOMETRY_INPUT 62 +#define INTEGRATE_NEE_BINDING_RADIANCE_INPUT 61 +#define INTEGRATE_NEE_BINDING_HIT_GEOMETRY_INPUT 62 // Inputs/Outputs diff --git a/src/dxvk/shaders/rtx/pass/nrd_args.h b/src/dxvk/shaders/rtx/pass/nrd_args.h index 6d0eae802..ee543e050 100644 --- a/src/dxvk/shaders/rtx/pass/nrd_args.h +++ b/src/dxvk/shaders/rtx/pass/nrd_args.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2021-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,8 +19,7 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ -#ifndef NRD_ARGS_H -#define NRD_ARGS_H +#pragma once #include "rtx/utility/shader_types.h" @@ -36,6 +35,3 @@ struct NrdArgs { vec3 specularLobeTrimmingParams; float pad3; }; - - -#endif diff --git a/src/dxvk/shaders/rtx/pass/raytrace_args.h b/src/dxvk/shaders/rtx/pass/raytrace_args.h index d4bfda01a..f0c575506 100644 --- a/src/dxvk/shaders/rtx/pass/raytrace_args.h +++ b/src/dxvk/shaders/rtx/pass/raytrace_args.h @@ -93,6 +93,7 @@ struct DomeLightArgs { vec3 radiance; uint active; + uint3 pad0; uint textureIndex; }; @@ -182,6 +183,15 @@ struct RaytraceArgs { TerrainArgs terrainArgs; NeeCacheArgs neeCacheArgs; + DomeLightArgs domeLightArgs; + + // Values to use on a ray miss + vec3 clearColorNormal; + float clearColorDepth; + uint32_t clearColorPicking; + uint enableDLSSRR; + + float2 upscaleFactor; // Displayed(upscaled) / RT resolution uint uniformRandomNumber; uint16_t opaqueDiffuseLobeSamplingProbabilityZeroThreshold; @@ -285,7 +295,7 @@ struct RaytraceArgs { float boilingFilterHigherThreshold; float boilingFilterRemoveReservoirThreshold; uint temporalHistoryLength; - uint32_t permutationSamplingSize; + uint permutationSamplingSize; uint enableReSTIRGITemporalBiasCorrection; uint enableReSTIRGIDiscardEnlargedPixels; float reSTIRGIHistoryDiscardStrength; @@ -330,15 +340,5 @@ struct RaytraceArgs { uint enableThinOpaque; float totalMipBias; - DomeLightArgs domeLightArgs; - - float2 upscaleFactor; // Displayed(upscaled) / RT resolution - - // Values to use on a ray miss - float clearColorDepth; - uint32_t clearColorPicking; - vec3 clearColorNormal; - uint enableDLSSRR; - uint forceFirstHitInGBufferPass; }; diff --git a/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_binding_indices.h b/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_binding_indices.h index fd9b99a51..38c49c154 100644 --- a/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_binding_indices.h +++ b/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_binding_indices.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,7 +36,7 @@ #define RTXDI_REUSE_BINDING_PREV_WORLD_POSITION_INPUT 27 #define RTXDI_REUSE_BINDING_VIEW_DIRECTION_INPUT 28 #define RTXDI_REUSE_BINDING_CONE_RADIUS_INPUT 29 -#define RTXDI_REUSE_BINDING_WS_MVEC_INPUT_OUTPUT 30 +#define RTXDI_REUSE_BINDING_WS_MVEC_INPUT 30 #define RTXDI_REUSE_BINDING_SS_MVEC_INPUT 31 #define RTXDI_REUSE_BINDING_POSITION_ERROR_INPUT 32 #define RTXDI_REUSE_BINDING_SHARED_FLAGS_INPUT 33 diff --git a/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_bindings.slangh b/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_bindings.slangh index 14d73efde..6396a5d3c 100644 --- a/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_bindings.slangh +++ b/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_reuse_bindings.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -60,7 +60,7 @@ RWTexture2D GBufferLast; layout(r32f, binding = RTXDI_REUSE_BINDING_REPROJECTION_CONFIDENCE_OUTPUT) RWTexture2D ReprojectionConfidence; -layout(rgba16f, binding = RTXDI_REUSE_BINDING_WS_MVEC_INPUT_OUTPUT) +layout(rgba16f, binding = RTXDI_REUSE_BINDING_WS_MVEC_INPUT) Texture2D PrimaryVirtualMotionVector; layout(rg16f, binding = RTXDI_REUSE_BINDING_SS_MVEC_INPUT) diff --git a/src/dxvk/shaders/rtx/utility/debug_view_helpers.slangh b/src/dxvk/shaders/rtx/utility/debug_view_helpers.slangh index 1528765ee..cae6fec60 100644 --- a/src/dxvk/shaders/rtx/utility/debug_view_helpers.slangh +++ b/src/dxvk/shaders/rtx/utility/debug_view_helpers.slangh @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,7 @@ #pragma once #include "rtx/utility/debug_view_indices.h" +#include "rtx/utility/color.slangh" vec4 readInDebugView(uvec2 pixelCoordinate) { @@ -73,52 +74,47 @@ void storeInDebugView(uvec2 pixelCoordinate, float16_t value) storeInDebugView(pixelCoordinate, float(value)); } +void storeInDebugView(uvec2 pixelCoordinate, uint value) +{ + storeInDebugView(pixelCoordinate, float(value)); +} + void accumulateInDebugViewAdd(u16vec2 pixelCoordinate, uint value) { vec4 prevValue = imageLoad(DebugView, pixelCoordinate); storeInDebugView(pixelCoordinate, prevValue + vec4(value)); } -void accumulateInDebugViewAnd(u16vec2 pixelCoordinate, uint value) +void accumulateInDebugViewAdd(u16vec2 pixelCoordinate, vec4 value) { vec4 prevValue = imageLoad(DebugView, pixelCoordinate); - storeInDebugView(pixelCoordinate, vec4(uint(prevValue.x) & value)); + storeInDebugView(pixelCoordinate, prevValue + value); } -void accumulateInDebugViewOr(u16vec2 pixelCoordinate, uint value) +void accumulateInDebugViewMax(u16vec2 pixelCoordinate, vec4 value) { vec4 prevValue = imageLoad(DebugView, pixelCoordinate); - storeInDebugView(pixelCoordinate, vec4(uint(prevValue.x) | value)); + storeInDebugView(pixelCoordinate, max(prevValue, value)); } -// Color codes a value into BGR, with only one channel being used to color code at a time -// Black: 0 value -// Red: values >= than max value -// Blue/Green (0,1]: the remaining values, with blue representing the lower half of valid range and green the rest -vec3 colorCodeIntoBGRexclusive(uint value, uint maxValue) +void accumulateInDebugViewMaxUsingLuminance(u16vec2 pixelCoordinate, vec4 value) { - if (value == 0) - return vec3(0); - else if (value >= maxValue) - return vec3(1, 0, 0); - - // Color code the rest, [1, maxValue-1], to a non-black BG color, one channel at a time - - value -= 1; - const uint numValues = maxValue - 1; - - const float numChannels = 2; - const uint ceilValuesPerChannel = ceil(numValues / numChannels); - - vec3 color = 0; - const uint channel = value / ceilValuesPerChannel; - const uint numValuesInCurrentChannel = min(numValues - channel * ceilValuesPerChannel, ceilValuesPerChannel); + vec4 prevValue = imageLoad(DebugView, pixelCoordinate); + const float prevLuminance = calcBt709Luminance(prevValue.rgb); + const float luminance = calcBt709Luminance(value.rgb); + storeInDebugView(pixelCoordinate, luminance > prevLuminance ? value : prevValue); +} - // Color code as (0,1] - color[channel] = (float(value % numValuesInCurrentChannel) + 1) / numValuesInCurrentChannel; +void accumulateInDebugViewAnd(u16vec2 pixelCoordinate, uint value) +{ + vec4 prevValue = imageLoad(DebugView, pixelCoordinate); + storeInDebugView(pixelCoordinate, vec4(uint(prevValue.x) & value)); +} - // Reswizzle to show lowest values in Blue and highest in Red - return color.bgr; +void accumulateInDebugViewOr(u16vec2 pixelCoordinate, uint value) +{ + vec4 prevValue = imageLoad(DebugView, pixelCoordinate); + storeInDebugView(pixelCoordinate, vec4(uint(prevValue.x) | value)); } // Analytically integrated checkerboard (box filter). diff --git a/src/dxvk/shaders/rtx/utility/debug_view_indices.h b/src/dxvk/shaders/rtx/utility/debug_view_indices.h index 0955ff339..73e398612 100644 --- a/src/dxvk/shaders/rtx/utility/debug_view_indices.h +++ b/src/dxvk/shaders/rtx/utility/debug_view_indices.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -146,13 +146,22 @@ #define DEBUG_VIEW_DENOISED_SECONDARY_COMBINED_DIFFUSE_RADIANCE 148 #define DEBUG_VIEW_DENOISED_SECONDARY_COMBINED_SPECULAR_RADIANCE 149 -#define DEBUG_VIEW_RTXDI_GRADIENTS 150 -#define DEBUG_VIEW_RTXDI_CONFIDENCE 151 -#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_COLOR 160 -#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_NORMAL 161 -#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_GEOMETRY_HASH 162 -#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_BACKGROUND_TRANSPARENCY 163 +#define DEBUG_VIEW_NOISY_PRIMARY_DIRECT_RADIANCE 155 +#define DEBUG_VIEW_NOISY_PRIMARY_INDIRECT_RADIANCE 156 +#define DEBUG_VIEW_NOISY_PRIMARY_RADIANCE 157 +#define DEBUG_VIEW_NOISY_SECONDARY_DIRECT_RADIANCE 158 +#define DEBUG_VIEW_NOISY_SECONDARY_INDIRECT_RADIANCE 159 +#define DEBUG_VIEW_NOISY_SECONDARY_RADIANCE 160 +#define DEBUG_VIEW_NOISY_RADIANCE 161 + +#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_COLOR 163 +#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_NORMAL 164 +#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_GEOMETRY_HASH 165 +#define DEBUG_VIEW_STOCHASTIC_ALPHA_BLEND_BACKGROUND_TRANSPARENCY 166 + +#define DEBUG_VIEW_RTXDI_GRADIENTS 167 +#define DEBUG_VIEW_RTXDI_CONFIDENCE 168 #define DEBUG_VIEW_NEE_CACHE_LIGHT_HISTOGRAM 170 #define DEBUG_VIEW_NEE_CACHE_HISTOGRAM 171 diff --git a/src/dxvk/shaders/rtx/utility/geometry_flags.slangh b/src/dxvk/shaders/rtx/utility/geometry_flags.slangh index 0b6203f04..672e94bde 100644 --- a/src/dxvk/shaders/rtx/utility/geometry_flags.slangh +++ b/src/dxvk/shaders/rtx/utility/geometry_flags.slangh @@ -61,12 +61,10 @@ uint geometryFlagsEncode(GeometryFlags geometryFlags) encodedFlags, geometryFlags.insideMedium ? (1 << 5) : 0); encodedFlags = packedFlagSet( encodedFlags, geometryFlags.firstSampledLobeIsSpecular ? (1 << 6) : 0); - // 7 bit unused encodedFlags = packedFlagSet( encodedFlags, geometryFlags.performPSTR ? (1 << 7) : 0); encodedFlags = packedFlagSet( encodedFlags, geometryFlags.performPSRR ? (1 << 8) : 0); - // 2 bits unused #if OBJECT_MASK_ALL_DYNAMIC_NUMBER_OF_ACTIVE_BITS > (16 - 12) diff --git a/src/dxvk/shaders/rtx/utility/gpu_printing.slangh b/src/dxvk/shaders/rtx/utility/gpu_printing.slangh index 78482c636..0ae9ca16d 100644 --- a/src/dxvk/shaders/rtx/utility/gpu_printing.slangh +++ b/src/dxvk/shaders/rtx/utility/gpu_printing.slangh @@ -27,7 +27,8 @@ namespace GpuPrint { void write(u16vec2 threadIndex, float4 data) { - if (any(threadIndex != cb.gpuPrintThreadIndex)) { + if (any(threadIndex != cb.gpuPrintThreadIndex)) + { return; }