diff --git a/code/Mesh/Instance/InstanceMesh.cpp b/code/Mesh/Instance/InstanceMesh.cpp
index 45b73a0b01..00242a4a01 100644
--- a/code/Mesh/Instance/InstanceMesh.cpp
+++ b/code/Mesh/Instance/InstanceMesh.cpp
@@ -28,6 +28,7 @@ namespace traktor::mesh
render::Handle s_handleInstanceWorld(L"InstanceWorld");
render::Handle s_handleInstanceWorldLast(L"InstanceWorldLast");
+render::Handle s_handleTargetSize(L"InstanceMesh_TargetSize");
render::Handle s_handleBoundingBoxMin(L"InstanceMesh_BoundingBoxMin");
render::Handle s_handleBoundingBoxMax(L"InstanceMesh_BoundingBoxMax");
render::Handle s_handleVisibility(L"InstanceMesh_Visibility");
@@ -132,6 +133,8 @@ void InstanceMesh::build(
for (int32_t i = (int32_t)cf.planes.size(); i < sizeof_array(cullFrustum); ++i)
cullFrustum[i] = Vector4::zero();
+ const Vector2 viewSize = worldRenderView.getViewSize();
+
auto renderBlock = renderContext->allocNamed< render::ComputeRenderBlock >(
str(L"InstanceMesh cull %d", worldRenderView.getCascade())
);
@@ -155,6 +158,7 @@ void InstanceMesh::build(
worldRenderPass.setProgramParameters(renderBlock->programParams);
+ renderBlock->programParams->setVectorParameter(s_handleTargetSize, Vector4(viewSize.x, viewSize.y, 0.0f, 0.0f));
renderBlock->programParams->setVectorParameter(s_handleBoundingBoxMin, m_renderMesh->getBoundingBox().mn);
renderBlock->programParams->setVectorParameter(s_handleBoundingBoxMax, m_renderMesh->getBoundingBox().mx);
renderBlock->programParams->setVectorArrayParameter(s_handleCullFrustum, cullFrustum, sizeof_array(cullFrustum));
diff --git a/code/Render/Frame/RenderPass.cpp b/code/Render/Frame/RenderPass.cpp
index 860df3d07c..80db168965 100644
--- a/code/Render/Frame/RenderPass.cpp
+++ b/code/Render/Frame/RenderPass.cpp
@@ -40,14 +40,10 @@ void RenderPass::addInput(handle_t resourceId)
input.resourceId = resourceId;
}
-bool RenderPass::requireInput(handle_t resourceId) const
+void RenderPass::addWeakInput(handle_t resourceId)
{
- for (const auto& input : m_inputs)
- {
- if (input.resourceId == resourceId)
- return true;
- }
- return false;
+ // #todo Currently we can get away with not doing anything but
+ // we need to revisit this to ensure resource life time.
}
void RenderPass::setOutput(handle_t resourceId)
diff --git a/code/Render/Frame/RenderPass.h b/code/Render/Frame/RenderPass.h
index bea9425532..0d66272ee3 100644
--- a/code/Render/Frame/RenderPass.h
+++ b/code/Render/Frame/RenderPass.h
@@ -72,9 +72,21 @@ class T_DLLCLASS RenderPass : public RefCountImpl< ITypedObject >
//! \{
+ /*! Add input to render pass.
+ *
+ * \param resourceId ID of input resource.
+ */
void addInput(handle_t resourceId);
- bool requireInput(handle_t resourceId) const;
+ /*! Add weak input to render pass.
+ *
+ * A weak input doesn't resolve into a dependency between
+ * passes but only register the pass as it will use the
+ * resource during build.
+ *
+ * \param resourceId ID of input resource.
+ */
+ void addWeakInput(handle_t resourceId);
const StaticVector< Input, 16 >& getInputs() const { return m_inputs; }
@@ -82,6 +94,14 @@ class T_DLLCLASS RenderPass : public RefCountImpl< ITypedObject >
//! \{
+ /*! Set output resource of render pass.
+ *
+ * Resource ID 0 means the primary framebuffer and
+ * an ID of ~0 means the render pass doesn't have an
+ * output resource associated.
+ *
+ * \param resourceId ID of output resource.
+ */
void setOutput(handle_t resourceId);
void setOutput(handle_t resourceId, uint32_t load, uint32_t store);
diff --git a/code/Render/IRenderView.h b/code/Render/IRenderView.h
index 82035d1e02..8d7bfede43 100644
--- a/code/Render/IRenderView.h
+++ b/code/Render/IRenderView.h
@@ -1,6 +1,6 @@
/*
* TRAKTOR
- * Copyright (c) 2022 Anders Pistol.
+ * Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
diff --git a/code/Render/Vulkan/RenderViewVk.cpp b/code/Render/Vulkan/RenderViewVk.cpp
index 6fb166d712..2835f60dce 100644
--- a/code/Render/Vulkan/RenderViewVk.cpp
+++ b/code/Render/Vulkan/RenderViewVk.cpp
@@ -1065,7 +1065,7 @@ void RenderViewVk::barrier(Stage from, Stage to, ITexture* written, uint32_t wri
0, nullptr
);
}
- else if (from == Stage::Compute && to == Stage::Compute && written == nullptr)
+ else if (from == Stage::Compute && to == Stage::Compute/* && written == nullptr*/)
{
VkMemoryBarrier mb = {};
mb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
@@ -1083,35 +1083,35 @@ void RenderViewVk::barrier(Stage from, Stage to, ITexture* written, uint32_t wri
0, nullptr
);
}
- else if (from == Stage::Compute && to == Stage::Compute && written != nullptr)
- {
- const Image* img = mandatory_non_null_type_cast< TextureVk* >(written)->getImage();
-
- VkImageMemoryBarrier imb = {};
- imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- imb.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
- imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- imb.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
- imb.newLayout = VK_IMAGE_LAYOUT_GENERAL;
- imb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- imb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- imb.image = img->getVkImage();
- imb.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- imb.subresourceRange.baseMipLevel = writtenMip;
- imb.subresourceRange.levelCount = 1;
- imb.subresourceRange.baseArrayLayer = 0;
- imb.subresourceRange.layerCount = 1;
-
- vkCmdPipelineBarrier(
- *frame.graphicsCommandBuffer,
- convertStage(from),
- convertStage(to),
- 0,
- 0, nullptr,
- 0, nullptr,
- 1, &imb
- );
- }
+ //else if (from == Stage::Compute && to == Stage::Compute && written != nullptr)
+ //{
+ // const Image* img = mandatory_non_null_type_cast< TextureVk* >(written)->getImage();
+
+ // VkImageMemoryBarrier imb = {};
+ // imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ // imb.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
+ // imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ // imb.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
+ // imb.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+ // imb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ // imb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ // imb.image = img->getVkImage();
+ // imb.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ // imb.subresourceRange.baseMipLevel = writtenMip;
+ // imb.subresourceRange.levelCount = 1;
+ // imb.subresourceRange.baseArrayLayer = 0;
+ // imb.subresourceRange.layerCount = 1;
+
+ // vkCmdPipelineBarrier(
+ // *frame.graphicsCommandBuffer,
+ // convertStage(from),
+ // convertStage(to),
+ // 0,
+ // 0, nullptr,
+ // 0, nullptr,
+ // 1, &imb
+ // );
+ //}
else
{
// No memory access; only add an execution barrier.
diff --git a/code/World/Deferred/WorldRendererDeferred.cpp b/code/World/Deferred/WorldRendererDeferred.cpp
index 677ad2910e..0cae457c4f 100644
--- a/code/World/Deferred/WorldRendererDeferred.cpp
+++ b/code/World/Deferred/WorldRendererDeferred.cpp
@@ -59,14 +59,6 @@ const render::Handle s_persistentVisualTargetSet[] =
render::Handle(L"World_VisualTargetSet_Odd")
};
-const render::Handle s_persistentHiZTexture[] =
-{
- render::Handle(L"World_HiZTexture_0"),
- render::Handle(L"World_HiZTexture_1"),
- render::Handle(L"World_HiZTexture_2"),
- render::Handle(L"World_HiZTexture_3")
-};
-
const resource::Id< render::Shader > c_lightShader(L"{707DE0B0-0E2B-A44A-9441-9B1FCFD428AA}");
}
@@ -148,19 +140,7 @@ void WorldRendererDeferred::setup(
};
// Add Hi-Z texture.
- const Vector2 viewSize = worldRenderView.getViewSize();
- const int32_t viewWidth = (int32_t)viewSize.x;
- const int32_t viewHeight = (int32_t)viewSize.y;
- const int32_t hiZWidth = viewWidth >> 1;
- const int32_t hiZHeight = viewHeight >> 1;
- const int32_t hiZMipCount = log2(std::max(hiZWidth, hiZHeight)) + 1;
-
- render::RenderGraphTextureDesc rgtxd;
- rgtxd.width = hiZWidth;
- rgtxd.height = hiZHeight;
- rgtxd.mipCount = hiZMipCount;
- rgtxd.format = render::TfR32F;
- const render::handle_t hizTextureId = renderGraph.addPersistentTexture(L"HiZ", s_persistentHiZTexture[worldRenderView.getIndex()], rgtxd);
+ const render::handle_t hizTextureId = m_hiZPass->addTexture(worldRenderView, renderGraph);
// Add passes to render graph.
m_lightClusterPass->setup(worldRenderView, m_gatheredView);
diff --git a/code/World/Shared/Passes/GBufferPass.cpp b/code/World/Shared/Passes/GBufferPass.cpp
index dc6d29b88e..b46921bbcd 100644
--- a/code/World/Shared/Passes/GBufferPass.cpp
+++ b/code/World/Shared/Passes/GBufferPass.cpp
@@ -61,9 +61,7 @@ render::handle_t GBufferPass::setup(
// Add GBuffer render pass.
Ref< render::RenderPass > rp = new render::RenderPass(L"GBuffer");
-
- // #fixme We cannot add this input since HiZ is created from depth of this pass.
- // rp->addInput(hiZTextureId);
+ rp->addWeakInput(hiZTextureId);
render::Clear clear;
clear.mask = render::CfColor | render::CfDepth | render::CfStencil;
diff --git a/code/World/Shared/Passes/HiZPass.cpp b/code/World/Shared/Passes/HiZPass.cpp
index 7cddc31794..9ce6b923d5 100644
--- a/code/World/Shared/Passes/HiZPass.cpp
+++ b/code/World/Shared/Passes/HiZPass.cpp
@@ -7,6 +7,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "Core/Log/Log.h"
+#include "Core/Math/Log2.h"
#include "Core/Misc/String.h"
#include "Core/Timer/Profiler.h"
#include "Render/Buffer.h"
@@ -32,6 +33,14 @@ const resource::Id< render::Shader > c_hiZBuildShader(L"{E8879B75-F646-5D46-8873
const render::Handle s_handleHiZInput(L"World_HiZInput");
const render::Handle s_handleHiZOutput(L"World_HiZOutput");
+const render::Handle s_persistentHiZTexture[] =
+{
+ render::Handle(L"World_HiZTexture_0"),
+ render::Handle(L"World_HiZTexture_1"),
+ render::Handle(L"World_HiZTexture_2"),
+ render::Handle(L"World_HiZTexture_3")
+};
+
}
T_IMPLEMENT_RTTI_CLASS(L"traktor.world.HiZPass", HiZPass, Object)
@@ -46,6 +55,23 @@ bool HiZPass::create(resource::IResourceManager* resourceManager)
return true;
}
+render::handle_t HiZPass::addTexture(const WorldRenderView& worldRenderView, render::RenderGraph& renderGraph) const
+{
+ const Vector2 viewSize = worldRenderView.getViewSize();
+ const int32_t viewWidth = (int32_t)viewSize.x;
+ const int32_t viewHeight = (int32_t)viewSize.y;
+ const int32_t hiZWidth = nearestLog2(viewWidth >> 1);
+ const int32_t hiZHeight = nearestLog2(viewHeight >> 1);
+ const int32_t hiZMipCount = log2(std::max(hiZWidth, hiZHeight)) + 1;
+
+ render::RenderGraphTextureDesc rgtxd;
+ rgtxd.width = hiZWidth;
+ rgtxd.height = hiZHeight;
+ rgtxd.mipCount = hiZMipCount;
+ rgtxd.format = render::TfR32F;
+ return renderGraph.addPersistentTexture(L"HiZ", s_persistentHiZTexture[worldRenderView.getIndex()], rgtxd);
+}
+
void HiZPass::setup(
const WorldRenderView& worldRenderView,
render::RenderGraph& renderGraph,
@@ -56,13 +82,10 @@ void HiZPass::setup(
T_PROFILER_SCOPE(L"HiZPass::setup");
const Vector2 viewSize = worldRenderView.getViewSize();
-
const int32_t viewWidth = (int32_t)viewSize.x;
const int32_t viewHeight = (int32_t)viewSize.y;
-
- const int32_t hiZWidth = viewWidth >> 1;
- const int32_t hiZHeight = viewHeight >> 1;
-
+ const int32_t hiZWidth = nearestLog2(viewWidth >> 1);
+ const int32_t hiZHeight = nearestLog2(viewHeight >> 1);
const int32_t hiZMipCount = log2(std::max(hiZWidth, hiZHeight)) + 1;
Ref< render::RenderPass > rp = new render::RenderPass(L"HiZ");
@@ -74,6 +97,12 @@ void HiZPass::setup(
const int32_t mipWidth = std::max(hiZWidth >> i, 1);
const int32_t mipHeight = std::max(hiZHeight >> i, 1);
+ const int32_t workWidth = std::max(viewWidth >> (i + 1), 1);
+ const int32_t workHeight = std::max(viewHeight >> (i + 1), 1);
+
+ T_FATAL_ASSERT(workWidth <= mipWidth);
+ T_FATAL_ASSERT(workHeight <= mipHeight);
+
rp->addBuild(
[=](const render::RenderGraph& renderGraph, render::RenderContext* renderContext)
{
@@ -87,6 +116,8 @@ void HiZPass::setup(
renderBlock->programParams->beginParameters(renderContext);
+ renderBlock->programParams->setVectorParameter(render::getParameterHandle(L"World_HiZWorkSize"), Vector4(workWidth, workHeight, 0.0f, 0.0f));
+
const auto outputTexture = renderGraph.getTexture(outputHiZTextureId);
renderBlock->programParams->setImageViewParameter(s_handleHiZOutput, outputTexture, i);
diff --git a/code/World/Shared/Passes/HiZPass.h b/code/World/Shared/Passes/HiZPass.h
index 774b80ead3..29cfb37572 100644
--- a/code/World/Shared/Passes/HiZPass.h
+++ b/code/World/Shared/Passes/HiZPass.h
@@ -42,6 +42,8 @@ class HiZPass : public Object
public:
bool create(resource::IResourceManager* resourceManager);
+ render::handle_t addTexture(const WorldRenderView& worldRenderView, render::RenderGraph& renderGraph) const;
+
void setup(
const WorldRenderView& worldRenderView,
render::RenderGraph& renderGraph,
@@ -50,7 +52,7 @@ class HiZPass : public Object
) const;
private:
-resource::Proxy< render::Shader > m_hiZBuildShader;
+ resource::Proxy< render::Shader > m_hiZBuildShader;
};
}
diff --git a/data/Source/System/Mesh/Shaders/Instance/Cull/Cull.xdi b/data/Source/System/Mesh/Shaders/Instance/Cull/Cull.xdi
index a03fc1b2e7..9f87b5e513 100644
--- a/data/Source/System/Mesh/Shaders/Instance/Cull/Cull.xdi
+++ b/data/Source/System/Mesh/Shaders/Instance/Cull/Cull.xdi
@@ -260,8 +260,8 @@ $Buffer[index].visible = $Input;
{6FAE432D-36E8-D046-96BA-65165BB9DCCC}
- 435
- 918
+ 422
+ 818
World_HiZTexture
Texture2D
@@ -313,6 +313,10 @@ $Buffer[index].visible = $Input;
{6D0649E3-ED26-0646-A195-028038D29BD8}
HiZState
+ -
+ {652EFABE-595D-9D4D-BC67-5C63D6168B21}
+ TargetSize
+
-
@@ -324,7 +328,7 @@ $Buffer[index].visible = $Input;
-
- {6E68FD9A-ACE2-9E4A-8B5B-AD54A457B107}
+ {CBB170DD-96E3-CF46-948E-47E5006E153F}
- -26
- 268
+ -21
+ 476
World_HiZInput
Image2D
Frame
-
- {FACE56FE-0DC8-4C47-A4B5-F75AF6D34A50}
+ {9E8F9562-547A-AA44-9F23-C243E184C92C}
- 154
- 174
+ -59
+ 556
World_HiZOutput
Image2D
Frame
- -
- {98BDEF21-F621-1345-8078-0D18AEA33005}
-
-
- -207
- 176
-
- Global
-
- -
- {75A93A5B-4AFA-E642-B5CB-4DBFDD319264}
-
-
- 40
- 202
-
- xy
-
- -
- {06182E78-38C4-A74B-8741-0205C03525AF}
+
-
+ {17342A62-7710-F841-9D31-0EA156A70A34}
- 231
- 263
+ -61
+ 616
- MaxZ
-
-
- 1
- 1
- 1
-
-
-
- {0E3643A0-A0DA-B649-9FD8-930F4EB6D42A}
-
-
- -
- {3C138D5C-5426-334C-99BF-A06F6FA6635B}
- Input
-
- -
- {109C1796-0BBF-CB47-B322-44901970D7F8}
- Index
-
-
-
- -
- {7E64C882-DF9D-C442-9D35-66B1FA5C2F61}
- Output
- Scalar
-
-
-
+ World_HiZWorkSize
+ Vector
+ Frame
-
- {60D25829-A948-4883-B26F-F2BE12B49891}
-
-
- -
-
-
-
- {F2E22CA6-DFF3-4B20-A70A-0D7A44EACD8C}
+ {D69B3EDE-00AB-2540-B217-394E11A1B0E1}
-
- {0907D535-A1B6-409A-A70A-C250D3CDCD58}
+ {2D2D3531-DD81-1F47-90F9-DDE0C69AEF69}
-
-
-
- {109C1796-0BBF-CB47-B322-44901970D7F8}
-
-
- -
-
-
-
- {3C138D5C-5426-334C-99BF-A06F6FA6635B}
-
-
- -
-
- {4356E929-19D3-45DD-8143-0168015DB701}
+ {98C61F79-5BF1-9D49-92B7-77AEEA0EDFAF}
diff --git a/data/Source/System/World/Overlay/Shaders/OverlayTargets.xdi b/data/Source/System/World/Overlay/Shaders/OverlayTargets.xdi
index 7666eb61d6..8f3b299ef2 100644
--- a/data/Source/System/World/Overlay/Shaders/OverlayTargets.xdi
+++ b/data/Source/System/World/Overlay/Shaders/OverlayTargets.xdi
@@ -2225,8 +2225,8 @@ else
{B215A6DE-86D1-2F4B-A606-D8EC68126A45}
- -843
- 3988
+ -881
+ 4009
Scene_DebugTexture
Texture2D
@@ -2282,10 +2282,10 @@ else
{D8AA7F23-349A-6142-9709-083B7811B53A}
- -746
- 4151
+ -820
+ 4072
- 4
+ 2
-
{431F1C47-067D-5042-B5DC-20EBDF01A8C7}
@@ -2315,6 +2315,10 @@ else
{A5895F7C-509E-0A40-870E-3E262BE78130}
TexCoord
+ -
+ {AFB734B7-EA74-6C4F-B0A9-16FE838CF389}
+ TargetSize
+
-
@@ -2325,15 +2329,23 @@ else
+ -
+ {A5B004FC-A637-A949-9958-F404AB11CDFC}
+
+
+ -882
+ 3942
+
+
-
@@ -3456,6 +3468,16 @@ $Output = vec4(p, 0.0f, 0.0f);
{6D5C5EFE-A35C-4748-B81E-B8EBACE433BC}
+ -
+
+
+
+ {AFB734B7-EA74-6C4F-B0A9-16FE838CF389}
+
+
-