Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
ShaderNodeRhi.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 fuddlesworth
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#pragma once
5
7#include <PhosphorRendering/phosphorrendering_export.h>
8
13
14#include <QColor>
15#include <QImage>
16#include <QMatrix4x4>
17#include <QPointF>
18#include <QPointer>
19#include <QSizeF>
20#include <QQuickItem>
21#include <QSGRenderNode>
22#include <QSGTextureProvider>
23#include <QString>
24#include <QStringList>
25#include <QVector>
26#include <QVector4D>
27
28#include <array>
29#include <atomic>
30#include <map>
31#include <memory>
32#include <mutex>
33#include <optional>
34
35#include <rhi/qrhi.h>
36
37namespace PhosphorRendering {
38
39// Forward declare constants used in member declarations.
40// `constexpr int` at namespace scope in a header is implicitly `inline` since
41// C++17 — no `static` needed (and matches the existing `constexpr int` style
42// used by kFirstFreeConsumerBinding / kMaxConsumerBinding below).
43constexpr int kMaxBufferPasses = 4;
44constexpr int kMaxUserTextures = 4;
45constexpr int kMaxCustomParams = 8;
46constexpr int kMaxCustomColors = 16;
47
48// ── Consumer binding range (for setExtraBinding) ────────────────────────
49// Library-managed bindings: 0 (UBO), 2-5 (multipass buffers), 6 (audio),
50// 7-10 (user textures), 11 (wallpaper), 12 (depth). Assigning any of those
51// via setExtraBinding() would duplicate SRB entries and is rejected at
52// runtime. Binding 1 is the one "free-in-the-gap" slot; 13..31 are free as
53// well.
54//
55// Phosphor uses binding 1 for its zone-labels texture by convention.
56// Other consumers that interoperate with Phosphor should pick from
57// 13..kMaxConsumerBinding to avoid a per-instance overwrite.
58constexpr int kFirstFreeConsumerBinding = 1;
63constexpr int kMaxConsumerBinding = 31;
64constexpr int kReservedBindingRangeStart = 2;
65constexpr int kReservedBindingRangeEnd = 12;
66
70constexpr int kUserTextureBaseBinding = 7;
71
73constexpr bool isConsumerBinding(int binding) noexcept
74{
75 return binding >= kFirstFreeConsumerBinding && binding <= kMaxConsumerBinding
76 && (binding < kReservedBindingRangeStart || binding > kReservedBindingRangeEnd);
77}
78
125class PHOSPHORRENDERING_EXPORT ShaderNodeRhi : public QSGRenderNode
126{
127public:
138 explicit ShaderNodeRhi(QQuickItem* item, std::unique_ptr<PhosphorShaders::IUboProfile> profile = nullptr);
139 ~ShaderNodeRhi() override;
140
149
160 bool hasValidItem() const
161 {
162 return m_itemValid.load(std::memory_order_acquire);
163 }
164
172 const std::shared_ptr<ShaderNodeLiveness>& liveness() const
173 {
174 return m_liveness;
175 }
176
177 // QSGRenderNode
178 QSGRenderNode::StateFlags changedStates() const override;
179 QSGRenderNode::RenderingFlags flags() const override;
180 QRectF rect() const override;
181 void prepare() override;
182 void render(const RenderState* state) override;
183 void releaseResources() override;
192 void preprocess() override;
193
194 // ── Uniform Extension ──────────────────────────────────────────────
195 void setUniformExtension(std::shared_ptr<PhosphorShaders::IUniformExtension> extension);
197 std::shared_ptr<PhosphorShaders::IUniformExtension> uniformExtension() const
198 {
199 return m_uniformExtension;
200 }
201
202 // ── Timing ─────────────────────────────────────────────────────────
203 void setTime(double time);
204 void setTimeDelta(float delta);
205 void setFrame(int frame);
206 void setResolution(float width, float height);
207 void setMousePosition(const QPointF& pos);
213 void setIsReversed(bool reverse);
214
215 // ── Custom Parameters (indexed API) ────────────────────────────────
216 void setCustomParams(int index, const QVector4D& params);
217 void setCustomColor(int index, const QColor& color);
218
219 // ── Surface-only state ─────────────────────────────────────────────
231 void setSurfaceOpacity(float opacity);
232 void setSurfaceScale(float scale);
233 void setSurfaceFocused(bool focused);
234 void setSurfaceSize(float width, float height);
242 void setBackdropRect(float x, float y, float w, float h);
243 void setSurfaceFrameTopLeft(float x, float y);
244 void setSurfaceFrameSize(float width, float height);
245
246 // ── App Fields (consumer escape hatch in BaseUniforms) ─────────────
254 void setAppField0(int value);
255 void setAppField1(int value);
256
257 // ── Extra Bindings (consumer-managed texture bindings) ─────────────
272 bool setExtraBinding(int binding, QRhiTexture* texture, QRhiSampler* sampler);
274 bool removeExtraBinding(int binding);
275
276 // ── Textures ───────────────────────────────────────────────────────
277 void setAudioSpectrum(const QVector<float>& spectrum);
278 void setUserTexture(int slot, const QImage& image);
282 void setUserTextureWrap(int slot, const QString& wrap);
283 void setWallpaperTexture(const QImage& image);
284 void setUseWallpaper(bool use);
285 void setUseDepthBuffer(bool use);
286
301 void setSourceTextureProvider(QSGTextureProvider* provider);
302 QSGTextureProvider* sourceTextureProvider() const
303 {
304 return m_sourceTextureProvider.data();
305 }
306
307 // ── Multi-pass Buffers ─────────────────────────────────────────────
308 void setBufferShaderPath(const QString& path);
309 void setBufferShaderPaths(const QStringList& paths);
310 void setBufferFeedback(bool enable);
311 void setBufferScale(qreal scale);
315 void setHalfFloatBuffers(bool enable);
316 void setBufferWrap(const QString& wrap);
317 void setBufferWraps(const QStringList& wraps);
318 void setBufferFilter(const QString& filter);
319 void setBufferFilters(const QStringList& filters);
320
321 // ── Shader Loading ─────────────────────────────────────────────────
322 bool loadVertexShader(const QString& path);
323 bool loadFragmentShader(const QString& path);
324 void setVertexShaderSource(const QString& source);
325 void setFragmentShaderSource(const QString& source);
326 bool isShaderReady() const;
327 QString shaderError() const;
330
331 // ── Include Paths ──────────────────────────────────────────────────
332 void setShaderIncludePaths(const QStringList& paths);
333
334 // ── Parameter preamble (T1.1: generated `#define p_<id> ...`) ─────
344 void setParamPreamble(const QString& preamble);
345
346 // ── Entry-point scaffold (T1.4: harness-generated `main()`) ────────
357 void setEntryScaffold(const QString& prologue, const QList<PhosphorShaders::EntryCandidate>& candidates);
358
364 static QString normalizeWrapMode(const QString& wrap);
366 static QString normalizeFilterMode(const QString& filter);
367
371 static QRhiSampler::AddressMode wrapModeToRhiAddress(const QString& wrap);
372
373protected:
381 QRhi* safeRhi() const;
382
398 void retractLiveness() noexcept;
399
400private:
401 bool ensurePipeline();
402 bool ensureBufferPipeline();
403 bool ensureBufferTarget();
404 bool ensureDummyChannelResources(QRhi* rhi);
405 bool ensureBufferSampler(QRhi* rhi, int index);
409 void resetBufferTargets();
413 void syncBaseUniforms(QRhi* rhi);
419 bool renderingIntoTexture() const;
420 void uploadDirtyTextures(QRhi* rhi, QRhiCommandBuffer* cb);
426 void uploadExtensionToUbo(QRhiResourceUpdateBatch* batch);
427 void releaseRhiResources();
428 void appendUserTextureBindings(QVector<QRhiShaderResourceBinding>& bindings) const;
442 bool wallpaperBindingLive() const
443 {
444 return m_useWallpaper && m_wallpaperTexture && m_wallpaperSampler && !m_wallpaperImage.isNull();
445 }
446 void appendWallpaperBinding(QVector<QRhiShaderResourceBinding>& bindings) const;
461 enum class DepthAccess {
462 Sampled,
463 WrittenThisPass
464 };
465 void appendDepthBinding(QVector<QRhiShaderResourceBinding>& bindings, DepthAccess access) const;
466 void appendExtraBindings(QVector<QRhiShaderResourceBinding>& bindings) const;
467 void appendAudioBinding(QVector<QRhiShaderResourceBinding>& bindings) const;
469 void appendUboAndExtraBindings(QVector<QRhiShaderResourceBinding>& bindings) const;
473 void appendCommonTrailerBindings(QVector<QRhiShaderResourceBinding>& bindings, DepthAccess depthAccess) const;
474 void resetAllBindingsAndPipelines();
475 void bakeBufferShaders();
476 QString loadAndExpandShader(const QString& path, QString* outError);
482 QString loadAndExpandShaderTracked(const QString& path, QStringList* outIncludedPaths, QString* outError);
483
484 QQuickItem* m_item = nullptr;
485 std::atomic<bool> m_itemValid{true};
486
496 // Lock-ordering invariant: MUST NOT block on the GUI thread while holding
497 // m_itemMutex (avoids deadlock during ~ShaderEffect → invalidateItem path).
498 mutable std::mutex m_itemMutex;
499
504 std::shared_ptr<ShaderNodeLiveness> m_liveness = std::make_shared<ShaderNodeLiveness>();
505
506 // ── Uniform Extension ──────────────────────────────────────────────
507 std::shared_ptr<PhosphorShaders::IUniformExtension> m_uniformExtension;
511 QByteArray m_extensionStaging;
512
513 // ── Shader Include Paths ───────────────────────────────────────────
514 QStringList m_shaderIncludePaths;
515
516 // ── Parameter preamble (generated `#define p_<id> ...`) ───────────
519 QString m_paramPreamble;
520
521 // ── Entry-point scaffold (T1.4) ────────────────────────────────────
525 QString m_entryPrologue;
526 QList<PhosphorShaders::EntryCandidate> m_entryCandidates;
527
528 // ── RHI Core Resources ─────────────────────────────────────────────
529 std::unique_ptr<QRhiBuffer> m_vbo;
530 std::unique_ptr<QRhiBuffer> m_ubo;
531 std::unique_ptr<QRhiShaderResourceBindings> m_srb;
532 std::unique_ptr<QRhiGraphicsPipeline> m_pipeline;
533 QShader m_vertexShader;
534 QShader m_fragmentShader;
535 QVector<quint32> m_renderPassFormat;
536
537 // ── Multi-pass: buffer pass(es) (optional). Up to 4 paths. ────────
538 QString m_bufferPath;
539 QStringList m_bufferPaths;
540 bool m_bufferFeedback = false;
541 qreal m_bufferScale = 1.0;
542 // Buffer-pass texel format. Half-float by default so packs that store HDR
543 // radiance, signed data, or feedback accumulators keep full precision; a
544 // pack whose buffers hold plain clamped [0,1] colour opts down to RGBA8
545 // via metadata to halve buffer bandwidth (which is what integrated GPUs
546 // are starved of).
547 bool m_halfFloatBuffers = true;
548 std::array<QString, kMaxBufferPasses> m_bufferWraps = {QStringLiteral("clamp"), QStringLiteral("clamp"),
549 QStringLiteral("clamp"), QStringLiteral("clamp")};
550 QString m_bufferWrapDefault = QStringLiteral("clamp");
551 std::array<QString, kMaxBufferPasses> m_bufferFilters = {QStringLiteral("linear"), QStringLiteral("linear"),
552 QStringLiteral("linear"), QStringLiteral("linear")};
553 QString m_bufferFilterDefault = QStringLiteral("linear");
554 QString m_bufferFragmentShaderSource;
555 QShader m_bufferFragmentShader;
556 bool m_bufferShaderReady = false;
557 bool m_bufferShaderDirty = true;
558 int m_bufferShaderRetries = 0;
559 std::unique_ptr<QRhiTexture> m_bufferTexture;
560 std::unique_ptr<QRhiRenderPassDescriptor> m_bufferRenderPassDescriptor;
561 std::unique_ptr<QRhiTextureRenderTarget> m_bufferRenderTarget;
562 std::array<std::unique_ptr<QRhiSampler>, kMaxBufferPasses> m_bufferSamplers;
563 std::unique_ptr<QRhiShaderResourceBindings> m_bufferSrb;
564 std::unique_ptr<QRhiGraphicsPipeline> m_bufferPipeline;
565 QVector<quint32> m_bufferRenderPassFormat;
566 // Ping-pong (bufferFeedback): second texture/RT/SRB for buffer pass; image pass has two SRBs
567 std::unique_ptr<QRhiTexture> m_bufferTextureB;
568 std::unique_ptr<QRhiRenderPassDescriptor> m_bufferRenderPassDescriptorB;
569 std::unique_ptr<QRhiTextureRenderTarget> m_bufferRenderTargetB;
570 std::unique_ptr<QRhiShaderResourceBindings> m_bufferSrbB;
571 std::unique_ptr<QRhiShaderResourceBindings> m_srbB; // image pass SRB with binding 2 = texture B
572 bool m_bufferFeedbackCleared = false;
573
574 // Multi-buffer mode (2-4 passes): per-pass resources
575 std::array<std::unique_ptr<QRhiTexture>, kMaxBufferPasses> m_multiBufferTextures = {};
576 std::array<std::unique_ptr<QRhiTextureRenderTarget>, kMaxBufferPasses> m_multiBufferRenderTargets = {};
577 std::array<std::unique_ptr<QRhiRenderPassDescriptor>, kMaxBufferPasses> m_multiBufferRenderPassDescriptors = {};
578 std::array<std::unique_ptr<QRhiGraphicsPipeline>, kMaxBufferPasses> m_multiBufferPipelines = {};
579 std::array<std::unique_ptr<QRhiShaderResourceBindings>, kMaxBufferPasses> m_multiBufferSrbs = {};
580 std::array<QShader, kMaxBufferPasses> m_multiBufferFragmentShaders = {};
581 std::array<QString, kMaxBufferPasses> m_multiBufferFragmentShaderSources = {};
582 bool m_multiBufferShadersReady = false;
583 bool m_multiBufferShaderDirty = true;
584 int m_multiBufferShaderRetries = 0;
585 // Dummy 1x1 texture for the multipass channel-0 buffer slot (SRB
586 // binding 2, GLSL `iChannel0`) when multipass is configured but the
587 // backing buffer hasn't been created yet. Distinct from the user-
588 // texture slot 0 (SRB binding 7, GLSL `uTexture0`) — the iChannel0
589 // name here refers to the buffer-channel binding, not the renamed
590 // user-texture.
591 std::unique_ptr<QRhiTexture> m_dummyChannelTexture;
592 std::unique_ptr<QRhiSampler> m_dummyChannelSampler;
593 bool m_dummyChannelTextureNeedsUpload = false;
594
595 // ── Shader Sources ─────────────────────────────────────────────────
596 QString m_vertexShaderSource;
597 QString m_fragmentShaderSource;
598 QString m_vertexPath;
599 QString m_fragmentPath;
600 qint64 m_vertexMtime = 0;
601 qint64 m_fragmentMtime = 0;
610 QStringList m_vertexIncludedPaths;
611 QStringList m_fragmentIncludedPaths;
612 QString m_shaderError;
613 bool m_initialized = false;
614 bool m_vboUploaded = false;
615 bool m_shaderReady = false;
616 bool m_shaderDirty = true;
617 bool m_uniformsDirty = true;
618 bool m_timeDirty = true;
619 bool m_timeHiDirty = true;
620 bool m_sceneDataDirty = true;
621 bool m_appFieldsDirty = false;
622 bool m_didFullUploadOnce = false;
628 std::optional<bool> m_lastTargetWasTexture;
629
630 // ── UBO Profile (pluggable uniform buffer concern) ─────────────────
635 std::unique_ptr<PhosphorShaders::IUboProfile> m_uboProfile;
636
641 int m_appField0 = 0;
642 int m_appField1 = 0;
643
644 // Full-precision elapsed seconds (double). Split into iTime (wrapped lo) +
645 // iTimeHi (wrap offset) at upload.
646 double m_time = 0.0;
647 float m_timeDelta = 0.0f;
648 int m_frame = 0;
649 bool m_isReversed = false;
650 float m_timeHi = 0.0f; // Cached iTimeHi for wrap-offset change detection
651 float m_width = 0.0f;
652 float m_height = 0.0f;
659 std::atomic<float> m_cachedWidth{0.0f};
660 std::atomic<float> m_cachedHeight{0.0f};
661 QPointF m_mousePosition;
662
663 // ── Surface-only state (consumed by a SurfaceUniformProfile; ignored by
664 // the BaseUniformProfile). Defaults mirror UboFrameState so the overlay
665 // path is byte-identical whether or not these are ever touched. ──
666 float m_surfaceOpacity = 1.0f;
667 float m_surfaceScale = 1.0f;
668 bool m_surfaceFocused = false;
669 float m_surfaceSize[2] = {0.0f, 0.0f};
670 float m_backdropRect[4] = {0.0f, 0.0f, 1.0f, 1.0f};
671 float m_surfaceFrameTopLeft[2] = {0.0f, 0.0f};
672 float m_surfaceFrameSize[2] = {0.0f, 0.0f};
673
674 // ── Custom Parameters (indexed) ────────────────────────────────────
675 std::array<QVector4D, kMaxCustomParams> m_customParams;
676 std::array<QColor, kMaxCustomColors> m_customColors;
677
678 // ── Extra Bindings (consumer-managed) ──────────────────────────────
679 struct ExtraBinding
680 {
681 QRhiTexture* texture = nullptr;
682 QRhiSampler* sampler = nullptr;
683 };
684 // std::map (ordered) so SRB construction produces a deterministic binding
685 // order regardless of insertion/erasure history. An unordered_map can
686 // produce different iteration orders after erasures, which Qt RHI
687 // backends may hash into different pipeline layout signatures.
688 std::map<int, ExtraBinding> m_extraBindings;
689 bool m_extraBindingsDirty = false;
690
691 // ── 1x1 Transparent Fallback ───────────────────────────────────────
692 QImage m_transparentFallbackImage;
693
694 // ── Audio spectrum texture (binding 6) ─────────────────────────────
695 QVector<float> m_audioSpectrum;
696 std::unique_ptr<QRhiTexture> m_audioSpectrumTexture;
697 std::unique_ptr<QRhiSampler> m_audioSpectrumSampler;
698 bool m_audioSpectrumDirty = false;
699
700 // ── User texture slots (bindings 7-10) ─────────────────────────────
701 std::array<QImage, kMaxUserTextures> m_userTextureImages;
702 std::array<std::unique_ptr<QRhiTexture>, kMaxUserTextures> m_userTextures;
703 std::array<std::unique_ptr<QRhiSampler>, kMaxUserTextures> m_userTextureSamplers;
704 // Spelled out rather than default-constructed, matching m_bufferWraps
705 // above. The only reader normalises an unknown token to ClampToEdge, so a
706 // null QString behaves identically today, but leaving the two arrays with
707 // different defaults means a future reader that string-compares gets a
708 // different answer for a user texture than for a buffer.
709 std::array<QString, kMaxUserTextures> m_userTextureWraps = {QStringLiteral("clamp"), QStringLiteral("clamp"),
710 QStringLiteral("clamp"), QStringLiteral("clamp")};
711 std::array<bool, kMaxUserTextures> m_userTextureDirty = {};
712
713 // ── Source texture override (slot 0 / binding 7) ───────────────────
714 // Texture-provider source — typically a `QQuickItem::textureProvider()`
715 // for a layer-enabled item. When non-null this supersedes
716 // m_userTextures[0] in the SRB build, so the shader's uTexture0
717 // samples a live QML render instead of a static QImage upload.
718 // m_sourceSampler is owned here (not a user-texture sampler) so we
719 // can keep slot 0's user-texture sampler available for callers that
720 // mix the two paths. m_lastSourceRhiTexture caches the QRhiTexture*
721 // we last bound; when the provider's underlying texture changes
722 // (FBO recreation on resize / device-loss) we drop the SRB so the
723 // next rebuild picks up the new pointer.
724 QPointer<QSGTextureProvider> m_sourceTextureProvider;
733 QMetaObject::Connection m_sourceTextureChangedConn;
734 std::unique_ptr<QRhiSampler> m_sourceSampler;
735 QRhiTexture* m_lastSourceRhiTexture = nullptr;
740 bool m_sourceSamplerFailed = false;
744 bool m_warnedForeignRhi = false;
749 mutable bool m_warnedWallpaperBindingOmitted = false;
754 bool m_warnedAudioTruncated = false;
755 bool m_warnedAudioCreateFailed = false;
763 std::unique_ptr<QRhiTexture> m_transparentFallbackTexture;
764 bool m_transparentFallbackTextureNeedsUpload = false;
765
766 // ── Depth buffer (binding 12) ──────────────────────────────────────
767 bool m_useDepthBuffer = false;
768 bool m_depthMultiBufferWarned = false;
769 std::unique_ptr<QRhiTexture> m_depthTexture;
770 std::unique_ptr<QRhiSampler> m_depthSampler;
771
772 // ── Desktop wallpaper texture (binding 11) ─────────────────────────
773 bool m_useWallpaper = false;
774 QImage m_wallpaperImage;
775 std::unique_ptr<QRhiTexture> m_wallpaperTexture;
776 std::unique_ptr<QRhiSampler> m_wallpaperSampler;
777 bool m_wallpaperDirty = false;
778};
779
782{
783 bool success = false;
785};
786
810 const QString& vertexPath, const QString& fragmentPath, const QStringList& includePaths = {},
811 const QString& paramPreamble = {}, const QString& entryPrologue = {},
812 const QList<PhosphorShaders::EntryCandidate>& entryCandidates = {});
813
814} // namespace PhosphorRendering
QSGRenderNode for fullscreen-quad shader rendering via Qt RHI (Vulkan / OpenGL)
Definition ShaderNodeRhi.h:126
bool removeExtraBinding(int binding)
void setBufferScale(qreal scale)
void setUniformExtension(std::shared_ptr< PhosphorShaders::IUniformExtension > extension)
void setIsReversed(bool reverse)
Direction signal for asymmetric leg rendering.
void setVertexShaderSource(const QString &source)
void setShaderIncludePaths(const QStringList &paths)
QRectF rect() const override
QSGRenderNode::RenderingFlags flags() const override
void setBufferWrap(const QString &wrap)
void setCustomParams(int index, const QVector4D &params)
void setSurfaceOpacity(float opacity)
Per-surface inputs consumed by a SurfaceUniformProfile.
void setUserTexture(int slot, const QImage &image)
void invalidateItem()
Notify the render node that its owning item is being destroyed.
void setBufferFilter(const QString &filter)
void setAppField0(int value)
Write the consumer's two int slots inside BaseUniforms (offsets 88, 92).
void setBufferShaderPaths(const QStringList &paths)
void setAudioSpectrum(const QVector< float > &spectrum)
void setSurfaceSize(float width, float height)
void setBufferWraps(const QStringList &wraps)
void setHalfFloatBuffers(bool enable)
Buffer-pass texel format: RGBA16F when true (the default — safe for HDR, signed-data,...
bool loadFragmentShader(const QString &path)
void setUserTextureWrap(int slot, const QString &wrap)
Set per-slot sampler address mode.
void setWallpaperTexture(const QImage &image)
bool hasValidItem() const
Whether this node still holds a usable back-pointer to its item.
Definition ShaderNodeRhi.h:160
QRhi * safeRhi() const
Thread-safe QRhi accessor.
void setMousePosition(const QPointF &pos)
void setResolution(float width, float height)
void retractLiveness() noexcept
Retract this node from its liveness block.
std::shared_ptr< PhosphorShaders::IUniformExtension > uniformExtension() const
Access the currently-installed uniform extension (may be nullptr).
Definition ShaderNodeRhi.h:197
void setFragmentShaderSource(const QString &source)
void setSourceTextureProvider(QSGTextureProvider *provider)
Live texture-provider override for user-texture slot 0 (SRB binding 7 / uTexture0).
void preprocess() override
Stock-parity dependency pull (mirrors QSGRhiShaderEffectNode): bring the source provider's layer text...
const std::shared_ptr< ShaderNodeLiveness > & liveness() const
The liveness block to hand to ShaderEffect::registerRenderNode.
Definition ShaderNodeRhi.h:172
void setBufferShaderPath(const QString &path)
QSGTextureProvider * sourceTextureProvider() const
Definition ShaderNodeRhi.h:302
void setSurfaceFocused(bool focused)
ShaderNodeRhi(QQuickItem *item, std::unique_ptr< PhosphorShaders::IUboProfile > profile=nullptr)
void setSurfaceFrameSize(float width, float height)
void setSurfaceFrameTopLeft(float x, float y)
void render(const RenderState *state) override
static QString normalizeFilterMode(const QString &filter)
Normalize filter mode string to "nearest", "linear", or "mipmap".
void setEntryScaffold(const QString &prologue, const QList< PhosphorShaders::EntryCandidate > &candidates)
Install the entry-point scaffold for the fragment stage.
void setCustomColor(int index, const QColor &color)
void setSurfaceScale(float scale)
QSGRenderNode::StateFlags changedStates() const override
static QString normalizeWrapMode(const QString &wrap)
Normalize wrap mode string to "clamp", "repeat", or "mirror" (static helper, safe to call from any th...
bool loadVertexShader(const QString &path)
void setParamPreamble(const QString &preamble)
Set the generated named-parameter preamble that is spliced after the fragment shader's #version line ...
void setBackdropRect(float x, float y, float w, float h)
The slice of the bound backdrop this surface samples, normalized texture coords (xy = min,...
bool setExtraBinding(int binding, QRhiTexture *texture, QRhiSampler *sampler)
Bind a consumer-owned texture/sampler at the given binding number.
void setBufferFeedback(bool enable)
void setBufferFilters(const QStringList &filters)
static QRhiSampler::AddressMode wrapModeToRhiAddress(const QString &wrap)
Map a normalized wrap-mode string to QRhiSampler::AddressMode.
constexpr int kMaxBufferPasses
Multipass buffer-pass budget.
Definition AnimationShaderContract.h:546
Definition ShaderCompiler.h:15
constexpr int kMaxBufferPasses
Definition ShaderNodeRhi.h:43
constexpr int kReservedBindingRangeEnd
Last library-managed binding.
Definition ShaderNodeRhi.h:65
constexpr int kMaxCustomColors
Definition ShaderNodeRhi.h:46
PHOSPHORRENDERING_EXPORT WarmShaderBakeResult warmShaderBakeCacheForPaths(const QString &vertexPath, const QString &fragmentPath, const QStringList &includePaths={}, const QString &paramPreamble={}, const QString &entryPrologue={}, const QList< PhosphorShaders::EntryCandidate > &entryCandidates={})
Pre-load cache warming: load, bake, and insert shaders for the given paths into the shared bake cache...
constexpr int kFirstFreeConsumerBinding
First slot usable via setExtraBinding()
Definition ShaderNodeRhi.h:58
constexpr int kReservedBindingRangeStart
First library-managed binding above 0.
Definition ShaderNodeRhi.h:64
constexpr bool isConsumerBinding(int binding) noexcept
Definition ShaderNodeRhi.h:73
constexpr int kMaxConsumerBinding
Highest portable SRB binding.
Definition ShaderNodeRhi.h:63
constexpr int kMaxUserTextures
Definition ShaderNodeRhi.h:44
constexpr int kUserTextureBaseBinding
First SRB binding for the user-texture slots (slot 0 → binding 7).
Definition ShaderNodeRhi.h:70
constexpr int kMaxCustomParams
Definition ShaderNodeRhi.h:45
Result of warmShaderBakeCacheForPaths for reporting to UI.
Definition ShaderNodeRhi.h:782
QString errorMessage
Definition ShaderNodeRhi.h:784
bool success
Definition ShaderNodeRhi.h:783