VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
renderPassDownsample.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4//
6
9
10namespace visutwin::canvas
11{
12 namespace
13 {
14 constexpr const char* DOWNSAMPLE_SOURCE = R"(
15#include <metal_stdlib>
16using namespace metal;
17
18struct QuadVertexIn {
19 float3 position [[attribute(0)]];
20 float3 normal [[attribute(1)]];
21 float2 uv0 [[attribute(2)]];
22 float4 tangent [[attribute(3)]];
23 float2 uv1 [[attribute(4)]];
24};
25
26struct QuadVarying {
27 float4 position [[position]];
28 float2 uv;
29};
30
31vertex QuadVarying downsampleVertex(QuadVertexIn in [[stage_in]])
32{
33 QuadVarying out;
34 out.position = float4(in.position, 1.0);
35 out.uv = in.uv0;
36 return out;
37}
38
39fragment float4 downsampleFragment(
40 QuadVarying in [[stage_in]],
41 texture2d<float> sourceTexture [[texture(0)]],
42 sampler linearSampler [[sampler(0)]])
43{
44 return sourceTexture.sample(linearSampler, clamp(in.uv, float2(0.0), float2(1.0)));
45}
46)";
47 }
48
49 RenderPassDownsample::RenderPassDownsample(const std::shared_ptr<GraphicsDevice>& device, Texture* sourceTexture)
50 : RenderPassDownsample(device, sourceTexture, Options{})
51 {
52 }
53
54 RenderPassDownsample::RenderPassDownsample(const std::shared_ptr<GraphicsDevice>& device, Texture* sourceTexture,
55 const Options& options)
56 : RenderPassShaderQuad(device), _sourceTexture(sourceTexture), _premultiplyTexture(options.premultiplyTexture), _options(options)
57 {
58 // Cache the downsample shader at the device level so that bloom passes
59 // (which create many RenderPassDownsample instances) don't each compile
60 // a separate MTL::Library with the same source. This avoids hitting
61 // the AGX compiled-variants footprint limit.
62 static constexpr const char* CACHE_KEY = "DownsampleQuad";
63 auto cached = device->getCachedShader(CACHE_KEY);
64 if (!cached) {
65 ShaderDefinition shaderDefinition;
66 shaderDefinition.name = CACHE_KEY;
67 shaderDefinition.vshader = "downsampleVertex";
68 shaderDefinition.fshader = "downsampleFragment";
69 cached = createShader(device.get(), shaderDefinition, DOWNSAMPLE_SOURCE);
70 device->setCachedShader(CACHE_KEY, cached);
71 }
72 setShader(cached);
73 }
74
76 {
77 _sourceTexture = value;
78 }
79
81 {
82 setQuadTextureBinding(0, _sourceTexture);
83 setQuadTextureBinding(1, _premultiplyTexture);
84 if (_sourceTexture) {
85 _sourceInvResolution[0] = _sourceTexture->width() > 0 ? 1.0f / static_cast<float>(_sourceTexture->width()) : 1.0f;
86 _sourceInvResolution[1] = _sourceTexture->height() > 0 ? 1.0f / static_cast<float>(_sourceTexture->height()) : 1.0f;
87 } else {
88 _sourceInvResolution[0] = 1.0f;
89 _sourceInvResolution[1] = 1.0f;
90 }
91
93 }
94}
RenderPassDownsample(const std::shared_ptr< GraphicsDevice > &device, Texture *sourceTexture)
std::shared_ptr< GraphicsDevice > device() const
Definition renderPass.h:124
void setShader(const std::shared_ptr< Shader > &shader)
void setQuadTextureBinding(const size_t slot, Texture *texture)
RenderPassShaderQuad(const std::shared_ptr< GraphicsDevice > &device)
GPU texture resource supporting 2D, cubemap, volume, and array formats with mipmap management.
Definition texture.h:57
std::shared_ptr< Shader > createShader(GraphicsDevice *graphicsDevice, const ShaderDefinition &definition, const std::string &sourceCode)
Definition shader.cpp:39