1 /****************************************************************************
2 **
3 ** Copyright (C) 2008-2012 NVIDIA Corporation.
4 ** Copyright (C) 2019 The Qt Company Ltd.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of Qt Quick 3D.
8 **
9 ** $QT_BEGIN_LICENSE:GPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU
20 ** General Public License version 3 or (at your option) any later version
21 ** approved by the KDE Free Qt Foundation. The licenses are as published by
22 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
23 ** included in the packaging of this file. Please review the following
24 ** information to ensure the GNU General Public License requirements will
25 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
26 **
27 ** $QT_END_LICENSE$
28 **
29 ****************************************************************************/
30
31 #include <QtQuick3DRender/private/qssgrendercontext_p.h>
32 #include <QtQuick3DRender/private/qssgrendertexturebase_p.h>
33
34 #include <limits>
35
36 QT_BEGIN_NAMESPACE
37
38 class QSSGRenderTextureSampler
39 {
40 public:
41 QSSGRenderTextureMinifyingOp minFilter = QSSGRenderTextureMinifyingOp::Linear;
42 QSSGRenderTextureMagnifyingOp magFilter = QSSGRenderTextureMagnifyingOp::Linear;
43 QSSGRenderTextureCoordOp wrapS = QSSGRenderTextureCoordOp::ClampToEdge;
44 QSSGRenderTextureCoordOp wrapT = QSSGRenderTextureCoordOp::ClampToEdge;
45 QSSGRenderTextureCoordOp wrapR = QSSGRenderTextureCoordOp::ClampToEdge;
46 QSSGRenderTextureSwizzleMode swizzleMode = QSSGRenderTextureSwizzleMode::NoSwizzle;
47 float minLod = -1000.;
48 float maxLod = 1000.;
49 float lodBias = 0.;
50 QSSGRenderTextureCompareMode compareMode = QSSGRenderTextureCompareMode::NoCompare;
51 QSSGRenderTextureCompareOp compareOp = QSSGRenderTextureCompareOp::LessThanOrEqual;
52 float m_anisotropy = 1.;
53
54 /**
55 * @brief constructor
56 *
57 * @param[in] context Pointer to context
58 * @param[in] fnd Pointer to foundation
59 * @param[in] minFilter Texture min filter
60 * @param[in] magFilter Texture mag filter
61 * @param[in] wrapS Texture coord generation for S
62 * @param[in] wrapT Texture coord generation for T
63 * @param[in] wrapR Texture coord generation for R
64 * @param[in] swizzleMode Texture swizzle mode
65 * @param[in] minLod Texture min level of detail
66 * @param[in] maxLod Texture max level of detail
67 * @param[in] lodBias Texture level of detail bias (unused)
68 * @param[in] compareMode Texture compare mode
69 * @param[in] compareFunc Texture compare function
70 * @param[in] anisoFilter Aniso filter value [1.0, 16.0]
71 * @param[in] borderColor Texture border color float[4] (unused)
72 *
73 * @return No return.
74 */
QSSGRenderTextureSampler(const QSSGRef<QSSGRenderContext> & context)75 explicit QSSGRenderTextureSampler(const QSSGRef<QSSGRenderContext> &context)
76 : m_backend(context->backend())
77 , m_handle(nullptr)
78 {
79 // create backend handle
80 m_handle = m_backend->createSampler();
81 }
82
~QSSGRenderTextureSampler()83 ~QSSGRenderTextureSampler()
84 {
85 if (m_handle)
86 m_backend->releaseSampler(m_handle);
87 }
88
89 /**
90 * @brief get the backend object handle
91 *
92 * @return the backend object handle.
93 */
handle() const94 QSSGRenderBackend::QSSGRenderBackendSamplerObject handle() const { return m_handle; }
95
96 private:
97 QSSGRef<QSSGRenderBackend> m_backend; ///< pointer to backend
98 QSSGRenderBackend::QSSGRenderBackendSamplerObject m_handle = nullptr;
99 };
100
101
QSSGRenderTextureBase(const QSSGRef<QSSGRenderContext> & context,QSSGRenderTextureTargetType texTarget,bool ownsTexture)102 QSSGRenderTextureBase::QSSGRenderTextureBase(const QSSGRef<QSSGRenderContext> &context,
103 QSSGRenderTextureTargetType texTarget,
104 bool ownsTexture)
105 : m_context(context)
106 , m_backend(context->backend())
107 , m_handle(nullptr)
108 , m_textureUnit(std::numeric_limits<qint32>::max())
109 , m_samplerParamsDirty(true)
110 , m_texStateDirty(false)
111 , m_sampleCount(1)
112 , m_format(QSSGRenderTextureFormat::Unknown)
113 , m_texTarget(texTarget)
114 , m_baseLevel(0)
115 , m_maxLevel(1000)
116 , m_maxMipLevel(0)
117 , m_immutable(false)
118 , m_ownsTexture(ownsTexture)
119 {
120 if (m_ownsTexture)
121 m_handle = m_backend->createTexture();
122 m_sampler = new QSSGRenderTextureSampler(context);
123 }
124
~QSSGRenderTextureBase()125 QSSGRenderTextureBase::~QSSGRenderTextureBase()
126 {
127 if (m_sampler)
128 delete m_sampler;
129 if (m_handle && m_ownsTexture)
130 m_backend->releaseTexture(m_handle);
131 }
132
setBaseLevel(qint32 value)133 void QSSGRenderTextureBase::setBaseLevel(qint32 value)
134 {
135 if (m_baseLevel != value) {
136 m_baseLevel = value;
137 m_texStateDirty = true;
138 }
139 }
140
setMaxLevel(qint32 value)141 void QSSGRenderTextureBase::setMaxLevel(qint32 value)
142 {
143 if (m_maxLevel != value) {
144 m_maxLevel = value;
145 m_texStateDirty = true;
146 }
147 }
148
setMinFilter(QSSGRenderTextureMinifyingOp value)149 void QSSGRenderTextureBase::setMinFilter(QSSGRenderTextureMinifyingOp value)
150 {
151 if (m_sampler->minFilter != value) {
152 m_sampler->minFilter = value;
153 m_samplerParamsDirty = true;
154 }
155 }
156
setMagFilter(QSSGRenderTextureMagnifyingOp value)157 void QSSGRenderTextureBase::setMagFilter(QSSGRenderTextureMagnifyingOp value)
158 {
159 if (m_sampler->magFilter != value) {
160 m_sampler->magFilter = value;
161 m_samplerParamsDirty = true;
162 }
163 }
164
setTextureWrapS(QSSGRenderTextureCoordOp value)165 void QSSGRenderTextureBase::setTextureWrapS(QSSGRenderTextureCoordOp value)
166 {
167 if (m_sampler->wrapS != value) {
168 m_sampler->wrapS = value;
169 m_samplerParamsDirty = true;
170 }
171 }
172
setTextureWrapT(QSSGRenderTextureCoordOp value)173 void QSSGRenderTextureBase::setTextureWrapT(QSSGRenderTextureCoordOp value)
174 {
175 if (m_sampler->wrapT != value) {
176 m_sampler->wrapT = value;
177 m_samplerParamsDirty = true;
178 }
179 }
180
setTextureCompareMode(QSSGRenderTextureCompareMode value)181 void QSSGRenderTextureBase::setTextureCompareMode(QSSGRenderTextureCompareMode value)
182 {
183 if (m_sampler->compareMode != value) {
184 m_sampler->compareMode = value;
185 m_samplerParamsDirty = true;
186 }
187 }
188
setTextureCompareFunc(QSSGRenderTextureCompareOp value)189 void QSSGRenderTextureBase::setTextureCompareFunc(QSSGRenderTextureCompareOp value)
190 {
191 if (m_sampler->compareOp != value) {
192 m_sampler->compareOp = value;
193 m_samplerParamsDirty = true;
194 }
195 }
196
applyTexParams()197 void QSSGRenderTextureBase::applyTexParams()
198 {
199 if (m_samplerParamsDirty) {
200 m_backend->updateSampler(m_sampler->handle(),
201 m_texTarget,
202 m_sampler->minFilter,
203 m_sampler->magFilter,
204 m_sampler->wrapS,
205 m_sampler->wrapT,
206 m_sampler->wrapR,
207 m_sampler->minLod,
208 m_sampler->maxLod,
209 m_sampler->lodBias,
210 m_sampler->compareMode,
211 m_sampler->compareOp);
212
213 m_samplerParamsDirty = false;
214 }
215
216 if (m_texStateDirty) {
217 m_backend->updateTextureObject(m_handle, m_texTarget, m_baseLevel, m_maxLevel);
218 m_texStateDirty = false;
219 }
220 }
221
applyTexSwizzle()222 void QSSGRenderTextureBase::applyTexSwizzle()
223 {
224 QSSGRenderTextureSwizzleMode theSwizzleMode = m_backend->getTextureSwizzleMode(m_format);
225 if (theSwizzleMode != m_sampler->swizzleMode) {
226 m_sampler->swizzleMode = theSwizzleMode;
227 m_backend->updateTextureSwizzle(m_handle, m_texTarget, theSwizzleMode);
228 }
229 }
230 QT_END_NAMESPACE
231