From b4954701093739e7a4e54a0669f306922d0d4605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Kera=CC=88nen?= Date: Thu, 6 Jun 2019 16:22:02 +0300 Subject: Long live the slayer! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initial commit of OpenGL Runtime to repository. Based on SHA1 61823aaccc6510699a54b34a2fe3f7523dab3b4e of qt3dstudio repository. Task-number: QT3DS-3600 Change-Id: Iaeb80237399f0e5656a19ebec9d1ab3a681d8832 Reviewed-by: Pasi Keränen --- src/render/backends/Qt3DSRenderBackend.h | 2245 ++++++++++++++++++++ src/render/backends/gl/Q3DSRenderBackendGLES2.cpp | 902 ++++++++ src/render/backends/gl/Q3DSRenderBackendGLES2.h | 195 ++ src/render/backends/gl/Qt3DSOpenGLExtensions.cpp | 170 ++ src/render/backends/gl/Qt3DSOpenGLExtensions.h | 392 ++++ src/render/backends/gl/Qt3DSOpenGLPrefix.h | 48 + src/render/backends/gl/Qt3DSOpenGLTokens.h | 408 ++++ src/render/backends/gl/Qt3DSOpenGLUtil.h | 2201 +++++++++++++++++++ src/render/backends/gl/Qt3DSRenderBackendGL3.cpp | 796 +++++++ src/render/backends/gl/Qt3DSRenderBackendGL3.h | 173 ++ src/render/backends/gl/Qt3DSRenderBackendGL4.cpp | 875 ++++++++ src/render/backends/gl/Qt3DSRenderBackendGL4.h | 205 ++ .../backends/gl/Qt3DSRenderBackendGLBase.cpp | 2230 +++++++++++++++++++ src/render/backends/gl/Qt3DSRenderBackendGLBase.h | 531 +++++ .../gl/Qt3DSRenderBackendInputAssemblerGL.h | 146 ++ .../backends/gl/Qt3DSRenderBackendRenderStatesGL.h | 173 ++ .../gl/Qt3DSRenderBackendShaderProgramGL.h | 105 + src/render/backends/gl/Qt3DSRenderContextGL.cpp | 91 + .../backends/software/Qt3DSRenderBackendNULL.cpp | 588 +++++ .../backends/software/Qt3DSRenderBackendNULL.h | 46 + 20 files changed, 12520 insertions(+) create mode 100644 src/render/backends/Qt3DSRenderBackend.h create mode 100644 src/render/backends/gl/Q3DSRenderBackendGLES2.cpp create mode 100644 src/render/backends/gl/Q3DSRenderBackendGLES2.h create mode 100644 src/render/backends/gl/Qt3DSOpenGLExtensions.cpp create mode 100644 src/render/backends/gl/Qt3DSOpenGLExtensions.h create mode 100644 src/render/backends/gl/Qt3DSOpenGLPrefix.h create mode 100644 src/render/backends/gl/Qt3DSOpenGLTokens.h create mode 100644 src/render/backends/gl/Qt3DSOpenGLUtil.h create mode 100644 src/render/backends/gl/Qt3DSRenderBackendGL3.cpp create mode 100644 src/render/backends/gl/Qt3DSRenderBackendGL3.h create mode 100644 src/render/backends/gl/Qt3DSRenderBackendGL4.cpp create mode 100644 src/render/backends/gl/Qt3DSRenderBackendGL4.h create mode 100644 src/render/backends/gl/Qt3DSRenderBackendGLBase.cpp create mode 100644 src/render/backends/gl/Qt3DSRenderBackendGLBase.h create mode 100644 src/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h create mode 100644 src/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h create mode 100644 src/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h create mode 100644 src/render/backends/gl/Qt3DSRenderContextGL.cpp create mode 100644 src/render/backends/software/Qt3DSRenderBackendNULL.cpp create mode 100644 src/render/backends/software/Qt3DSRenderBackendNULL.h (limited to 'src/render/backends') diff --git a/src/render/backends/Qt3DSRenderBackend.h b/src/render/backends/Qt3DSRenderBackend.h new file mode 100644 index 0000000..12de5d8 --- /dev/null +++ b/src/render/backends/Qt3DSRenderBackend.h @@ -0,0 +1,2245 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_H +#define QT3DS_RENDER_BACKEND_H + +/// @file Qt3DSRenderBackend.h +/// NVRender backend definition. + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSNoCopy.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSBounds3.h" +#include + +#include + +namespace qt3ds { +namespace render { + +#define HandleToID_cast(staticType, dynamicType, handle) \ + static_cast(reinterpret_cast(handle)) + + class NVRenderBackend : public NVRefCounted, public NoCopy + { + + public: + /// opaque buffer object handle + typedef struct _NVRenderBackendBufferObject *NVRenderBackendBufferObject; + /// opaque attribute layout object handle + typedef struct _NVRenderBackendAttribLayoutObject *NVRenderBackendAttribLayoutObject; + /// opaque input assembler object handle + typedef struct _NVRenderBackendInputAssemblerObject *NVRenderBackendInputAssemblerObject; + /// opaque texture object handle + typedef struct _NVRenderBackendTextureObject *NVRenderBackendTextureObject; + /// opaque sampler object handle + typedef struct _NVRenderBackendSamplerObject *NVRenderBackendSamplerObject; + /// opaque renderbuffer object handle + typedef struct _NVRenderBackendRenderbufferObject *NVRenderBackendRenderbufferObject; + /// opaque framebuffer object handle + typedef struct _NVRenderBackendRenderTargetObject *NVRenderBackendRenderTargetObject; + /// opaque vertex shader object handle + typedef struct _NVRenderBackendVertexShaderObject *NVRenderBackendVertexShaderObject; + /// opaque fragment shader object handle + typedef struct _NVRenderBackendFragmentShaderObject *NVRenderBackendFragmentShaderObject; + /// opaque tesselation control shader object handle + typedef struct _NVRenderBackendTessControlShaderObject + *NVRenderBackendTessControlShaderObject; + /// opaque tesselation evaluation shader object handle + typedef struct _NVRenderBackendTessEvaluationShaderObject + *NVRenderBackendTessEvaluationShaderObject; + /// opaque geometry shader object handle + typedef struct _NVRenderBackendGeometryShaderObject *NVRenderBackendGeometryShaderObject; + /// opaque compute shader object handle + typedef struct _NVRenderBackendComputeShaderObject *NVRenderBackendComputeShaderObject; + /// opaque shader program object handle + typedef struct _NVRenderBackendShaderProgramObject *NVRenderBackendShaderProgramObject; + /// opaque depth stencil state object handle + typedef struct _NVRenderBackendDepthStencilStateObject + *NVRenderBackendDepthStencilStateObject; + /// opaque rasterizer state object handle + typedef struct _NVRenderBackendRasterizerStateObject *NVRenderBackendRasterizerStateObject; + /// opaque query object handle + typedef struct _NVRenderBackendQueryObject *NVRenderBackendQueryObject; + /// opaque sync object handle + typedef struct _NVRenderBackendSyncObject *NVRenderBackendSyncObject; + /// opaque sync object handle + typedef struct _NVRenderBackendProgramPipeline *NVRenderBackendProgramPipeline; + /// opaque sync object handle + typedef struct _NVRenderBackendPathObject *NVRenderBackendPathObject; + + // backend capability caps + typedef struct + { + enum Enum { + ConstantBuffer, ///< Constant buffer support query + DepthStencilTexture, ///< depth stencil texture format suport query + DxtImages, ///< DXT image support query + FpRenderTarget, ///< render to floating point target support query + MsTexture, ///< Multisample texture support query + TexSwizzle, ///< Texture swizzle support query + FastBlits, ///< Hardware supports fast blits + Tessellation, ///< Hardware supports tessellation + Compute, ///< Hardware supports compute shader + Geometry, ///< Hardware supports geometry shader + SampleQuery, ///< Hardware supports query calls of type samples + TimerQuery, ///< Hardware supports query calls of type timer + CommandSync, ///< Hardware supports command sync object + TextureArray, ///< Hardware supports texture arrays + StorageBuffer, ///< Hardware supports shader storage buffers + AtomicCounterBuffer, ///< Hardware supports atomic counter buffers + ShaderImageLoadStore, ///< Hardware supports shader image load store operations + ProgramPipeline, ///< Driver supports separate programs + PathRendering, ///< Driver support path rendering + AdvancedBlend, ///< Driver supports advanced blend modes + BlendCoherency, ///< Hardware supports blend coherency + gpuShader5, // for high precision sampling + AdvancedBlendKHR, ///< Driver supports advanced blend modes + VertexArrayObject, + StandardDerivatives, + TextureLod + }; + } NVRenderBackendCaps; + + // backend queries + typedef struct + { + enum Enum { + MaxTextureSize, ///< Return max supported texture size + MaxTextureArrayLayers, ///< Return max supported layer count for texture arrays + MaxConstantBufferSlots, ///< Return max supported constant buffe slots for a single + ///shader stage + MaxConstantBufferBlockSize ///< Return max supported size for a single constant + ///buffer block + }; + } NVRenderBackendQuery; + + /// backend interface + + /** + * @brief get the backend type + * + * @return true backend type + */ + virtual NVRenderContextType GetRenderContextType() const = 0; + + /** + * @brief get the version of the shading language + * @return version string, must be copied by clients to be retained. + */ + virtual const char *GetShadingLanguageVersion() = 0; + + /** + * @brief get maximum supported texture image units that + * can be used to access texture maps from the vertex shader and the fragment processor + *combined. + * + * @return max texture size + */ + virtual QT3DSU32 GetMaxCombinedTextureUnits() = 0; + + /** + * @brief query Backend capabilities + * + * @param[in] inCap CAPS flag to query + * @ConstantBuffer, @DepthStencilTexture, ... + * + * @return true if supported + */ + virtual bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const = 0; + + /** + * @brief query Backend values + * + * @param[in] inQuery Query flag to get value for + * @MaxTextureSize, @MaxTextureArrayLayers, + *... + * @param[in/out] params the query result is stored here + * + * @return no return + */ + virtual void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, + QT3DSI32 *params) const = 0; + + /** + * @brief query for bit depth of the depth buffer + * + * @return depth buffer bitplanes + */ + virtual QT3DSU32 GetDepthBits() const = 0; + + /** + * @brief query for bit depth of the stencil buffer + * + * @return stencil buffer bitplanes + */ + virtual QT3DSU32 GetStencilBits() const = 0; + + /* + * @brief set a backend rende state + * + * @param[in] bEnable enable/disable state + * @param[in] value type of state + * + * @return no return + */ + virtual void SetRenderState(bool bEnable, const NVRenderState::Enum value) = 0; + + /** + * @brief get a backend rende state + * + * @param[in] value type of state + * + * @return true if state enabled otherwise false + */ + virtual bool GetRenderState(const NVRenderState::Enum value) = 0; + + /** + * @brief get current depth function + * + * @return active depth function + */ + virtual NVRenderBoolOp::Enum GetDepthFunc() = 0; + + /** + * @brief create a depth stencil state object + * + * @param[in] enableDepth enable depth test + * @param[in] depthMask enable depth writes + * @param[in] depthFunc depth compare function + * @param[in] enableStencil enable stencil test + * @param[in] stencilFuncFront stencil setup front faces + * @param[in] stencilFuncBack stencil setup back faces + * @param[in] depthStencilOpFront depth/stencil operations front faces + * @param[in] depthStencilOpBack depth/stencil operations back faces + * + * @return opaque handle to state object + */ + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) = 0; + + /** + * @brief release a depth stencil state object + * + * @param[in] depthStencilState pointer to state object + * + * @return none + */ + virtual void + ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; + + /** + * @brief create a rasterizer state object + * + * @param[in] depthBias any othe value than 0 enables depth bias + * @param[in] depthScale any othe value than 0 enables depth scale + * @param[in] cullFace select face to cull front or back + * + * @return opaque handle to state object + */ + virtual NVRenderBackendRasterizerStateObject + CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) = 0; + + /** + * @brief release a rasterizer state object + * + * @param[in] rasterizerState pointer to state object + * + * @return none + */ + virtual void + ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; + + /** + * @brief set depth stencil state + * + * @param[in] depthStencilState pointer to state object + * + * @return none + */ + virtual void + SetDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; + + /** + * @brief set rasterizer state + * + * @param[in] rasterizerState pointer to state object + * + * @return none + */ + virtual void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; + + /** + * @brief set current depth function + * + * @param[in] func type of function + * + * @return no return + */ + virtual void SetDepthFunc(const NVRenderBoolOp::Enum func) = 0; + + /** + * @brief query if depth write is enabled + * + * @return true if enabled + */ + virtual bool GetDepthWrite() = 0; + + /** + * @brief enable / disable depth writes + * + * @param[in] bEnable true for enable + * + * @return no return + */ + virtual void SetDepthWrite(bool bEnable) = 0; + + /** + * @brief enable / disable color channel writes + * + * @param[in] bRed true for enable red channel + * @param[in] bGreen true for enable green channel + * @param[in] bBlue true for enable blue channel + * @param[in] bAlpha true for enable alpha channel + * + * @return no return + */ + virtual void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; + + /** + * @brief enable / disable multisample rendering + * + * @param[in] bEnable true for enable + * + * @return no return + */ + virtual void SetMultisample(bool bEnable) = 0; + + /** + * @brief query blend functions + * + * @param[out] pBlendFuncArg blending functions + * + * @return no return + */ + virtual void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) = 0; + + /** + * @brief set blend functions + * + * @param[in] pBlendFuncArg blending functions + * + * @return no return + */ + virtual void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) = 0; + + /** + * @brief set blend equation + * + * @param[in] pBlendEquArg blending equation + * + * @return no return + */ + virtual void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) = 0; + + /** + * @brief guarantee blend coherency + * + * + * @return no return + */ + virtual void SetBlendBarrier(void) = 0; + + /** + * @brief query scissor rectangle + * + * @param[out] pRect contains scissor rect + * + * @return no return + */ + virtual void GetScissorRect(NVRenderRect *pRect) = 0; + + /** + * @brief set scissor rectangle + * + * @param[out] pRect contains scissor rect + * + * @return no return + */ + virtual void SetScissorRect(const NVRenderRect &rect) = 0; + + /** + * @brief query viewport rectangle + * + * @param[out] pRect contains viewport rect + * + * @return no return + */ + virtual void GetViewportRect(NVRenderRect *pRect) = 0; + + /** + * @brief set viewport rectangle + * + * @param[out] pRect contains viewport rect + * + * @return no return + */ + virtual void SetViewportRect(const NVRenderRect &rect) = 0; + + /** + * @brief query viewport rectangle + * + * @param[in] clearColor clear color + * + * @return no return + */ + virtual void SetClearColor(const QT3DSVec4 *pClearColor) = 0; + + /** + * @brief query viewport rectangle + * + * @param[in] flags clear flags + * + * @return no return + */ + virtual void Clear(NVRenderClearFlags flags) = 0; + + /** + * @brief create a buffer object + * + * @param[in] size Size of the buffer + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + *application. + * + * @return The created buffer object or NULL if the creation failed. + */ + virtual NVRenderBackendBufferObject CreateBuffer(size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, + const void *hostPtr = NULL) = 0; + + /** + * @brief bind a buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * + * @return no return. + */ + virtual void BindBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) = 0; + + /** + * @brief Release a single buffer object + * + * @param[in] bo Pointer to buffer object + * + * @return no return. + */ + virtual void ReleaseBuffer(NVRenderBackendBufferObject bo) = 0; + + /** + * @brief update a whole buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] size Size of the data buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return no return. + */ + virtual void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t size, NVRenderBufferUsageType::Enum usage, + const void *data) = 0; + + /** + * @brief update a range of a buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] size Size of the data buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return no return. + */ + virtual void UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) = 0; + + /** + * @brief Get a pointer to the buffer data ( GL(ES) >= 3 only ) + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] offset Byte offset into the data buffer + * @param[in] length Byte length of mapping size + * @param[in] access Access of the buffer (e.g. read, write, ...) + * + * @return pointer to mapped data or null. + */ + virtual void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) = 0; + + /** + * @brief Unmap a previously mapped buffer ( GL(ES) >= 3 only ) + * This functions transfers the content to the hardware buffer + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * + * @return true if successful + */ + virtual bool UnmapBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) = 0; + + /** + * @brief Set a memory barrier + * + * @param[in] barriers Flags for barriers + * + * @return no return. + */ + virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0; + + /** + * @brief create a query object + * + * @return The created query object or NULL if the creation failed. + */ + virtual NVRenderBackendQueryObject CreateQuery() = 0; + + /** + * @brief delete query objects + * + * @param[in] qo Handle to query object + * + * @return no return + */ + virtual void ReleaseQuery(NVRenderBackendQueryObject qo) = 0; + + /** + * @brief Start query recording + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * + * @return no return + */ + virtual void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; + + /** + * @brief End query recording + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * + * @return no return + */ + virtual void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; + + /** + * @brief Get a query result + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * @param[out] params Contains result of query regarding query type + * + * @return no return + */ + virtual void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) = 0; + + /** + * @brief Get a query result + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * @param[out] params Contains result of query regarding query type 64 bit returns + * + * @return no return + */ + virtual void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) = 0; + + /** + * @brief Record the GPU time using the query object + * + * @param[in] qo Handle to query object + * + * @return no return + */ + virtual void SetQueryTimer(NVRenderBackendQueryObject qo) = 0; + + /** + * @brief create a sync object and place it in the command queue + * + * @param[in] tpye Type to sync + * @param[in] syncFlags Currently unused + * + * @return The created sync object or NULL if the creation failed. + */ + virtual NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) = 0; + + /** + * @brief delete sync object + * + * @param[in] so Handle to sync object + * + * @return no return + */ + virtual void ReleaseSync(NVRenderBackendSyncObject so) = 0; + + /** + * @brief wait for sync object to be signaled + * + * @param[in] so Handle to sync object + * @param[in] syncFlags Currently unused + * @param[in] timeout Currently ignored + * + * @return no return + */ + virtual void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) = 0; + + /** + * @brief create a render target object + * + * + * @return The created render target object or NULL if the creation failed. + */ + virtual NVRenderBackendRenderTargetObject CreateRenderTarget() = 0; + + /** + * @brief Release a single render target object + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Attach a renderbuffer object to the framebuffer + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] rbo Pointer to renderbuffer object + * + * @return no return. + */ + virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) = 0; + + /** + * @brief Attach a texture object to the render target + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] to Pointer to texture object + * @param[in] target Attachment texture target + * + * @return no return. + */ + virtual void RenderTargetAttach( + NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) = 0; + + /** + * @brief Attach a texture object to the render target + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] to Pointer to texture object + * @param[in] level Texture mip level + * @param[in] layer Texture layer or slice + * + * @return no return. + */ + virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) = 0; + + /** + * @brief Make a render target active + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void SetRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Check if a render target is ready for render + * + * @param[in] rto Pointer to render target object + * + * @return true if usable. + */ + virtual bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Make a render target active for reading + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void SetReadTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Set active buffers for drawing + * + * @param[in] rto Pointer to render target object + * @param[in] inDrawBufferSet Pointer to array of enabled render targets + * + * @return no return. + */ + virtual void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) = 0; + + /** + * @brief Set active buffer for reading + * + * @param[in] rto Pointer to render target object + * @param[in] inReadFace Buffer to read from + * + * @return no return. + */ + virtual void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) = 0; + + /** + * @brief Copy framebuffer attachments. Source is set with SetReadTarget dest with + * SetRenderTarget + * + * @param[in] srcX0 Lower left X coord of source rectangle + * @param[in] srcY0 Lower left Y coord of source rectangle + * @param[in] srcX1 Upper right X coord of source rectangle + * @param[in] srcY1 Upper right Y coord of source rectangle + * @param[in] dstX0 Lower left X coord of dest rectangle + * @param[in] dstY0 Lower left Y coord of dest rectangle + * @param[in] dstX1 Upper right X coord of dest rectangle + * @param[in] dstY1 Upper right Y coord of dest rectangle + * @param[in] inDrawBufferSet pointer to array of enabled render targets + * @param[in] filter Copy filter method (NEAREST or LINEAR) + * + * @return no return. + */ + virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) = 0; + + /** + * @brief create a render buffer object + * + * @param[in] storageFormat Format of the buffer + * @param[in] width Buffer with + * @param[in] height Buffer height + * + * @return The created render buffer object or NULL if the creation failed. + */ + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) = 0; + + /** + * @brief Release a single renderbuffer object + * + * @param[in] bo Pointer to renderbuffer object + * + * @return no return. + */ + virtual void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) = 0; + + /** + * @brief resize a render buffer object + * + * @param[in] storageFormat Format of the buffer + * @param[in] width Buffer with + * @param[in] height Buffer height + * + * @return True on success + */ + virtual bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) = 0; + + /** + * @brief create a texture object + * + * @return The created texture object or NULL if the creation failed.. + */ + virtual NVRenderBackendTextureObject CreateTexture() = 0; + + /** + * @brief set texture data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief set texture data for the face of a Cube map + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target face + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief create a storage for a 2D texture including mip levels + * Note that this makes texture immutable in size and format + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] levels Texture mip level count + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * + * @return No return + */ + virtual void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) = 0; + + /** + * @brief set texture sub data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] xOffset Texture x offset + * @param[in] yOffset Texture y offset + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] border border + * @param[in] format format of texture + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture data for a Cubemap face + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture sub data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] xOffset Texture x offset + * @param[in] yOffset Texture y offset + * @param[in] width texture width + * @param[in] height texture height + * @param[in] format format of provided pixel data + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureSubData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief establish a multisampled 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D MS + * @param[in] samples Textures sample count + * @param[in] internalFormat Format of the texture + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] bool Fixed sample locations + * + * @return No return + */ + virtual void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) = 0; + + /** + * @brief set texture data for a 3D texture or 2D texture array + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] depth texture depth or slice count + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief generate mipmap levels + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D,... + * @param[in] hint How to generate mips (Nicest) + * + * @return No return + */ + virtual void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) = 0; + + /** + * @brief bind a texture object + * + * @param[in] to Pointer to texture object + * @param[in] target Where to bind this texture (e.g. 2D, 3D, ...) + * @param[in] unit Which unit to bind this texture + * + * @return no return. + */ + virtual void BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) = 0; + + /** + * @brief bind a image/texture object + * + * @param[in] to Pointer to texture object + * @param[in] unit Which unit to bind this texture + * @param[in] level Which level to bind + * @param[in] layered Bind layered texture (cube map, array,... ) + * @param[in] level Specify layer. Only valid of layered=false. + * @param[in] access Access mode ( read, write, read-write ) + * @param[in] format Texture format must be compatible with Image format + * + * @return no return. + */ + virtual void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum accessFlags, + NVRenderTextureFormats::Enum format) = 0; + + /** + * @brief Release a single texture object + * + * @param[in] to Pointer to buffer object + * + * @return no return. + */ + virtual void ReleaseTexture(NVRenderBackendTextureObject to) = 0; + + /** + * @brief query texture swizzle mode + * This is mainly for luminance, alpha replacement with R8 formats + * + * @param[in] inFormat input texture format to check + * + * @return texture swizzle mode + */ + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const = 0; + + /** + * @ brief create a sampler + * + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail example + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] + * + * @return The created sampler object or NULL if the creation failed. + */ + virtual NVRenderBackendSamplerObject CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; + + /** + * @ brief update a sampler + * + * @param[in] so Pointer to sampler object + * @param[in] target Texture target 2D, 3D + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail bias (unused) + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] (unused) + * + * @return No return + */ + virtual void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; + + /** + * @ brief Update a textures swizzle mode + * + * @param[in] so Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] swizzleMode Texture swizzle mode + * + * @return No return + */ + virtual void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) = 0; + + /** + * @ brief Update state belonging to a texture object + * + * @param[in] so Pointer to texture object + * @param[in] target Texture target 2D, 3D, Cube + * @param[in] baseLevel Texture base level + * @param[in] maxLevel Texture max level + * + * @return No return + */ + virtual void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) = 0; + + /** + * @brief Release a single sampler object + * + * @param[in] so Pointer to sampler object + * + * @return no return. + */ + virtual void ReleaseSampler(NVRenderBackendSamplerObject so) = 0; + + /** + * @brief create a attribute layout object + * + * @param[in] attribs Array off vertex attributes. + * + * @return The created attribute layout object or NULL if the creation failed. + */ + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef attribs) = 0; + + /** + * @brief Release a attribute layoutr object + * + * @param[in] ao Pointer to attribute layout object + * + * @return no return. + */ + virtual void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) = 0; + + /** + * @brief create a input assembler object + * + * @param[in] attribLayout Pointer to NVRenderBackendAttribLayoutObject object + * @param[in] buffers list of vertex buffers + * @param[in] indexBuffer index buffer object + * @param[in] strides list of strides of the buffer + * @param[in] offsets list of offsets into the buffer + * @param[in] patchVertexCount vertext count for a patch. Only valid for patch primitives + * + * @return The created input assembler object or NULL if the creation failed. + */ + virtual NVRenderBackendInputAssemblerObject + CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, + QT3DSU32 patchVertexCount) = 0; + + /** + * @brief Release a input assembler object + * + * @param[in] iao Pointer to attribute layout object + * + * @return no return. + */ + virtual void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) = 0; + + /** + * @brief Set a input assembler object. + * This setup the render engine vertex assmebly + * + * @param[in] iao Pointer to attribute layout object + * @param[in] po Pointer program object + * + * @return false if it fails. + */ + virtual bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Set the per patch vertex count + * + * @param[in] iao Pointer to attribute layout object + * @param[in] count Count of vertices per patch + * + * @return false if it fails. + */ + virtual void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) = 0; + + /** + * @brief create a vertex shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created vertex shader object or NULL if the creation failed. + */ + virtual NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef source, + eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a vertex shader object + * + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief create a fragment shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created vertex shader object or NULL if the creation failed. + */ + virtual NVRenderBackendFragmentShaderObject + CreateFragmentShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a fragment shader object + * + * @param[in] vso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief create a tessellation control shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created tessellation control shader object or NULL if the creation failed. + */ + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a tessellation control shader object + * + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief create a tessellation evaluation shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created tessellation evaluation shader object or NULL if the creation failed. + */ + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a tessellation evaluation shader object + * + * @param[in] tcso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void + ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief create a geometry shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created geometry shader object or NULL if the creation failed. + */ + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a geometry shader object + * + * @param[in] tcso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief create a compute shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created compute shader object or NULL if the creation failed. + */ + virtual NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef source, + eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a compute shader object + * + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief attach a vertex shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief detach a vertex shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief attach a fragment shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] fso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief detach a fragment shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] fso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief attach a tessellation control shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief detach a tessellation control shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief attach a tessellation evaluation shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief detach a tessellation evaluation shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief attach a geometry shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief detach a geometry shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief attach a compute shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief detach a compute shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief create a shader program object + * + * @param[in] isSeparable Tell the backend that this program is separable + * + * @return The created shader program object or NULL if the creation failed. + */ + virtual NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) = 0; + + /** + * @brief release a shader program object + * + * @param[in] po Pointer to shader program object + * + * @return No Return. + */ + virtual void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief link a shader program object + * + * @param[in] po Pointer to shader program object + * @param[in/out] errorMessage Pointer to copy the error message + * + * @return True if program is succesful linked. + */ + virtual bool LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) = 0; + + /** + * @brief Make a program current + * + * @param[in] po Pointer to shader program object + * + * @return No return + */ + virtual void SetActiveProgram(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief create a program pipeline object + * + * + * @return The created program pipeline object or NULL if the creation failed. + */ + virtual NVRenderBackendProgramPipeline CreateProgramPipeline() = 0; + + /** + * @brief release a program pipeline object + * + * @param[in] ppo Pointer to program pipeline object + * + * @return No Return. + */ + virtual void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; + + /** + * @brief Make a program pipeline current + * + * @param[in] ppo Pointer to program pipeline object + * + * @return No return + */ + virtual void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; + + /** + * @brief Make a program stage active for this pipeline + * + * @param[in] ppo Pointer to program pipeline object + * @param[in] flags Shader stage flags to which this po is bound to + * @param[in] po Pointer to shader program object + * + * @return No return + */ + virtual void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Runs a compute program + * + * @param[in] po Pointer to shader program object + * @param[in] numGroupsX The number of work groups to be launched in the X + * dimension + * @param[in] numGroupsY The number of work groups to be launched in the Y + * dimension + * @param[in] numGroupsZ The number of work groups to be launched in the Z + * dimension + * + * @return No return + */ + virtual void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0; + + /** + * @brief Query constant count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active constant count + */ + virtual QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query constant buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active constant buffer count + */ + virtual QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query constant information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant ID + * @param[in] bufSize Max char for nameBuf + * @param[out] numElem Usually one unless for arrays + * @param[out] type Constant data type (QT3DSVec4, QT3DSVec3,...) + * @param[out] binding Unit binding point for samplers and images + * @param[out] nameBuf Name of the constant + * + * @return Return current constant location or -1 if not found + */ + virtual QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) = 0; + + /** + * @brief Query constant buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count ot parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current constant buffer location or -1 if not found + */ + virtual QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) = 0; + + /** + * @brief Query constant buffer param indices + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant buffer ID + * @param[out] indices Receives the indices of the uniforms within the + * constant buffer + * + * @return no return value + */ + virtual void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) = 0; + + /** + * @brief Query constant buffer param info by indices + * + * @param[in] po Pointer to shader program object + * @param[in] count Number of indices + * @param[in] indices The indices of the uniforms within the constant + * buffer + * @param[out] type Array of param types ( float ,int, ...) + * @param[out] size Array of param size + * @param[out] offset Array of param offsets within the constant buffer + * + * @return no return value + */ + virtual void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) = 0; + + /** + * @brief Bind program constant block + * + * @param[in] po Pointer to shader program object + * @param[in] blockIndex Constant block index returned by + * GetConstantBufferInfoByID + * @param[in] binding Block binding location which should be the same as index + * in ProgramSetConstantBlock + * + * @return No return + */ + virtual void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) = 0; + + /** + * @brief Bind constant buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to constant buffer object + * + * @return No return + */ + virtual void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Query storage buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active storage buffer count + */ + virtual QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query storage buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Storage buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count of parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current storage buffer binding or -1 if not found + */ + virtual QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) = 0; + + /** + * @brief Bind a storage buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to storage buffer object + * + * @return No return + */ + virtual void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Query atomic counter buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active atomic buffer count + */ + virtual QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query atomic counter buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Storage buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count of parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current storage buffer binding or -1 if not found + */ + virtual QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) = 0; + + /** + * @brief Bind a atomic counter buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to atomic counter buffer object + * + * @return No return + */ + virtual void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Set constant value + * + * @param[in] po Pointer program object + * @param[in] id Constant ID + * @param[in] type Constant data type (QT3DSVec4, QT3DSVec3,...) + * @param[in] count Element count + * @param[in] value Pointer to constant value + * @param[in] transpose Transpose a matrix + * + * @return No return + */ + virtual void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose = false) = 0; + + /** + * @brief Draw the current active vertex buffer + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] start Start vertex + * @param[in] count Vertex count + * + * @return no return. + */ + virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) = 0; + + /** + * @brief Draw the current active vertex buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] indirect Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) = 0; + + /** + * @brief Draw the current active index buffer + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] count Index count + * @param[in] type Index type (QT3DSU16, QT3DSU8) + * @param[in] indices Pointer to index buffer. In the case of buffer objects + * this is an offset into the active index buffer + *object. + * + * @return no return. + */ + virtual void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) = 0; + + /** + * @brief Draw the current active index buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] type Index type (QT3DSU16, QT3DSU8) + * @param[in] indices Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) = 0; + + /** + * @brief Read a pixel rectangle from render target (from bottom left) + * + * @param[in] rto Pointer to render target object + * @param[in] x Windows X start coord + * @param[in] y Windows Y start coord + * @param[in] width Read width dim + * @param[in] height Read height dim + * @param[out] pixels Returned pixel data + * + * @return No return + */ + virtual void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, + QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, + void *pixels) = 0; + + /** + * @brief Create a NV path render object + * + * @param[in] range Number of internal objects + * + * @return return path object on success or NULL + */ + virtual NVRenderBackendPathObject CreatePathNVObject(size_t range) = 0; + + /** + * @brief Relase a NV path render object + * + * @param[in] po Created path object + * @param[in] range Number of internal objects + * + * @return return path object on success or NULL + */ + virtual void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) = 0; + + /** + * @brief Set the path commands and data. + * + * @param[in] inPathObject Pointer to NV path object + * @param[in] inPathCommands vector of path commands ( moveTo,... ) + * @param[in] inPathCoords vector of path coords + * + * @return No return + */ + virtual void SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef inPathCommands, + NVConstDataRef inPathCoords) = 0; + + /** + * @brief Get Bounds of the path object + * + * @param[in] inPathObject Pointer to NV path object + * + * @return return bounds + */ + virtual NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) = 0; + virtual NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) = 0; + virtual NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) = 0; + + /** + * @brief Set stroke width. Defaults to 0 if unset. + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void SetStrokeWidth(NVRenderBackendPathObject inPathObject, + QT3DSF32 inStrokeWidth) = 0; + + /** + * @brief Path transform commands + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0; + virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0; + + /** + * @brief Path stencil pass operations + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void StencilStrokePath(NVRenderBackendPathObject inPathObject) = 0; + virtual void StencilFillPath(NVRenderBackendPathObject inPathObject) = 0; + + /** + * @brief Does a instanced stencil fill pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] fillMode Fille mode + * @param[in] stencilMask Stencil mask + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced stencil stroke pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] stencilRef Stencil reference + * @param[in] stencilMask Stencil mask + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, + QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced cover fill pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] coverMode Cover mode + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced cover stroke pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] coverMode Cover mode + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Path stencil and depth offset + * + * @param[in] inSlope slope + * @param[in] inBias bias + * + * @return No return + */ + virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0; + + /** + * @brief Path cover function + * + * @param[in] inDepthFunction depth function + * + * @return No return + */ + virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) = 0; + + /** + * @brief Load glyphs + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] numGlyphs Glyph count + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] handleMissingGlyphs skip or use + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return No return + */ + virtual void LoadPathGlyphs(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, + NVRenderPathFormatType::Enum type, const void *charCodes, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) = 0; + + /** + * @brief Load indexed font set + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] firstGlyphIndex First glyph + * @param[in] numGlyphs Glyph count + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return return load status + */ + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) = 0; + + /** + * @brief Load indexed font set + * + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * @param[out] po contains glyph count + * + * @return returnr base path object + */ + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, + QT3DSU32 *count) = 0; + + /** + * @brief Load font set + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] firstGlyph First glyph + * @param[in] numGlyphs Glyph count + * @param[in] handleMissingGlyphs skip or use + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return No return + */ + virtual void LoadPathGlyphRange(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) = 0; + + /** + * @brief Query font metrics + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] metricQueryMask Qeury bit mask + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] stride scale ( true type scale e.g. 2048 ) + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, const void *charCodes, + size_t stride, QT3DSF32 *metrics) = 0; + + /** + * @brief Query font metrics + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] metricQueryMask Qeury bit mask + * @param[in] stride scale ( true type scale e.g. 2048 ) + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) = 0; + + /** + * @brief Query path spacing + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] pathListMode How to compute spacing + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] advanceScale + * @param[in] kerningScale + * @param[in] transformType + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, + QT3DSF32 advanceScale, QT3DSF32 kerningScale, + NVRenderPathTransformType::Enum transformType, + QT3DSF32 *spacing) = 0; + + virtual QSurfaceFormat format() const = 0; + + protected: + /// struct for what the backend supports + typedef struct NVRenderBackendSupport + { + union { + struct + { + bool bDXTImagesSupported : 1; ///< compressed images supported + bool bAnistropySupported : 1; ///< anistropic filtering supported + bool bTextureSwizzleSupported : 1; ///< texture swizzle supported + bool bDepthStencilSupported : 1; ///< depth stencil textures are supported + bool bFPRenderTargetsSupported : 1; ///< floating point render targets are + ///supported + bool bConstantBufferSupported : 1; ///< Constant (uniform) buffers are supported + bool bMsTextureSupported : 1; ///< Multisample textures are esupported + bool bFastBlitsSupported : 1; ///< The hardware supports fast memor blits + bool bTessellationSupported : 1; ///< Hardware supports tessellation + bool bComputeSupported : 1; ///< Hardware supports compute shader + bool bGeometrySupported : 1; ///< Hardware supports geometry shader + bool bTimerQuerySupported : 1; ///< Hardware supports timer queries + bool bProgramInterfaceSupported : 1; ///< API supports program interface queries + bool bStorageBufferSupported : 1; ///< Shader storage buffers are supported + bool bAtomicCounterBufferSupported : 1; ///< Atomic counter buffers are + /// supported + bool bShaderImageLoadStoreSupported : 1; ///< Shader image load / store + ///operations are supported + bool bProgramPipelineSupported : 1; ///< Driver supports separate programs + bool bNVPathRenderingSupported : 1; ///< Driver NV path rendering + bool bNVAdvancedBlendSupported : 1; ///< Advanced blend modes supported + bool bNVBlendCoherenceSupported : 1; ///< Advanced blend done coherently + ///supported + bool bGPUShader5ExtensionSupported : 1; + bool bKHRAdvancedBlendSupported : 1; ///< Advanced blend modes supported + bool bKHRBlendCoherenceSupported : 1; ///< Advanced blend done coherently + bool bVertexArrayObjectSupported : 1; + bool bStandardDerivativesSupported : 1; + bool bTextureLodSupported : 1; + } bits; + + QT3DSU32 u32Values; + } caps; + } NVRenderBackendSupportBits; + + NVRenderBackendSupportBits m_backendSupport; ///< holds the backend support bits + }; +} +} + +#endif diff --git a/src/render/backends/gl/Q3DSRenderBackendGLES2.cpp b/src/render/backends/gl/Q3DSRenderBackendGLES2.cpp new file mode 100644 index 0000000..ac5b992 --- /dev/null +++ b/src/render/backends/gl/Q3DSRenderBackendGLES2.cpp @@ -0,0 +1,902 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Q3DSRenderBackendGLES2.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#include + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_MULTISAMPLE_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTENSION_FUNCTION(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_TIMER_EXT(x) +#define GL_CALL_TESSELATION_EXT(x) +#define GL_CALL_MULTISAMPLE_EXT(x) +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTENSION_FUNCTION(x) +#endif + +#ifndef GL_DEPTH_STENCIL_OES +#define GL_DEPTH_STENCIL_OES 0x84F9 +#endif + +namespace qt3ds { +namespace render { + +/// constructor +NVRenderBackendGLES2Impl::NVRenderBackendGLES2Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGLBase(fnd, stringTable, format) +{ + QString exts3tc = QStringLiteral("GL_EXT_texture_compression_s3tc"); + QString extsdxt = QStringLiteral("GL_EXT_texture_compression_dxt1"); + QString extsAniso = QStringLiteral("GL_EXT_texture_filter_anisotropic"); + QString extsTexSwizzle = QStringLiteral("GL_ARB_texture_swizzle"); + QString extsFPRenderTarget = QStringLiteral("GL_EXT_color_buffer_float"); + QString extsTimerQuery = QStringLiteral("GL_EXT_timer_query"); + QString extsGpuShader5 = QStringLiteral("EXT_gpu_shader5"); + QString extDepthTexture = QStringLiteral("GL_OES_packed_depth_stencil"); + QString extvao = QStringLiteral("GL_OES_vertex_array_object"); + QString extStdDd = QStringLiteral("GL_OES_standard_derivatives"); + QString extTexLod = QStringLiteral("GL_EXT_shader_texture_lod"); + + const char *languageVersion = GetShadingLanguageVersion(); + qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + eastl::string apiVendor(getVendorString()); + qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); + + eastl::string apiRenderer(getRendererString()); + qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); + + // clear support bits + m_backendSupport.caps.u32Values = 0; + + const char *extensions = getExtensionString(); + m_extensions = QString::fromLocal8Bit(extensions).split(" "); + + // get extension count + GLint numExtensions = m_extensions.size(); + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + + const QString &extensionString = m_extensions.at(i); + + // search for extension + if (!m_backendSupport.caps.bits.bDXTImagesSupported + && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { + m_backendSupport.caps.bits.bDXTImagesSupported = true; + } else if (!m_backendSupport.caps.bits.bAnistropySupported + && extsAniso.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAnistropySupported = true; + } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported + && extsFPRenderTarget.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + } else if (!m_backendSupport.caps.bits.bTimerQuerySupported + && extsTimerQuery.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported + && extsGpuShader5.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; + } else if (!m_backendSupport.caps.bits.bTextureSwizzleSupported + && extsTexSwizzle.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTextureSwizzleSupported = true; + } else if (!m_backendSupport.caps.bits.bDepthStencilSupported + && extDepthTexture.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bDepthStencilSupported = true; + } else if (!m_backendSupport.caps.bits.bVertexArrayObjectSupported + && extvao.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; + } else if (!m_backendSupport.caps.bits.bStandardDerivativesSupported + && extStdDd.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bStandardDerivativesSupported = true; + } else if (!m_backendSupport.caps.bits.bTextureLodSupported + && extTexLod.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTextureLodSupported = true; + } + } + + qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensions); + + // constant buffers support is always not true + m_backendSupport.caps.bits.bConstantBufferSupported = false; + + // query hardware + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); + + // internal state tracker + m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); + + // finally setup caps based on device + setAndInspectHardwareCaps(); + + // Initialize extensions +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#endif +} +/// destructor +NVRenderBackendGLES2Impl::~NVRenderBackendGLES2Impl() +{ + if (m_pCurrentMiscState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + if (m_qt3dsExtensions) + delete m_qt3dsExtensions; +#endif +} + +void NVRenderBackendGLES2Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(samples); + NVRENDER_BACKEND_UNUSED(internalFormat); + NVRENDER_BACKEND_UNUSED(width); + NVRENDER_BACKEND_UNUSED(height); + NVRENDER_BACKEND_UNUSED(fixedsamplelocations); +} + +void NVRenderBackendGLES2Impl::SetTextureData3D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, + QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + } + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + } + + GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, + (GLsizei)height, (GLsizei)depth, border, glformat, + gltype, hostPtr)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLES2Impl::SetTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + glInternalFormat = glformat; + } + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + if (format == NVRenderTextureFormats::Depth24Stencil8) { + glformat = GL_DEPTH_STENCIL_OES; + gltype = GL_UNSIGNED_INT_24_8; + } + glInternalFormat = glformat; + } + + Q_ASSERT(glformat == glInternalFormat); + GL_CALL_EXTRA_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, + (GLsizei)height, border, glformat, gltype, hostPtr)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLES2Impl::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) +{ + + // Satisfy the compiler + // These are not available in GLES 3 and we don't use them right now + QT3DS_ASSERT(lodBias == 0.0); + QT3DS_ASSERT(!borderColor); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(borderColor); + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + anisotropy)); + } +} + +void NVRenderBackendGLES2Impl::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) +{ + NVRENDER_BACKEND_UNUSED(to); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); +} + +void NVRenderBackendGLES2Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(swizzleMode); +#if defined(QT_OPENGL_ES) + if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { + GLint glSwizzle[4]; + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); + + // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); + + } +#endif +} + +QT3DSU32 +NVRenderBackendGLES2Impl::GetDepthBits() const +{ + QT3DSI32 depthBits; + GL_CALL_EXTRA_FUNCTION( + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); + + return depthBits; +} + +QT3DSU32 +NVRenderBackendGLES2Impl::GetStencilBits() const +{ + QT3DSI32 stencilBits; + GL_CALL_EXTRA_FUNCTION( + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilBits)); + + return stencilBits; +} + +void NVRenderBackendGLES2Impl::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum /*genType*/) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +bool NVRenderBackendGLES2Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) +{ + if (iao == nullptr) { + // unbind and return; + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(0)); + return true; + } + + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + NVDataRef shaderAttribBuffer; + if (pProgram->m_shaderInput) + shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; + + if ((attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) + || (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot)) { + return false; + } + + if (inputAssembler->m_VaoID == 0) { + // generate vao + GL_CALL_EXTENSION_FUNCTION(glGenVertexArraysOES(1, &inputAssembler->m_VaoID)); + QT3DS_ASSERT(inputAssembler->m_VaoID); + } + + if (inputAssembler->m_cachedShaderHandle != programID) { + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); + inputAssembler->m_cachedShaderHandle = programID; + + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents) { + qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + return false; + } else { + entryData.m_AttribIndex = attrib.m_AttribLocation; + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + + // disable max possible used first + // this is currently sufficient since we always re-arrange input attributes from 0 + for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); + + // setup all attribs + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); + if (entry) { + const NVRenderBackendLayoutEntryGL &entryData(*entry); + GLuint id = HandleToID_cast( + GLuint, size_t, + inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); + GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); + GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; + GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; + GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( + entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, + stride, (const void *)(entryData.m_Offset + offset))); + + } else { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); + } + } + + // setup index buffer. + if (inputAssembler->m_IndexbufferHandle) { + GL_CALL_EXTRA_FUNCTION(glBindBuffer( + GL_ELEMENT_ARRAY_BUFFER, + HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); + } else { + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + } else { + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); + } +#ifdef _DEBUG + if (inputAssembler->m_VaoID) { + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents + || entryData.m_AttribIndex != attrib.m_AttribLocation) { + qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + } +#endif // _DEBUG + + return true; +} + +void NVRenderBackendGLES2Impl::ReleaseInputAssembler( + NVRenderBackend::NVRenderBackendInputAssemblerObject iao) +{ + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + if (inputAssembler->m_VaoID) + GL_CALL_EXTENSION_FUNCTION(glDeleteVertexArraysOES(1, &inputAssembler->m_VaoID)); + NVDelete(m_Foundation.getAllocator(), inputAssembler); +} + +void NVRenderBackendGLES2Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) +{ + NVRENDER_BACKEND_UNUSED(rto); + + m_DrawBuffersArray.clear(); + + for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { + if (inDrawBufferSet[idx] < 0) + m_DrawBuffersArray.push_back(GL_NONE); + else + m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); + } + + GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), + m_DrawBuffersArray.data())); +} + +void NVRenderBackendGLES2Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) +{ + NVRENDER_BACKEND_UNUSED(rto); + NVRENDER_BACKEND_UNUSED(inReadFace); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) +{ + NVRENDER_BACKEND_UNUSED(attachment); + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(level); + NVRENDER_BACKEND_UNUSED(layer); + Q_ASSERT(false); +} + +void NVRenderBackendGLES2Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, + QT3DSI32 srcY1, QT3DSI32 dstX0, QT3DSI32 dstY0, + QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) +{ + GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, + dstY1, + m_Conversion.fromClearFlagsToGL(flags), + m_Conversion.fromTextureMagnifyingOpToGL(filter))); +} + + +NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLES2Impl::CreateRenderTarget() +{ + GLuint fboID = 0; + GL_CALL_EXTRA_FUNCTION(glGenFramebuffers(1, &fboID)); + return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; +} + +void NVRenderBackendGLES2Impl::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + if (fboID) + GL_CALL_EXTRA_FUNCTION(glDeleteFramebuffers(1, &fboID)); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) +{ + // rto must be the current render target + GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_EXTRA_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, + rbID)); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target) +{ + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D + || m_backendSupport.caps.bits.bMsTextureSupported); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + if (attachment == NVRenderFrameBufferAttachments::DepthStencil) { + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + glTarget, texID, 0)); + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + glTarget, texID, 0)); + } else { + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, + 0)); + } +} + +void NVRenderBackendGLES2Impl::SetRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + if (!fboID) + fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject(); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); +} + +void NVRenderBackendGLES2Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + if (!fboID) + fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject(); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); +} + +bool NVRenderBackendGLES2Impl::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) +{ + GLenum completeStatus = GL_CALL_EXTRA_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); + switch (completeStatus) { +#define HANDLE_INCOMPLETE_STATUS(x) \ + case x: \ + qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ + return false; + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) + #undef HANDLE_INCOMPLETE_STATUS + } + return true; +} + +NVRenderBackend::NVRenderBackendRenderbufferObject +NVRenderBackendGLES2Impl::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + GLuint bufID = 0; + + GL_CALL_EXTRA_FUNCTION(glGenRenderbuffers(1, &bufID)); + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + bufID = 0; + } + + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; +} + +void NVRenderBackendGLES2Impl::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + if (bufID) + GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); +} + +bool NVRenderBackendGLES2Impl::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + bool success = true; + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + QT3DS_ASSERT(bufID); + + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + success = false; + } + + return success; +} + +void *NVRenderBackendGLES2Impl::MapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t length, NVRenderBufferAccessFlags accessFlags) +{ + void *ret = nullptr; + ret = GL_CALL_EXTRA_FUNCTION( + glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, + length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); + + return ret; +} + +bool NVRenderBackendGLES2Impl::UnmapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags) +{ + GLboolean ret; + + ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); + + return (ret) ? true : false; +} + +QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) +{ + QT3DS_ASSERT(po); + GLint numUniformBuffers = 0; + if (GetRenderBackendCap(NVRenderBackendCaps::ConstantBuffer)) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, + &numUniformBuffers)); + } + return numUniformBuffers; +} + +QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferInfoByID( + NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + GLuint blockIndex = GL_INVALID_INDEX; + + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, + nameBuf)); + + if (*length > 0) { + blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); + if (blockIndex != GL_INVALID_INDEX) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); + } + } + + return blockIndex; +} + +void NVRenderBackendGLES2Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (indices) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + indices)); + } +} + +void NVRenderBackendGLES2Impl::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(count); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (count && indices) { + if (type) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, + GL_UNIFORM_TYPE, type)); + // convert to UIC types + QT3DS_FOREACH(idx, count) + { + type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); + } + } + if (size) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, + GL_UNIFORM_SIZE, size)); + } + if (offset) { + GL_CALL_EXTRA_FUNCTION( + glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); + } + } +} + +void NVRenderBackendGLES2Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); +} + +void NVRenderBackendGLES2Impl::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) +{ + QT3DS_ASSERT(bo); + + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); +} + +NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLES2Impl::CreateQuery() +{ + QT3DSU32 glQueryID = 0; + + return (NVRenderBackendQueryObject)glQueryID; +} + +void NVRenderBackendGLES2Impl::ReleaseQuery(NVRenderBackendQueryObject) +{ + +} + +void NVRenderBackendGLES2Impl::BeginQuery(NVRenderBackendQueryObject, + NVRenderQueryType::Enum) +{ + +} + +void NVRenderBackendGLES2Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) +{ + +} + +void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, + QT3DSU32 *) +{ + +} + +void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, + QT3DSU64 *) +{ + +} + +void NVRenderBackendGLES2Impl::SetQueryTimer(NVRenderBackendQueryObject) +{ + +} + +NVRenderBackend::NVRenderBackendSyncObject +NVRenderBackendGLES2Impl::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) +{ + GLsync syncID = 0; + return NVRenderBackendSyncObject(syncID); +} + +void NVRenderBackendGLES2Impl::ReleaseSync(NVRenderBackendSyncObject) +{ + +} + +void NVRenderBackendGLES2Impl::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, + QT3DSU64) +{ + +} +} +} diff --git a/src/render/backends/gl/Q3DSRenderBackendGLES2.h b/src/render/backends/gl/Q3DSRenderBackendGLES2.h new file mode 100644 index 0000000..2c7a355 --- /dev/null +++ b/src/render/backends/gl/Q3DSRenderBackendGLES2.h @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_BACKEND_GLES2_H +#define QT3DS_RENDER_BACKEND_GLES2_H + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +#include +#include + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendMiscStateGL; + + using namespace foundation; + + class NVRenderBackendGLES2Impl : public NVRenderBackendGLBase + { + public: + /// constructor + NVRenderBackendGLES2Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGLES2Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = nullptr) override; + + void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = nullptr) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0f, QT3DSF32 maxLod = 1000.0f, QT3DSF32 lodBias = 0.0f, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0f, QT3DSF32 *borderColor = nullptr) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override; + + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) override; + + void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) override; + void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) override; + + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + + NVRenderBackendRenderTargetObject CreateRenderTarget() override; + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target + = NVRenderTextureTargetType::Texture2D) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) override; + void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; + + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) override; + void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) override; + + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, + QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + protected: + NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; +#endif + }; +} +} + +#endif diff --git a/src/render/backends/gl/Qt3DSOpenGLExtensions.cpp b/src/render/backends/gl/Qt3DSOpenGLExtensions.cpp new file mode 100644 index 0000000..564ecd5 --- /dev/null +++ b/src/render/backends/gl/Qt3DSOpenGLExtensions.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +Qt3DSOpenGLExtensions::Qt3DSOpenGLExtensions() + : QAbstractOpenGLExtension(*(new Qt3DSOpenGLExtensionsPrivate)) +{ +} + +bool Qt3DSOpenGLExtensions::initializeOpenGLFunctions() +{ + if (isInitialized()) + return true; + + QT_PREPEND_NAMESPACE(QOpenGLContext) *context = + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); + if (!context) { + qWarning("A current OpenGL context is required to resolve functions"); + return false; + } + + Q_D(Qt3DSOpenGLExtensions); + + d->BlendBarrierNV = reinterpret_cast( + context->getProcAddress("glBlendBarrierNV")); + d->PathGlyphIndexArrayNV = reinterpret_cast( + context->getProcAddress("glPathGlyphIndexArrayNV")); + d->PathGlyphIndexRangeNV = reinterpret_cast( + context->getProcAddress("glPathGlyphIndexRangeNV")); + QAbstractOpenGLExtension::initializeOpenGLFunctions(); + return true; +} + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +Qt3DSOpenGLES2Extensions::Qt3DSOpenGLES2Extensions() +{ +} + +bool Qt3DSOpenGLES2Extensions::initializeOpenGLFunctions() +{ + if (isInitialized()) + return true; + + QT_PREPEND_NAMESPACE(QOpenGLContext) *context = + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); + if (!context) { + qWarning("A current OpenGL context is required to resolve functions"); + return false; + } + + Q_D(Qt3DSOpenGLExtensions); + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + d->PatchParameteriEXT = reinterpret_cast( + context->getProcAddress("glPatchParameteriEXT")); + d->QueryCounterEXT = reinterpret_cast( + context->getProcAddress("glQueryCounterEXT")); + d->GetQueryObjectui64vEXT = reinterpret_cast( + context->getProcAddress("glGetQueryObjectui64vEXT")); + d->GenPathsNV = reinterpret_cast( + context->getProcAddress("glGenPathsNV")); + d->DeletePathsNV = reinterpret_cast( + context->getProcAddress("glDeletePathsNV")); + d->PathCommandsNV = reinterpret_cast( + context->getProcAddress("glPathCommandsNV")); + d->PathGlyphsNV = reinterpret_cast( + context->getProcAddress("glPathGlyphsNV")); + d->PathGlyphRangeNV = reinterpret_cast( + context->getProcAddress("glPathGlyphRangeNV")); + d->PathParameterfNV = reinterpret_cast( + context->getProcAddress("glPathParameterfNV")); + d->PathStencilDepthOffsetNV = reinterpret_cast( + context->getProcAddress("glPathStencilDepthOffsetNV")); + d->StencilFillPathNV = reinterpret_cast( + context->getProcAddress("glStencilFillPathNV")); + d->StencilStrokePathNV = reinterpret_cast( + context->getProcAddress("glStencilStrokePathNV")); + d->StencilFillPathInstancedNV = reinterpret_cast( + context->getProcAddress("glStencilFillPathInstancedNV")); + d->StencilStrokePathInstancedNV + = reinterpret_cast( + context->getProcAddress("glStencilStrokePathInstancedNV")); + d->PathCoverDepthFuncNV = reinterpret_cast( + context->getProcAddress("glPathCoverDepthFuncNV")); + d->CoverFillPathInstancedNV = reinterpret_cast( + context->getProcAddress("glCoverFillPathInstancedNV")); + d->CoverStrokePathInstancedNV = reinterpret_cast( + context->getProcAddress("glCoverStrokePathInstancedNV")); + d->GetPathParameterfvNV = reinterpret_cast( + context->getProcAddress("glGetPathParameterfvNV")); + d->GetPathMetricsNV = reinterpret_cast( + context->getProcAddress("glGetPathMetricsNV")); + d->GetPathMetricRangeNV = reinterpret_cast( + context->getProcAddress("glGetPathMetricRangeNV")); + d->GetPathSpacingNV = reinterpret_cast( + context->getProcAddress("glGetPathSpacingNV")); + d->BindVertexArrayOES = reinterpret_cast( + context->getProcAddress("glBindVertexArrayOES")); + d->DeleteVertexArraysOES = reinterpret_cast( + context->getProcAddress("glDeleteVertexArraysOES")); + d->GenVertexArraysOES = reinterpret_cast( + context->getProcAddress("glGenVertexArraysOES")); + d->IsVertexArrayOES = reinterpret_cast( + context->getProcAddress("glIsVertexArrayOES")); +#endif + Qt3DSOpenGLExtensions::initializeOpenGLFunctions(); + return true; +} +#endif // QT_OPENGL_ES diff --git a/src/render/backends/gl/Qt3DSOpenGLExtensions.h b/src/render/backends/gl/Qt3DSOpenGLExtensions.h new file mode 100644 index 0000000..c9ba76a --- /dev/null +++ b/src/render/backends/gl/Qt3DSOpenGLExtensions.h @@ -0,0 +1,392 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLEXTENSIONS_H +#define QT3DSOPENGLEXTENSIONS_H + +#include + +/* Some OpenGL extensions that are not (yet) found in Qt's OpenGL extensions. + * These should be auto-generated and added to QtOpenGLExtensions module */ +class Qt3DSOpenGLExtensionsPrivate : public QAbstractOpenGLExtensionPrivate +{ +public: + void (QOPENGLF_APIENTRYP BlendBarrierNV)(); + GLenum (QOPENGLF_APIENTRYP PathGlyphIndexArrayNV)( + GLuint, GLenum, const void*, GLbitfield, GLuint, GLsizei, GLuint, + GLfloat); + GLenum (QOPENGLF_APIENTRYP PathGlyphIndexRangeNV)( + GLenum, const void*, GLbitfield, GLuint, GLfloat, GLuint[2]); + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + void (QOPENGLF_APIENTRYP PatchParameteriEXT)(GLenum, GLint); + void (QOPENGLF_APIENTRYP QueryCounterEXT)(GLuint, GLenum); + void (QOPENGLF_APIENTRYP GetQueryObjectui64vEXT)(GLuint, GLenum, + GLuint64 *); + GLuint (QOPENGLF_APIENTRYP GenPathsNV)(GLsizei); + void (QOPENGLF_APIENTRYP DeletePathsNV)(GLuint, GLsizei); + void (QOPENGLF_APIENTRYP PathCommandsNV)(GLuint, GLsizei, const GLubyte *, + GLsizei, GLenum, const void *); + void (QOPENGLF_APIENTRYP PathGlyphsNV)(GLuint, GLenum, const void *, + GLbitfield, GLsizei, GLenum, const void *, GLenum, GLuint, GLfloat); + void (QOPENGLF_APIENTRYP PathGlyphRangeNV)(GLuint, GLenum, const void *, + GLbitfield, GLuint, GLsizei, GLenum, GLuint, GLfloat); + void (QOPENGLF_APIENTRYP PathParameterfNV)(GLuint, GLenum, GLfloat); + void (QOPENGLF_APIENTRYP PathStencilDepthOffsetNV)(GLfloat, GLfloat); + void (QOPENGLF_APIENTRYP StencilFillPathNV)(GLuint, GLenum, GLuint); + void (QOPENGLF_APIENTRYP StencilStrokePathNV)(GLuint, GLint, GLuint); + void (QOPENGLF_APIENTRYP StencilFillPathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLuint, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP StencilStrokePathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLint, GLuint, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP PathCoverDepthFuncNV)(GLenum); + void (QOPENGLF_APIENTRYP CoverFillPathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP CoverStrokePathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP GetPathParameterfvNV)(GLuint, GLenum, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathMetricsNV)(GLbitfield, GLsizei, GLenum, + const void *, GLuint, GLsizei, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathMetricRangeNV)(GLbitfield, GLuint, GLsizei, + GLsizei, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathSpacingNV)(GLenum, GLsizei, GLenum, + const void *, GLuint, GLfloat, GLfloat, GLenum, GLfloat *); + void (QOPENGLF_APIENTRYP BindVertexArrayOES) (GLuint array); + void (QOPENGLF_APIENTRYP DeleteVertexArraysOES) (GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP GenVertexArraysOES) (GLsizei n, GLuint *arrays); + GLboolean (QOPENGLF_APIENTRYP IsVertexArrayOES) (GLuint array); +#endif +}; + +class Qt3DSOpenGLExtensions : public QAbstractOpenGLExtension +{ +public: + Qt3DSOpenGLExtensions(); + + bool initializeOpenGLFunctions() override; + + void glBlendBarrierNV(); + GLenum glPathGlyphIndexArrayNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, + GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); + GLenum glPathGlyphIndexRangeNV(GLenum fontTarget, const void *fontName, + GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, + GLuint baseAndCount[2]); + +protected: + Q_DECLARE_PRIVATE(Qt3DSOpenGLExtensions) +}; + +inline void Qt3DSOpenGLExtensions::glBlendBarrierNV() +{ + Q_D(Qt3DSOpenGLExtensions); + d->BlendBarrierNV(); +} + +inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexArrayNV( + GLuint firstPathName, GLenum fontTarget, const void *fontName, + GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, + GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->PathGlyphIndexArrayNV(firstPathName, fontTarget, fontName, + fontStyle, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale); +} + +inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexRangeNV(GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, + GLfloat emScale, GLuint baseAndCount[2]) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->PathGlyphIndexRangeNV(fontTarget, fontName, fontStyle, + pathParameterTemplate, emScale, baseAndCount); +} + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +class Qt3DSOpenGLES2Extensions : public Qt3DSOpenGLExtensions +{ +public: + Qt3DSOpenGLES2Extensions(); + + // tesselation shader + void glPatchParameteriEXT(GLenum pname, GLint value); + + // timer + void glQueryCounterEXT(GLuint id, GLenum target); + void glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params); + + // nv paths + + GLuint glGenPathsNV(GLsizei range); + void glDeletePathsNV(GLuint path, GLsizei range); + void glPathCommandsNV(GLuint path, GLsizei numCommands, + const GLubyte *commands, GLsizei numCoords, GLenum coordType, + const void *coords); + void glPathGlyphsNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, + GLenum type, const void *charcodes, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale); + void glPathGlyphRangeNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, + GLsizei numGlyphs, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale); + void glPathParameterfNV(GLuint path, GLenum pname, GLfloat value); + void glPathStencilDepthOffsetNV(GLfloat factor, GLfloat units); + void glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask); + void glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask); + void glStencilFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, + GLenum transformType, const GLfloat *transformValues); + void glStencilStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLint reference, GLuint mask, + GLenum transformType, const GLfloat *transformValues); + void glPathCoverDepthFuncNV(GLenum func); + void glCoverFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum coverMode, + GLenum transformType, const GLfloat *transformValues); + void glCoverStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum coverMode, + GLenum transformType, const GLfloat *transformValues); + void glGetPathParameterfvNV(GLuint path, GLenum pname, GLfloat *value); + void glGetPathMetricsNV(GLbitfield metricQueryMask, GLsizei numPaths, + GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, + GLfloat *metrics); + void glGetPathMetricRangeNV(GLbitfield metricQueryMask, + GLuint firstPathName, GLsizei numPaths, GLsizei stride, + GLfloat *metrics); + void glGetPathSpacingNV(GLenum pathListMode, GLsizei numPaths, + GLenum pathNameType, const void *paths, GLuint pathBase, + GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, + GLfloat *returnedSpacing); + void glBindVertexArrayOES(GLuint array); + void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays); + void glGenVertexArraysOES(GLsizei n, GLuint *arrays); + GLboolean glIsVertexArrayOES(GLuint array); + + bool initializeOpenGLFunctions() Q_DECL_FINAL; +}; + +inline void Qt3DSOpenGLES2Extensions::glPatchParameteriEXT(GLenum pname, + GLint value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PatchParameteriEXT(pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glQueryCounterEXT(GLuint id, + GLenum target) +{ + Q_D(Qt3DSOpenGLExtensions); + d->QueryCounterEXT(id, target); +} + +inline void Qt3DSOpenGLES2Extensions::glGetQueryObjectui64vEXT(GLuint id, + GLenum pname, GLuint64 *params) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetQueryObjectui64vEXT(id, pname, params); +} + +inline GLuint Qt3DSOpenGLES2Extensions::glGenPathsNV(GLsizei range) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->GenPathsNV(range); +} + +inline void Qt3DSOpenGLES2Extensions::glDeletePathsNV(GLuint path, + GLsizei range) +{ + Q_D(Qt3DSOpenGLExtensions); + d->DeletePathsNV(path, range); +} + +inline void Qt3DSOpenGLES2Extensions::glPathCommandsNV(GLuint path, + GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, + GLenum coordType, const void *coords) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathCommandsNV(path, numCommands, commands, numCoords, coordType, + coords); +} + +inline void Qt3DSOpenGLES2Extensions::glPathGlyphsNV(GLuint firstPathName, + GLenum fontTarget, const void *fontName, GLbitfield fontStyle, + GLsizei numGlyphs, GLenum type, const void *charcodes, + GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathGlyphsNV(firstPathName, fontTarget, fontName, fontStyle, numGlyphs, + type, charcodes, handleMissingGlyphs, pathParameterTemplate, emScale); +} + +inline void Qt3DSOpenGLES2Extensions::glPathGlyphRangeNV(GLuint firstPathName, + GLenum fontTarget, const void *fontName, GLbitfield fontStyle, + GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathGlyphRangeNV(firstPathName, fontTarget, fontName, fontStyle, + firstGlyph, numGlyphs, handleMissingGlyphs, pathParameterTemplate, + emScale); +} + +inline void Qt3DSOpenGLES2Extensions::glPathParameterfNV(GLuint path, + GLenum pname, GLfloat value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathParameterfNV(path, pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glPathStencilDepthOffsetNV(GLfloat factor, + GLfloat units) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathStencilDepthOffsetNV(factor, units); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilFillPathNV(GLuint path, + GLenum fillMode, GLuint mask) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilFillPathNV(path, fillMode, mask); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathNV(GLuint path, + GLint reference, GLuint mask) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilStrokePathNV(path, reference, mask); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilFillPathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum fillMode, GLuint mask, GLenum transformType, + const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, + fillMode, mask, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLint reference, GLuint mask, GLenum transformType, + const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, + reference, mask, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glPathCoverDepthFuncNV(GLenum func) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathCoverDepthFuncNV(func); +} + +inline void Qt3DSOpenGLES2Extensions::glCoverFillPathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum coverMode, GLenum transformType, const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->CoverFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glCoverStrokePathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum coverMode, GLenum transformType, const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->CoverStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathParameterfvNV(GLuint path, + GLenum pname, GLfloat *value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathParameterfvNV(path, pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathMetricsNV( + GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathMetricsNV(metricQueryMask, numPaths, pathNameType, paths, + pathBase, stride, metrics); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathMetricRangeNV( + GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, + GLsizei stride, GLfloat *metrics) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathMetricRangeNV(metricQueryMask, firstPathName, numPaths, stride, + metrics); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathSpacingNV(GLenum pathListMode, + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, + GLfloat *returnedSpacing) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathSpacingNV(pathListMode, numPaths, pathNameType, paths, pathBase, + advanceScale, kerningScale, transformType, returnedSpacing); +} + +inline void Qt3DSOpenGLES2Extensions::glBindVertexArrayOES(GLuint array) +{ + Q_D(Qt3DSOpenGLExtensions); + d->BindVertexArrayOES(array); +} + +inline void Qt3DSOpenGLES2Extensions::glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) +{ + Q_D(Qt3DSOpenGLExtensions); + d->DeleteVertexArraysOES(n, arrays); +} + +inline void Qt3DSOpenGLES2Extensions::glGenVertexArraysOES(GLsizei n, GLuint *arrays) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GenVertexArraysOES(n, arrays); +} + +inline GLboolean Qt3DSOpenGLES2Extensions::glIsVertexArrayOES(GLuint array) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->IsVertexArrayOES(array); +} + +#endif // QT_OPENGL_ES + +#endif // QT3DSOPENGLEXTENSIONS_H diff --git a/src/render/backends/gl/Qt3DSOpenGLPrefix.h b/src/render/backends/gl/Qt3DSOpenGLPrefix.h new file mode 100644 index 0000000..0e6dc6d --- /dev/null +++ b/src/render/backends/gl/Qt3DSOpenGLPrefix.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLPREFIX_H +#define QT3DSOPENGLPREFIX_H + +#include +#if defined(QT_OPENGL_ES) +#define GL_GLEXT_PROTOTYPES +#if defined(QT_OPENGL_ES_3_2) +#include +#else +#include +#include +#endif + +// Adding this to ensure that platform version of gl2ext.h is included +// before Qt's qopengles2ext.h which is missing symbols we need +#include +#endif + +#endif // QT3DSOPENGLPREFIX_H diff --git a/src/render/backends/gl/Qt3DSOpenGLTokens.h b/src/render/backends/gl/Qt3DSOpenGLTokens.h new file mode 100644 index 0000000..882e276 --- /dev/null +++ b/src/render/backends/gl/Qt3DSOpenGLTokens.h @@ -0,0 +1,408 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLTOKENS_H +#define QT3DSOPENGLTOKENS_H + +/** + * This is our general internal to GL type conversion routines + * Add defines which are not in standard GL(ext) header but in GL2(ext) + * The define are the same with different names + * Expectation is the NVIDIA defines (need for compile) + */ +#ifndef GL_NVIDIA_PLATFORM_BINARY_NV +#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B +#endif +#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT +#endif + +#if defined(__APPLE__) || defined(ANDROID) || defined(__INTEGRITY) +#ifndef GL_DEPTH_COMPONENT24 +#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES +#endif +#ifndef GL_DEPTH_COMPONENT32 +#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES +#endif + +/** +_* tessellation_shader defines + */ +#ifndef GL_TESS_EVALUATION_SHADER +#define GL_TESS_EVALUATION_SHADER GL_TESS_EVALUATION_SHADER_EXT +#endif +#ifndef GL_TESS_CONTROL_SHADER +#define GL_TESS_CONTROL_SHADER GL_TESS_CONTROL_SHADER_EXT +#endif +#ifndef GL_PATCHES +#define GL_PATCHES GL_PATCHES_EXT +#endif +#ifndef GL_PATCH_VERTICES +#define GL_PATCH_VERTICES GL_PATCH_VERTICES_EXT +#endif +#ifndef GL_TESS_CONTROL_SHADER_BIT +#define GL_TESS_CONTROL_SHADER_BIT GL_TESS_CONTROL_SHADER_BIT_EXT +#endif +#ifndef GL_TESS_EVALUATION_SHADER_BIT +#define GL_TESS_EVALUATION_SHADER_BIT GL_TESS_EVALUATION_SHADER_BIT_EXT +#endif +#ifndef GL_VERTEX_SHADER_BIT +#define GL_VERTEX_SHADER_BIT GL_VERTEX_SHADER_BIT_EXT +#endif +#ifndef GL_FRAGMENT_SHADER_BIT +#define GL_FRAGMENT_SHADER_BIT GL_FRAGMENT_SHADER_BIT_EXT +#endif +#ifndef GL_GEOMETRY_SHADER_BIT +#define GL_GEOMETRY_SHADER_BIT GL_GEOMETRY_SHADER_BIT_EXT +#endif + + +/** + * sample shading extension + */ +#ifndef GL_SAMPLE_SHADING +#define GL_SAMPLE_SHADING GL_SAMPLE_SHADING_OES +#endif +#ifndef GL_MIN_SAMPLE_SHADING_VALUE +#define GL_MIN_SAMPLE_SHADING_VALUE GL_MIN_SAMPLE_SHADING_VALUE_OES +#endif + +/** + * Timer query extension + */ +#ifndef GL_TIME_ELAPSED +#define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT +#endif +#ifndef GL_TIMESTAMP +#define GL_TIMESTAMP GL_TIMESTAMP_EXT +#endif + +/** + * compute shader + */ +#ifndef GL_IMAGE_2D +#define GL_IMAGE_2D 0x904D +#endif + +/** + * texture formats ( make build happy ) + */ +#ifndef GL_R16 +#define GL_R16 0x822A +#endif + +#endif // __APPLE__ || ANDROID || __INTEGRITY + +#if defined(__APPLE__) || defined(ANDROID) + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_SHADER_STORAGE_BUFFER +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_ATOMIC_COUNTER_BUFFER +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#endif + +#ifndef GL_ALL_BARRIER_BITS +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#endif + +#ifndef GL_SHADER_STORAGE_BARRIER_BIT +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#endif + +#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif + + + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_2_BYTES_NV 0x1407 +#define GL_3_BYTES_NV 0x1408 +#define GL_4_BYTES_NV 0x1409 +#define GL_EYE_LINEAR_NV 0x2400 +#define GL_OBJECT_LINEAR_NV 0x2401 +#define GL_CONSTANT_NV 0x8576 +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_FRAGMENT_INPUT_NV 0x936D +#endif /* GL_NV_path_rendering */ + +#ifndef GL_SHADER_STORAGE_BLOCK +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#endif + +#ifndef GL_ACTIVE_RESOURCES +#define GL_ACTIVE_RESOURCES 0x92F5 +#endif + +#ifndef GL_BUFFER_BINDING +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#endif + +#ifndef GL_UNIFORM +#define GL_UNIFORM 0x92E1 +#endif + +#ifndef GL_COMPUTE_SHADER +#define GL_COMPUTE_SHADER 0x91B9 +#endif + +#endif // __APPLE__ || ANDROID + +#endif // QT3DSOPENGLTOKENS_H diff --git a/src/render/backends/gl/Qt3DSOpenGLUtil.h b/src/render/backends/gl/Qt3DSOpenGLUtil.h new file mode 100644 index 0000000..32f7dad --- /dev/null +++ b/src/render/backends/gl/Qt3DSOpenGLUtil.h @@ -0,0 +1,2201 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLUTIL_H +#define QT3DSOPENGLUTIL_H + +#include "render/backends/gl/Qt3DSOpenGLPrefix.h" +#include "render/backends/gl/Qt3DSOpenGLTokens.h" +#include +#include + +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSVec4.h" +#include "foundation/Qt3DSFoundation.h" + +// The actual binding to the hardware the does some minor conversions between gles and +// the nv render enumeration types +namespace qt3ds { +namespace render { + +#ifndef GL_TEXTURE_2D_MULTISAMPLE +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#endif + +#ifndef GL_IMAGE_2D +#define GL_IMAGE_2D 0x904D +#endif + +#ifndef GL_MULTISAMPLE_EXT +#define GL_MULTISAMPLE_EXT 0x809D +#endif + +#ifndef GL_COLOR_ATTACHMENT1 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#endif + +#ifndef GL_RED +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#endif + +#ifndef GL_PATCHES +#define GL_PATCHES 0x000E +#endif + +#ifndef GL_READ_ONLY +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_ATOMIC_COUNTER_BUFFER +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#endif + +#ifndef GL_DRAW_INDIRECT_BUFFER +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#endif + +#ifndef GL_VERTEX_SHADER_BIT +#define GL_VERTEX_SHADER_BIT 0x00000001 +#endif + +#ifndef GL_FRAGMENT_SHADER_BIT +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#endif + +#ifndef GL_GEOMETRY_SHADER_BIT +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#endif + +#ifndef GL_TESS_CONTROL_SHADER_BIT +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#endif + +#ifndef GL_TESS_EVALUATION_SHADER_BIT +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#endif + +#ifndef GL_ETC1_RGB8_OES +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +#ifndef GL_COMPRESSED_RED_RGTC1 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#endif + +#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#endif + +#ifndef GL_COMPRESSED_RG_RGTC2 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#endif + +#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM_ARB +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#endif + +#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#endif + +#ifndef GL_COMPRESSED_RGB8_ETC2 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ETC2 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#endif + +#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#endif + +#ifndef GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#endif + +#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#endif + +#ifndef GL_COMPRESSED_R11_EAC +#define GL_COMPRESSED_R11_EAC 0x9270 +#endif + +#ifndef GL_COMPRESSED_SIGNED_R11_EAC +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#endif + +#ifndef GL_COMPRESSED_RG11_EAC +#define GL_COMPRESSED_RG11_EAC 0x9272 +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG11_EAC +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#endif + +#define QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ZERO, Zero) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE, One) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_COLOR, SrcColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_COLOR, OneMinusSrcColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_COLOR, DstColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_COLOR, OneMinusDstColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_ALPHA, SrcAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_ALPHA, OneMinusSrcAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_ALPHA, DstAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_ALPHA, OneMinusDstAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_COLOR, ConstantColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_COLOR, OneMinusConstantColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_ALPHA, ConstantAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_ALPHA, OneMinusConstantAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(GL_SRC_ALPHA_SATURATE, SrcAlphaSaturate) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT, Front) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_BACK, Back) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT_AND_BACK, FrontAndBack) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CW, Clockwise) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CCW, CounterClockwise) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NEVER, Never) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LESS, Less) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_EQUAL, Equal) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LEQUAL, LessThanOrEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GREATER, Greater) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NOTEQUAL, NotEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GEQUAL, GreaterThanOrEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_ALWAYS, AlwaysTrue) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_HINT \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_FASTEST, Fastest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_NICEST, Nicest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_DONT_CARE, Unspecified) + +#define QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_KEEP, Keep) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_ZERO, Zero) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_REPLACE, Replace) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR, Increment) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR_WRAP, IncrementWrap) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR, Decrement) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR_WRAP, DecrementWrap) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INVERT, Invert) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_BYTE, QT3DSU8) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_BYTE, QT3DSI8) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_SHORT, QT3DSU16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_SHORT, QT3DSI16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_INT, QT3DSU32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(GL_INT, QT3DSI32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_FLOAT, QT3DSF32) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_STATIC_DRAW, Static) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_DYNAMIC_DRAW, Dynamic) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_NEAREST, Nearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_LINEAR, Linear) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_NEAREST, NearestMipmapNearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_NEAREST, LinearMipmapNearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_LINEAR, NearestMipmapLinear) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_LINEAR, LinearMipmapLinear) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_CLAMP_TO_EDGE, ClampToEdge) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_MIRRORED_REPEAT, MirroredRepeat) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_REPEAT, Repeat) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT, QT3DSF32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC2, QT3DSVec2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC3, QT3DSVec3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC4, QT3DSVec4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT, QT3DSI32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC2, QT3DSI32_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC3, QT3DSI32_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC4, QT3DSI32_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL, QT3DSRenderBool) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC2, bool_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC3, bool_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC4, bool_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT, QT3DSU32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC2, QT3DSU32_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC3, QT3DSU32_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC4, QT3DSU32_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT3, QT3DSMat33) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT4, QT3DSMat44) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D, NVRenderTexture2DPtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D_ARRAY, NVRenderTexture2DArrayPtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_CUBE, NVRenderTextureCubePtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_IMAGE_2D, NVRenderImage2DPtr) +// cube Sampler and mat22 unsupported + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT, QT3DSF32, 1) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC2, QT3DSF32, 2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC3, QT3DSF32, 3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC4, QT3DSF32, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT2, QT3DSF32, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT3, QT3DSF32, 9) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT4, QT3DSF32, 16) +#if defined(GL_DEPTH_COMPONENT32) +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT32, Depth32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) +#else +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) +#endif + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color0, 0) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color1, 1) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color2, 2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color3, 3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color4, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color5, 5) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color6, 6) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color7, 7) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_ATTACHMENT, Depth) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_STENCIL_ATTACHMENT, Stencil) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_STENCIL_ATTACHMENT, DepthStencil) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_COLOR_BUFFER_BIT, Color) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_DEPTH_BUFFER_BIT, Depth) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_STENCIL_BUFFER_BIT, Stencil) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS + + static bool IsGlEsContext(NVRenderContextType inContextType) + { + NVRenderContextType esContextTypes(NVRenderContextValues::GLES2 + | NVRenderContextValues::GLES3 + | NVRenderContextValues::GLES3PLUS); + + if ((inContextType & esContextTypes)) + return true; + + return false; + } + + struct GLConversion + { + GLConversion() + { } + + static const char *processGLError(GLenum error) + { + const char *errorString = ""; + switch (error) { +#define stringiseError(error) \ + case error: \ + errorString = #error; \ + break + stringiseError(GL_NO_ERROR); + stringiseError(GL_INVALID_ENUM); + stringiseError(GL_INVALID_VALUE); + stringiseError(GL_INVALID_OPERATION); + stringiseError(GL_INVALID_FRAMEBUFFER_OPERATION); + stringiseError(GL_OUT_OF_MEMORY); +#undef stringiseError + default: + errorString = "Unknown GL error"; + break; + } + return errorString; + } + + static NVRenderSrcBlendFunc::Enum fromGLToSrcBlendFunc(QT3DSI32 value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case srcVal: \ + return NVRenderSrcBlendFunc::enumVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ + case srcVal: \ + return NVRenderSrcBlendFunc::enumVal; + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return NVRenderSrcBlendFunc::Unknown; + } + } + + static GLenum fromSrcBlendFuncToGL(NVRenderSrcBlendFunc::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case NVRenderSrcBlendFunc::enumVal: \ + return srcVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ + case NVRenderSrcBlendFunc::enumVal: \ + return srcVal; + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return 0; + } + } + + static NVRenderDstBlendFunc::Enum fromGLToDstBlendFunc(QT3DSI32 value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case srcVal: \ + return NVRenderDstBlendFunc::enumVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return NVRenderDstBlendFunc::Unknown; + } + } + + static GLenum fromDstBlendFuncToGL(NVRenderDstBlendFunc::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case NVRenderDstBlendFunc::enumVal: \ + return srcVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return 0; + } + } + + static GLenum fromBlendEquationToGL(NVRenderBlendEquation::Enum value, + bool nvAdvancedBlendSupported, + bool khrAdvancedBlendSupported) + { + switch (value) { + case NVRenderBlendEquation::Add: + return GL_FUNC_ADD; + case NVRenderBlendEquation::Subtract: + return GL_FUNC_SUBTRACT; + case NVRenderBlendEquation::ReverseSubtract: + return GL_FUNC_REVERSE_SUBTRACT; + default: + QT3DS_ASSERT(nvAdvancedBlendSupported || khrAdvancedBlendSupported); + break; + } + + if (nvAdvancedBlendSupported) { + switch (value) { + case NVRenderBlendEquation::Overlay: + return GL_OVERLAY_NV; + case NVRenderBlendEquation::ColorBurn: + return GL_COLORBURN_NV; + case NVRenderBlendEquation::ColorDodge: + return GL_COLORDODGE_NV; + default: + break; + } + } + +#if defined(GL_KHR_blend_equation_advanced) + if (khrAdvancedBlendSupported) { + switch (value) { + case NVRenderBlendEquation::Overlay: + return GL_OVERLAY_KHR; + case NVRenderBlendEquation::ColorBurn: + return GL_COLORBURN_KHR; + case NVRenderBlendEquation::ColorDodge: + return GL_COLORDODGE_KHR; + default: + break; + } + } +#endif + + QT3DS_ASSERT(false); + return GL_FUNC_ADD; + } + + static NVRenderFaces::Enum fromGLToFaces(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ + case x: \ + return NVRenderFaces::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderFaces::Unknown; + } + + static GLenum fromFacesToGL(NVRenderFaces::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ + case NVRenderFaces::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVReadFaces::Enum fromGLToReadFaces(GLenum value) + { + switch (value) { + case GL_FRONT: + return NVReadFaces::Front; + case GL_BACK: + return NVReadFaces::Back; + case GL_COLOR_ATTACHMENT0: + return NVReadFaces::Color0; + case GL_COLOR_ATTACHMENT1: + return NVReadFaces::Color1; + case GL_COLOR_ATTACHMENT2: + return NVReadFaces::Color2; + case GL_COLOR_ATTACHMENT3: + return NVReadFaces::Color3; + case GL_COLOR_ATTACHMENT4: + return NVReadFaces::Color4; + case GL_COLOR_ATTACHMENT5: + return NVReadFaces::Color5; + case GL_COLOR_ATTACHMENT6: + return NVReadFaces::Color6; + case GL_COLOR_ATTACHMENT7: + return NVReadFaces::Color7; + + default: + break; + } + QT3DS_ASSERT(false); + return NVReadFaces::Unknown; + } + + static GLenum fromReadFacesToGL(NVReadFaces::Enum value) + { + switch (value) { + case NVReadFaces::Front: + return GL_FRONT; + case NVReadFaces::Back: + return GL_BACK; + case NVReadFaces::Color0: + return GL_COLOR_ATTACHMENT0; + case NVReadFaces::Color1: + return GL_COLOR_ATTACHMENT1; + case NVReadFaces::Color2: + return GL_COLOR_ATTACHMENT2; + case NVReadFaces::Color3: + return GL_COLOR_ATTACHMENT3; + case NVReadFaces::Color4: + return GL_COLOR_ATTACHMENT4; + case NVReadFaces::Color5: + return GL_COLOR_ATTACHMENT5; + case NVReadFaces::Color6: + return GL_COLOR_ATTACHMENT6; + case NVReadFaces::Color7: + return GL_COLOR_ATTACHMENT7; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderWinding::Enum fromGLToWinding(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ + case x: \ + return NVRenderWinding::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderWinding::Unknown; + } + + static GLenum fromWindingToGL(NVRenderWinding::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ + case NVRenderWinding::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderBoolOp::Enum fromGLToBoolOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case x: \ + return NVRenderBoolOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderBoolOp::Unknown; + } + + static GLenum fromBoolOpToGL(NVRenderBoolOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case NVRenderBoolOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderHint::Enum fromGLToHint(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ + case x: \ + return NVRenderHint::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_HINT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderHint::Unknown; + } + + static GLenum fromHintToGL(NVRenderHint::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ + case NVRenderHint::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_HINT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderStencilOp::Enum fromGLToStencilOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ + case x: \ + return NVRenderStencilOp::y; + QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP + default: + break; + } + + QT3DS_ASSERT(false); + return NVRenderStencilOp::Unknown; + } + + static GLenum fromStencilOpToGL(NVRenderStencilOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ + case NVRenderStencilOp::y: \ + return x; + QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP + default: + break; + } + + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderComponentTypes::Enum fromGLToBufferComponentTypes(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ + case x: \ + return NVRenderComponentTypes::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderComponentTypes::Unknown; + } + + static GLenum fromBufferComponentTypesToGL(NVRenderComponentTypes::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ + case NVRenderComponentTypes::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) \ + case NVRenderComponentTypes::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromIndexBufferComponentsTypesToGL(NVRenderComponentTypes::Enum value) + { + switch (value) { + case NVRenderComponentTypes::QT3DSU8: + return GL_UNSIGNED_BYTE; + case NVRenderComponentTypes::QT3DSU16: + return GL_UNSIGNED_SHORT; + case NVRenderComponentTypes::QT3DSU32: + return GL_UNSIGNED_INT; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromBindBufferFlagsToGL(NVRenderBufferBindFlags flags) + { + QT3DSU32 value = flags; + GLenum retval = GL_INVALID_ENUM; + if (value & NVRenderBufferBindValues::Vertex) + retval = GL_ARRAY_BUFFER; + else if (value & NVRenderBufferBindValues::Index) + retval = GL_ELEMENT_ARRAY_BUFFER; + else if (value & NVRenderBufferBindValues::Constant) + retval = GL_UNIFORM_BUFFER; + else if (value & NVRenderBufferBindValues::Storage) + retval = GL_SHADER_STORAGE_BUFFER; + else if (value & NVRenderBufferBindValues::Atomic_Counter) + retval = GL_ATOMIC_COUNTER_BUFFER; + else if (value & NVRenderBufferBindValues::Draw_Indirect) + retval = GL_DRAW_INDIRECT_BUFFER; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderBufferBindFlags fromGLToBindBufferFlags(GLenum value) + { + QT3DSU32 retval = 0; + + if (value == GL_ARRAY_BUFFER) + retval |= NVRenderBufferBindValues::Vertex; + else if (value == GL_ELEMENT_ARRAY_BUFFER) + retval |= NVRenderBufferBindValues::Index; + else if (value == GL_UNIFORM_BUFFER) + retval |= NVRenderBufferBindValues::Constant; + else if (value == GL_SHADER_STORAGE_BUFFER) + retval |= NVRenderBufferBindValues::Storage; + else if (value == GL_ATOMIC_COUNTER_BUFFER) + retval |= NVRenderBufferBindValues::Atomic_Counter; + else if (value == GL_DRAW_INDIRECT_BUFFER) + retval |= NVRenderBufferBindValues::Draw_Indirect; + else + QT3DS_ASSERT(false); + + return NVRenderBufferBindFlags(retval); + } + + static NVRenderBufferUsageType::Enum fromGLToBufferUsageType(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ + case x: \ + return NVRenderBufferUsageType::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderBufferUsageType::Unknown; + } + + static GLenum fromBufferUsageTypeToGL(NVRenderBufferUsageType::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ + case NVRenderBufferUsageType::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromQueryTypeToGL(NVRenderQueryType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderQueryType::Samples) + retval = GL_ANY_SAMPLES_PASSED; +#if defined(GL_TIME_ELAPSED) + else if (type == NVRenderQueryType::Timer) + retval = GL_TIME_ELAPSED; +#elif defined(GL_TIME_ELAPSED_EXT) + else if (type == NVRenderQueryType::Timer) + retval = GL_TIME_ELAPSED_EXT; +#endif + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromQueryResultTypeToGL(NVRenderQueryResultType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderQueryResultType::ResultAvailable) + retval = GL_QUERY_RESULT_AVAILABLE; + else if (type == NVRenderQueryResultType::Result) + retval = GL_QUERY_RESULT; + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromSyncTypeToGL(NVRenderSyncType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderSyncType::GpuCommandsComplete) + retval = GL_SYNC_GPU_COMMANDS_COMPLETE; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderTextureFormats::Enum + replaceDeprecatedTextureFormat(NVRenderContextType type, NVRenderTextureFormats::Enum value, + NVRenderTextureSwizzleMode::Enum &swizzleMode) + { + NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderTextureFormats::Enum newValue = value; + swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + + if (!(type & deprecatedContextFlags)) { + switch (value) { + case NVRenderTextureFormats::Luminance8: + newValue = NVRenderTextureFormats::R8; + swizzleMode = NVRenderTextureSwizzleMode::L8toR8; + break; + case NVRenderTextureFormats::LuminanceAlpha8: + newValue = NVRenderTextureFormats::RG8; + swizzleMode = NVRenderTextureSwizzleMode::L8A8toRG8; + break; + case NVRenderTextureFormats::Alpha8: + newValue = NVRenderTextureFormats::R8; + swizzleMode = NVRenderTextureSwizzleMode::A8toR8; + break; + case NVRenderTextureFormats::Luminance16: + newValue = NVRenderTextureFormats::R16; + swizzleMode = NVRenderTextureSwizzleMode::L16toR16; + break; + default: + break; + } + } + + return newValue; + } + + static void + NVRenderConvertSwizzleModeToGL(const NVRenderTextureSwizzleMode::Enum swizzleMode, + GLint glSwizzle[4]) + { + switch (swizzleMode) { + case NVRenderTextureSwizzleMode::L16toR16: + case NVRenderTextureSwizzleMode::L8toR8: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_RED; + glSwizzle[2] = GL_RED; + glSwizzle[3] = GL_ONE; + break; + case NVRenderTextureSwizzleMode::L8A8toRG8: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_RED; + glSwizzle[2] = GL_RED; + glSwizzle[3] = GL_GREEN; + break; + case NVRenderTextureSwizzleMode::A8toR8: + glSwizzle[0] = GL_ZERO; + glSwizzle[1] = GL_ZERO; + glSwizzle[2] = GL_ZERO; + glSwizzle[3] = GL_RED; + break; + case NVRenderTextureSwizzleMode::NoSwizzle: + default: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_GREEN; + glSwizzle[2] = GL_BLUE; + glSwizzle[3] = GL_ALPHA; + break; + } + } + + static bool fromUncompressedTextureFormatToGL(NVRenderContextType type, + NVRenderTextureFormats::Enum value, + GLenum &outFormat, GLenum &outDataType, + GLenum &outInternalFormat) + { + switch (value) { + case NVRenderTextureFormats::R8: + if (type == NVRenderContextValues::GLES2) { + outFormat = GL_ALPHA; + outInternalFormat = GL_ALPHA; + } else { + outFormat = GL_RED; + outInternalFormat = GL_R8; + } + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RG8: + outFormat = GL_RG; + outInternalFormat = GL_RG8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGBA8: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGB8: + outFormat = GL_RGB; + outInternalFormat = GL_RGB8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGB565: + outFormat = GL_RGB; + outInternalFormat = GL_RGB8; + outDataType = GL_UNSIGNED_SHORT_5_6_5; + return true; + case NVRenderTextureFormats::RGBA5551: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA8; + outDataType = GL_UNSIGNED_SHORT_5_5_5_1; + return true; + case NVRenderTextureFormats::Alpha8: + outFormat = GL_ALPHA; + outInternalFormat = GL_ALPHA; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::Luminance8: + outFormat = GL_LUMINANCE; + outInternalFormat = GL_LUMINANCE; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::LuminanceAlpha8: + outFormat = GL_LUMINANCE_ALPHA; + outInternalFormat = GL_LUMINANCE_ALPHA; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::Luminance16: +#if defined(QT_OPENGL_ES) + outFormat = GL_LUMINANCE16F_EXT; + outInternalFormat = GL_LUMINANCE16F_EXT; +#else + outFormat = GL_LUMINANCE; + outInternalFormat = GL_LUMINANCE; +#endif + outDataType = GL_UNSIGNED_INT; + return true; + default: + break; + } + + NVRenderContextType contextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + // check extented texture formats + if (!(type & contextFlags)) { + switch (value) { +#if !defined(QT_OPENGL_ES) + case NVRenderTextureFormats::R16: { + if (IsGlEsContext(type)) { + outFormat = GL_RED_INTEGER; + outInternalFormat = GL_R16UI; + } else { + outFormat = GL_RED; + outInternalFormat = GL_R16; + } + outDataType = GL_UNSIGNED_SHORT; + return true; + } +#endif + case NVRenderTextureFormats::R16F: + outFormat = GL_RED; + outInternalFormat = GL_R16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::R32UI: + outFormat = GL_RED_INTEGER; + outInternalFormat = GL_R32UI; + outDataType = GL_UNSIGNED_INT; + return true; + case NVRenderTextureFormats::R32F: + outFormat = GL_RED; + outInternalFormat = GL_R32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGBA16F: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::RG16F: + outFormat = GL_RG; + outInternalFormat = GL_RG16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::RG32F: + outFormat = GL_RG; + outInternalFormat = GL_RG32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGBA32F: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGB32F: + outFormat = GL_RGB; + outInternalFormat = GL_RGB32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::R11G11B10: + outFormat = GL_RGB; + outInternalFormat = GL_R11F_G11F_B10F; + outDataType = GL_UNSIGNED_INT_10F_11F_11F_REV; + return true; + case NVRenderTextureFormats::RGB9E5: + outFormat = GL_RGB; + outInternalFormat = GL_RGB9_E5; + outDataType = GL_UNSIGNED_INT_5_9_9_9_REV; + return true; + case NVRenderTextureFormats::SRGB8: + outFormat = GL_RGB; + outInternalFormat = GL_SRGB8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::SRGB8A8: + outFormat = GL_RGBA; + outInternalFormat = GL_SRGB8_ALPHA8; + outDataType = GL_UNSIGNED_BYTE; + return true; + default: + break; + } + } + + QT3DS_ASSERT(false); + return false; + } + + static GLenum fromCompressedTextureFormatToGL(NVRenderTextureFormats::Enum value) + { + switch (value) { + case NVRenderTextureFormats::RGBA_DXT1: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case NVRenderTextureFormats::RGB_DXT1: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case NVRenderTextureFormats::RGBA_DXT3: + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case NVRenderTextureFormats::RGBA_DXT5: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case NVRenderTextureFormats::R_ATI1N_UNorm: + return GL_COMPRESSED_RED_RGTC1; + case NVRenderTextureFormats::R_ATI1N_SNorm: + return GL_COMPRESSED_SIGNED_RED_RGTC1; + case NVRenderTextureFormats::RG_ATI2N_UNorm: + return GL_COMPRESSED_RG_RGTC2; + case NVRenderTextureFormats::RG_ATI2N_SNorm: + return GL_COMPRESSED_SIGNED_RG_RGTC2; + case NVRenderTextureFormats::RGB_BP_UNSIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_SIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_UNorm: + return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + case NVRenderTextureFormats::R11_EAC_UNorm: + return GL_COMPRESSED_R11_EAC; + case NVRenderTextureFormats::R11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_R11_EAC; + case NVRenderTextureFormats::RG11_EAC_UNorm: + return GL_COMPRESSED_RG11_EAC; + case NVRenderTextureFormats::RG11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_RG11_EAC; + case NVRenderTextureFormats::RGB8_ETC2: + return GL_COMPRESSED_RGB8_ETC2; + case NVRenderTextureFormats::SRGB8_ETC2: + return GL_COMPRESSED_SRGB8_ETC2; + case NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::RGBA8_ETC2_EAC: + return GL_COMPRESSED_RGBA8_ETC2_EAC; + case NVRenderTextureFormats::SRGB8_Alpha8_ETC2_EAC: + return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + case NVRenderTextureFormats::RGB8_ETC1: + return GL_ETC1_RGB8_OES; +#ifdef GL_KHR_texture_compression_astc_hdr + case NVRenderTextureFormats::RGBA_ASTC_4x4: + return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x4: + return GL_COMPRESSED_RGBA_ASTC_5x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x5: + return GL_COMPRESSED_RGBA_ASTC_5x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x5: + return GL_COMPRESSED_RGBA_ASTC_6x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x6: + return GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x5: + return GL_COMPRESSED_RGBA_ASTC_8x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x6: + return GL_COMPRESSED_RGBA_ASTC_8x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x8: + return GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x5: + return GL_COMPRESSED_RGBA_ASTC_10x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x6: + return GL_COMPRESSED_RGBA_ASTC_10x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x8: + return GL_COMPRESSED_RGBA_ASTC_10x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x10: + return GL_COMPRESSED_RGBA_ASTC_10x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x10: + return GL_COMPRESSED_RGBA_ASTC_12x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x12: + return GL_COMPRESSED_RGBA_ASTC_12x12_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_4x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x12: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; +#endif // GL_KHR_texture_compression_astc_hdr + default: + break; + } + + QT3DS_ASSERT(false); + return 0; + } + + static bool fromDepthTextureFormatToGL(NVRenderContextType type, + NVRenderTextureFormats::Enum value, + GLenum &outFormat, GLenum &outDataType, + GLenum &outInternalFormat) + { + NVRenderContextType theContextFlags(NVRenderContextValues::GLES2 + | NVRenderContextValues::GL2); + + bool supportDepth24 = !(type & theContextFlags); + bool supportDepth32f = !(type & theContextFlags); + bool supportDepth24Stencil8 = !(type & theContextFlags); + + switch (value) { + case NVRenderTextureFormats::Depth16: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = GL_DEPTH_COMPONENT16; + outDataType = GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth24: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = (supportDepth24) ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth24) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth32: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = + (supportDepth32f) ? GL_DEPTH_COMPONENT32F : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth32f) ? GL_FLOAT : GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth24Stencil8: + outFormat = (supportDepth24Stencil8) ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT; + outInternalFormat = + (supportDepth24Stencil8) ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth24Stencil8) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_SHORT; + return true; + default: + break; + } + + QT3DS_ASSERT(false); + return false; + } + + static GLenum fromTextureTargetToGL(NVRenderTextureTargetType::Enum value) + { + GLenum retval = 0; + if (value == NVRenderTextureTargetType::Texture2D) + retval = GL_TEXTURE_2D; + else if (value == NVRenderTextureTargetType::Texture2D_MS) + retval = GL_TEXTURE_2D_MULTISAMPLE; + else if (value == NVRenderTextureTargetType::Texture2D_Array) + retval = GL_TEXTURE_2D_ARRAY; + else if (value == NVRenderTextureTargetType::TextureCube) + retval = GL_TEXTURE_CUBE_MAP; + else if (value == NVRenderTextureTargetType::TextureCubeNegX) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; + else if (value == NVRenderTextureTargetType::TextureCubePosX) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + else if (value == NVRenderTextureTargetType::TextureCubeNegY) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; + else if (value == NVRenderTextureTargetType::TextureCubePosY) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; + else if (value == NVRenderTextureTargetType::TextureCubeNegZ) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + else if (value == NVRenderTextureTargetType::TextureCubePosZ) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderTextureTargetType::Enum fromGLToTextureTarget(GLenum value) + { + NVRenderTextureTargetType::Enum retval = NVRenderTextureTargetType::Unknown; + + if (value == GL_TEXTURE_2D) + retval = NVRenderTextureTargetType::Texture2D; + else if (value == GL_TEXTURE_2D_MULTISAMPLE) + retval = NVRenderTextureTargetType::Texture2D_MS; + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromTextureUnitToGL(NVRenderTextureUnit::Enum value) + { + QT3DSU32 v = value; + GLenum retval = GL_TEXTURE0; + retval = GL_TEXTURE0 + v; + + return retval; + } + + static GLenum fromGLToTextureUnit(GLenum value) + { + QT3DS_ASSERT(value > GL_TEXTURE0); + + QT3DSU32 v = value - GL_TEXTURE0; + NVRenderTextureUnit::Enum retval = + NVRenderTextureUnit::Enum(NVRenderTextureUnit::TextureUnit_0 + v); + + return retval; + } + + static GLenum fromTextureMinifyingOpToGL(NVRenderTextureMinifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case NVRenderTextureMinifyingOp::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ + case NVRenderTextureMinifyingOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureMinifyingOp::Enum fromGLToTextureMinifyingOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case x: \ + return NVRenderTextureMinifyingOp::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ + case x: \ + return NVRenderTextureMinifyingOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureMinifyingOp::Unknown; + } + + static GLenum fromTextureMagnifyingOpToGL(NVRenderTextureMagnifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case NVRenderTextureMagnifyingOp::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureMagnifyingOp::Enum fromGLToTextureMagnifyingOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case x: \ + return NVRenderTextureMagnifyingOp::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureMagnifyingOp::Unknown; + } + + static GLenum fromTextureCoordOpToGL(NVRenderTextureCoordOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ + case NVRenderTextureCoordOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureCoordOp::Enum fromGLToTextureCoordOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ + case x: \ + return NVRenderTextureCoordOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureCoordOp::Unknown; + } + + static GLenum fromTextureCompareModeToGL(NVRenderTextureCompareMode::Enum value) + { + switch (value) { + case NVRenderTextureCompareMode::NoCompare: + return GL_NONE; + case NVRenderTextureCompareMode::CompareToRef: + return GL_COMPARE_REF_TO_TEXTURE; + default: + break; + } + + QT3DS_ASSERT(false); + return NVRenderTextureCompareMode::Unknown; + } + + static GLenum fromGLToTextureCompareMode(GLenum value) + { + switch (value) { + case GL_NONE: + return NVRenderTextureCompareMode::NoCompare; + case GL_COMPARE_REF_TO_TEXTURE: + return NVRenderTextureCompareMode::CompareToRef; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static GLenum fromTextureCompareFuncToGL(NVRenderTextureCompareOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case NVRenderTextureCompareOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromImageFormatToGL(NVRenderTextureFormats::Enum value) + { + switch (value) { + case NVRenderTextureFormats::R8: + return GL_R8; + case NVRenderTextureFormats::R32I: + return GL_R32I; + case NVRenderTextureFormats::R32UI: + return GL_R32UI; + case NVRenderTextureFormats::R32F: + return GL_R32F; + case NVRenderTextureFormats::RGBA8: + return GL_RGBA8; + case NVRenderTextureFormats::SRGB8A8: + return GL_RGBA8_SNORM; + case NVRenderTextureFormats::RG16F: + return GL_RG16F; + case NVRenderTextureFormats::RGBA16F: + return GL_RGBA16F; + case NVRenderTextureFormats::RGBA32F: + return GL_RGBA32F; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + + static GLenum fromImageAccessToGL(NVRenderImageAccessType::Enum value) + { + switch (value) { + case NVRenderImageAccessType::Read: + return GL_READ_ONLY; + case NVRenderImageAccessType::Write: + return GL_WRITE_ONLY; + case NVRenderImageAccessType::ReadWrite: + return GL_READ_WRITE; + default: + break; + } + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static GLbitfield fromBufferAccessBitToGL(NVRenderBufferAccessFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; + + if (value & NVRenderBufferAccessTypeValues::Read) + retval |= GL_MAP_READ_BIT; + if (value & NVRenderBufferAccessTypeValues::Write) + retval |= GL_MAP_WRITE_BIT; + if (value & NVRenderBufferAccessTypeValues::Invalid) + retval |= GL_MAP_INVALIDATE_BUFFER_BIT; + if (value & NVRenderBufferAccessTypeValues::InvalidRange) + retval |= GL_MAP_INVALIDATE_RANGE_BIT; + + QT3DS_ASSERT(retval); + return retval; + } + + static GLbitfield fromMemoryBarrierFlagsToGL(NVRenderBufferBarrierFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderBufferBarrierValues::AtomicCounter) + retval |= GL_ATOMIC_COUNTER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::BufferUpdate) + retval |= GL_BUFFER_UPDATE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::CommandBuffer) + retval |= GL_COMMAND_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ElementArray) + retval |= GL_ELEMENT_ARRAY_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::Framebuffer) + retval |= GL_FRAMEBUFFER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::PixelBuffer) + retval |= GL_PIXEL_BUFFER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ShaderImageAccess) + retval |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ShaderStorage) + retval |= GL_SHADER_STORAGE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TextureFetch) + retval |= GL_TEXTURE_FETCH_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TextureUpdate) + retval |= GL_TEXTURE_UPDATE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TransformFeedback) + retval |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::UniformBuffer) + retval |= GL_UNIFORM_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::VertexAttribArray) + retval |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; +#endif + QT3DS_ASSERT(retval); + return retval; + } + + static GLbitfield fromShaderTypeFlagsToGL(NVRenderShaderTypeFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; + if (value & NVRenderShaderTypeValue::Vertex) + retval |= GL_VERTEX_SHADER_BIT; + if (value & NVRenderShaderTypeValue::Fragment) + retval |= GL_FRAGMENT_SHADER_BIT; + if (value & NVRenderShaderTypeValue::TessControl) + retval |= GL_TESS_CONTROL_SHADER_BIT; + if (value & NVRenderShaderTypeValue::TessEvaluation) + retval |= GL_TESS_EVALUATION_SHADER_BIT; + if (value & NVRenderShaderTypeValue::Geometry) +#if defined(QT_OPENGL_ES_3_1) + retval |= GL_GEOMETRY_SHADER_BIT_EXT; +#else + retval |= GL_GEOMETRY_SHADER_BIT; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + + static GLenum fromPropertyDataTypesToShaderGL(NVRenderShaderDataTypes::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ + case NVRenderShaderDataTypes::nv: \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderShaderDataTypes::Enum fromShaderGLToPropertyDataTypes(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ + case gl: \ + return NVRenderShaderDataTypes::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES + case GL_SAMPLER_2D_SHADOW: + return NVRenderShaderDataTypes::NVRenderTexture2DPtr; +#if !defined(QT_OPENGL_ES) + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return NVRenderShaderDataTypes::QT3DSU32; + case GL_UNSIGNED_INT_IMAGE_2D: + return NVRenderShaderDataTypes::NVRenderImage2DPtr; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderShaderDataTypes::Unknown; + } + + static GLenum fromComponentTypeAndNumCompsToAttribGL(NVRenderComponentTypes::Enum compType, + QT3DSU32 numComps) + { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ + if (compType == NVRenderComponentTypes::ct && numComps == nc) \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES + QT3DS_ASSERT(false); + return 0; + } + + static void fromAttribGLToComponentTypeAndNumComps( + GLenum enumVal, NVRenderComponentTypes::Enum &outCompType, QT3DSU32 &outNumComps) + { + switch (enumVal) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ + case gl: \ + outCompType = NVRenderComponentTypes::ct; \ + outNumComps = nc; \ + return; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES + default: + break; + } + QT3DS_ASSERT(false); + outCompType = NVRenderComponentTypes::Unknown; + outNumComps = 0; + } + + static GLenum + fromRenderBufferFormatsToRenderBufferGL(NVRenderRenderBufferFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ + case NVRenderRenderBufferFormats::nv: \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderRenderBufferFormats::Enum + fromRenderBufferGLToRenderBufferFormats(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ + case gl: \ + return NVRenderRenderBufferFormats::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderRenderBufferFormats::Unknown; + } + + static GLenum fromFramebufferAttachmentsToGL(NVRenderFrameBufferAttachments::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ + case NVRenderFrameBufferAttachments::x: \ + return GL_COLOR_ATTACHMENT0 + idx; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ + case NVRenderFrameBufferAttachments::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderFrameBufferAttachments::Unknown; + } + + static NVRenderFrameBufferAttachments::Enum fromGLToFramebufferAttachments(GLenum value) + { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ + if (value == GL_COLOR_ATTACHMENT0 + idx) \ + return NVRenderFrameBufferAttachments::x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ + if (value == x) \ + return NVRenderFrameBufferAttachments::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT + QT3DS_ASSERT(false); + return NVRenderFrameBufferAttachments::Unknown; + } + + static GLbitfield fromClearFlagsToGL(NVRenderClearFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ + if ((value & NVRenderClearValues::nv)) \ + retval |= gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS + return retval; + } + + static NVRenderClearFlags fromGLToClearFlags(GLbitfield value) + { + QT3DSU32 retval = 0; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ + if ((value & gl)) \ + retval |= NVRenderClearValues::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS + return NVRenderClearFlags(retval); + } + + static GLenum fromDrawModeToGL(NVRenderDrawMode::Enum value, bool inTesselationSupported) + { + switch (value) { + case NVRenderDrawMode::Points: + return GL_POINTS; + case NVRenderDrawMode::Lines: + return GL_LINES; + case NVRenderDrawMode::LineStrip: + return GL_LINE_STRIP; + case NVRenderDrawMode::LineLoop: + return GL_LINE_LOOP; + case NVRenderDrawMode::TriangleStrip: + return GL_TRIANGLE_STRIP; + case NVRenderDrawMode::TriangleFan: + return GL_TRIANGLE_FAN; + case NVRenderDrawMode::Triangles: + return GL_TRIANGLES; + case NVRenderDrawMode::Patches: + return (inTesselationSupported) ? GL_PATCHES : GL_TRIANGLES; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static NVRenderDrawMode::Enum fromGLToDrawMode(GLenum value) + { + switch (value) { + case GL_POINTS: + return NVRenderDrawMode::Points; + case GL_LINES: + return NVRenderDrawMode::Lines; + case GL_LINE_STRIP: + return NVRenderDrawMode::LineStrip; + case GL_LINE_LOOP: + return NVRenderDrawMode::LineLoop; + case GL_TRIANGLE_STRIP: + return NVRenderDrawMode::TriangleStrip; + case GL_TRIANGLE_FAN: + return NVRenderDrawMode::TriangleFan; + case GL_TRIANGLES: + return NVRenderDrawMode::Triangles; + case GL_PATCHES: + return NVRenderDrawMode::Patches; + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderDrawMode::Unknown; + } + + static GLenum fromRenderStateToGL(NVRenderState::Enum value) + { + switch (value) { + case NVRenderState::Blend: + return GL_BLEND; + case NVRenderState::CullFace: + return GL_CULL_FACE; + case NVRenderState::DepthTest: + return GL_DEPTH_TEST; + case NVRenderState::Multisample: +#if defined(QT_OPENGL_ES) + return GL_MULTISAMPLE_EXT; +#else + return GL_MULTISAMPLE; +#endif + case NVRenderState::StencilTest: + return GL_STENCIL_TEST; + case NVRenderState::ScissorTest: + return GL_SCISSOR_TEST; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderState::Enum fromGLToRenderState(GLenum value) + { + switch (value) { + case GL_BLEND: + return NVRenderState::Blend; + case GL_CULL_FACE: + return NVRenderState::CullFace; + case GL_DEPTH_TEST: + return NVRenderState::DepthTest; +#if defined(QT_OPENGL_ES) + case GL_MULTISAMPLE_EXT: +#else + case GL_MULTISAMPLE: +#endif + return NVRenderState::Multisample; + case GL_STENCIL_TEST: + return NVRenderState::StencilTest; + case GL_SCISSOR_TEST: + return NVRenderState::ScissorTest; + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderState::Unknown; + } + + static bool fromReadPixelsToGlFormatAndType(NVRenderReadPixelFormats::Enum inReadPixels, + GLuint *outFormat, GLuint *outType) + { + switch (inReadPixels) { + case NVRenderReadPixelFormats::Alpha8: + *outFormat = GL_ALPHA; + *outType = GL_UNSIGNED_BYTE; + break; + case NVRenderReadPixelFormats::RGB565: + *outFormat = GL_RGB; + *outType = GL_UNSIGNED_SHORT_5_6_5; + case NVRenderReadPixelFormats::RGB8: + *outFormat = GL_RGB; + *outType = GL_UNSIGNED_BYTE; + break; + case NVRenderReadPixelFormats::RGBA4444: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case NVRenderReadPixelFormats::RGBA5551: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case NVRenderReadPixelFormats::RGBA8: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_BYTE; + break; + default: + *outFormat = 0; + *outType = 0; + QT3DS_ASSERT(false); + return false; + }; + + return true; + } + + static GLenum fromPathFillModeToGL(NVRenderPathFillMode::Enum inMode) + { + GLenum glFillMode; + + switch (inMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathFillMode::Fill: + glFillMode = GL_PATH_FILL_MODE_NV; + break; + case NVRenderPathFillMode::CountUp: + glFillMode = GL_COUNT_UP_NV; + break; + case NVRenderPathFillMode::CountDown: + glFillMode = GL_COUNT_DOWN_NV; + break; + case NVRenderPathFillMode::Invert: + glFillMode = GL_INVERT; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glFillMode; + } + + static GLenum fromPathFontTargetToGL(NVRenderPathFontTarget::Enum inFontTarget) + { + GLenum glFontTarget; + + switch (inFontTarget) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathFontTarget::StandardFont: + glFontTarget = GL_STANDARD_FONT_NAME_NV; + break; + case NVRenderPathFontTarget::SystemFont: + glFontTarget = GL_SYSTEM_FONT_NAME_NV; + break; + case NVRenderPathFontTarget::FileFont: + glFontTarget = GL_FILE_NAME_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glFontTarget; + } + + static NVRenderPathReturnValues::Enum fromGLToPathFontReturn(GLenum inReturnValue) + { + NVRenderPathReturnValues::Enum returnValue; + + switch (inReturnValue) { +#if !defined(QT_OPENGL_ES) + case GL_FONT_GLYPHS_AVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontGlypsAvailable; + break; + case GL_FONT_TARGET_UNAVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontTargetUnavailable; + break; + case GL_FONT_UNAVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontUnavailable; + break; + case GL_FONT_UNINTELLIGIBLE_NV: + returnValue = NVRenderPathReturnValues::FontUnintelligible; + break; +#endif + case GL_INVALID_ENUM: + case GL_INVALID_VALUE: + returnValue = NVRenderPathReturnValues::InvalidEnum; + break; + case GL_OUT_OF_MEMORY: + returnValue = NVRenderPathReturnValues::OutOfMemory; + break; + default: + QT3DS_ASSERT(false); + returnValue = NVRenderPathReturnValues::FontTargetUnavailable; + break; + } + + return returnValue; + } + + static GLenum fromPathMissingGlyphsToGL(NVRenderPathMissingGlyphs::Enum inHandleGlyphs) + { + GLenum glMissingGlyphs; + + switch (inHandleGlyphs) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathMissingGlyphs::SkipMissing: + glMissingGlyphs = GL_SKIP_MISSING_GLYPH_NV; + break; + case NVRenderPathMissingGlyphs::UseMissing: + glMissingGlyphs = GL_USE_MISSING_GLYPH_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glMissingGlyphs; + } + + static GLenum fromPathListModeToGL(NVRenderPathListMode::Enum inListMode) + { + GLenum glListMode; + + switch (inListMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathListMode::AccumAdjacentPairs: + glListMode = GL_ACCUM_ADJACENT_PAIRS_NV; + break; + case NVRenderPathListMode::AdjacentPairs: + glListMode = GL_ADJACENT_PAIRS_NV; + break; + case NVRenderPathListMode::FirstToRest: + glListMode = GL_FIRST_TO_REST_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glListMode; + } + + static GLenum fromPathCoverModeToGL(NVRenderPathCoverMode::Enum inMode) + { + GLenum glCoverMode; + + switch (inMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathCoverMode::ConvexHull: + glCoverMode = GL_CONVEX_HULL_NV; + break; + case NVRenderPathCoverMode::BoundingBox: + glCoverMode = GL_BOUNDING_BOX_NV; + break; + case NVRenderPathCoverMode::BoundingBoxOfBoundingBox: + glCoverMode = GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV; + break; + case NVRenderPathCoverMode::PathFillCover: + glCoverMode = GL_PATH_FILL_COVER_MODE_NV; + break; + case NVRenderPathCoverMode::PathStrokeCover: + glCoverMode = GL_PATH_STROKE_COVER_MODE_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glCoverMode; + } + + static GLenum fromPathTypeToGL(NVRenderPathFormatType::Enum value) + { + switch (value) { + case NVRenderPathFormatType::Byte: + return GL_BYTE; + case NVRenderPathFormatType::UByte: + return GL_UNSIGNED_BYTE; + case NVRenderPathFormatType::Short: + return GL_SHORT; + case NVRenderPathFormatType::UShort: + return GL_UNSIGNED_SHORT; + case NVRenderPathFormatType::Int: + return GL_INT; + case NVRenderPathFormatType::Uint: + return GL_UNSIGNED_INT; +#if !defined(QT_OPENGL_ES) + case NVRenderPathFormatType::Bytes2: + return GL_2_BYTES_NV; + case NVRenderPathFormatType::Bytes3: + return GL_3_BYTES_NV; + case NVRenderPathFormatType::Bytes4: + return GL_4_BYTES_NV; + case NVRenderPathFormatType::Utf8: + return GL_UTF8_NV; + case NVRenderPathFormatType::Utf16: + return GL_UTF16_NV; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return GL_UNSIGNED_BYTE; + } + + static GLbitfield fromPathFontStyleToGL(NVRenderPathFontStyleFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderPathFontStyleValues::Bold) + retval |= GL_BOLD_BIT_NV; + if (value & NVRenderPathFontStyleValues::Italic) + retval |= GL_ITALIC_BIT_NV; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + + static GLenum fromPathTransformToGL(NVRenderPathTransformType::Enum value) + { + switch (value) { + case NVRenderPathTransformType::NoTransform: + return GL_NONE; +#if !defined(QT_OPENGL_ES) + case NVRenderPathTransformType::TranslateX: + return GL_TRANSLATE_X_NV; + case NVRenderPathTransformType::TranslateY: + return GL_TRANSLATE_Y_NV; + case NVRenderPathTransformType::Translate2D: + return GL_TRANSLATE_2D_NV; + case NVRenderPathTransformType::Translate3D: + return GL_TRANSLATE_3D_NV; + case NVRenderPathTransformType::Affine2D: + return GL_AFFINE_2D_NV; + case NVRenderPathTransformType::Affine3D: + return GL_AFFINE_3D_NV; + case NVRenderPathTransformType::TransposeAffine2D: + return GL_TRANSPOSE_AFFINE_2D_NV; + case NVRenderPathTransformType::TransposeAffine3D: + return GL_TRANSPOSE_AFFINE_3D_NV; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return GL_UNSIGNED_BYTE; + } + + static GLbitfield fromPathMetricQueryFlagsToGL(NVRenderPathGlyphFontMetricFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderPathGlyphFontMetricValues::GlyphWidth) + retval |= GL_GLYPH_WIDTH_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHeight) + retval |= GL_GLYPH_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingX) + retval |= GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingY) + retval |= GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingAdvance) + retval |= GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingX) + retval |= GL_GLYPH_VERTICAL_BEARING_X_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingY) + retval |= GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingAdvance) + retval |= GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHasKerning) + retval |= GL_GLYPH_HAS_KERNING_BIT_NV; + + if (value & NVRenderPathGlyphFontMetricValues::FontXMinBounds) + retval |= GL_FONT_X_MIN_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontYMinBounds) + retval |= GL_FONT_Y_MIN_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontXMaxBounds) + retval |= GL_FONT_X_MAX_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontYMaxBounds) + retval |= GL_FONT_Y_MAX_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontUnitsPerEm) + retval |= GL_FONT_UNITS_PER_EM_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontAscender) + retval |= GL_FONT_ASCENDER_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontDescender) + retval |= GL_FONT_DESCENDER_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontHeight) + retval |= GL_FONT_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) + retval |= GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceHeight) + retval |= GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontUnderlinePosition) + retval |= GL_FONT_UNDERLINE_POSITION_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) + retval |= GL_FONT_UNDERLINE_THICKNESS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontHasKerning) + retval |= GL_FONT_HAS_KERNING_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontNumGlyphIndices) + retval |= GL_FONT_NUM_GLYPH_INDICES_BIT_NV; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + }; +} +} + +#endif // QT3DSOPENGLUTIL_H diff --git a/src/render/backends/gl/Qt3DSRenderBackendGL3.cpp b/src/render/backends/gl/Qt3DSRenderBackendGL3.cpp new file mode 100644 index 0000000..c4d8b64 --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendGL3.cpp @@ -0,0 +1,796 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +#if defined(QT_OPENGL_ES) +#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_TIMER_EXT(x) m_timerExtension->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_tessellationShader->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_MULTISAMPLE_EXT(x) m_multiSample->x; RENDER_LOG_ERROR_PARAMS(x); +#endif + +namespace qt3ds { +namespace render { + +#ifndef GL_PATCH_VERTICES +#define GL_PATCH_VERTICES 0x8E72 +#endif + + /// constructor + NVRenderBackendGL3Impl::NVRenderBackendGL3Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGLBase(fnd, stringTable, format) + { + eastl::string exts3tc("GL_EXT_texture_compression_s3tc"); + eastl::string extsdxt("GL_EXT_texture_compression_dxt1"); + eastl::string extsAniso("GL_EXT_texture_filter_anisotropic"); + eastl::string extsTexSwizzle("GL_ARB_texture_swizzle"); + eastl::string extsAstcHDR("GL_KHR_texture_compression_astc_hdr"); + eastl::string extsAstcLDR("GL_KHR_texture_compression_astc_ldr"); + eastl::string extsFPRenderTarget("GL_EXT_color_buffer_float"); + eastl::string extsTimerQuery("GL_EXT_timer_query"); + eastl::string extsGpuShader5("EXT_gpu_shader5"); + + const char *languageVersion = GetShadingLanguageVersion(); + qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + eastl::string apiVendor(getVendorString()); + qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); + + eastl::string apiRenderer(getRendererString()); + qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); + + // clear support bits + m_backendSupport.caps.u32Values = 0; + + // get extension count + GLint numExtensions = 0; + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); + + eastl::string extensionBuffer; + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); + + m_extensions.push_back(QString::fromLocal8Bit(extensionString)); + + if (extensionBuffer.size()) + extensionBuffer.append(" "); + extensionBuffer.append(extensionString); + + // search for extension + if (!m_backendSupport.caps.bits.bDXTImagesSupported + && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { + m_backendSupport.caps.bits.bDXTImagesSupported = true; + } else if (!m_backendSupport.caps.bits.bAnistropySupported + && extsAniso.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAnistropySupported = true; + } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported + && extsFPRenderTarget.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + } else if (!m_backendSupport.caps.bits.bTimerQuerySupported + && extsTimerQuery.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported + && extsGpuShader5.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; + } + + } + + qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensionBuffer.c_str()); + + // texture swizzle is always true + m_backendSupport.caps.bits.bTextureSwizzleSupported = true; + // depthstencil renderbuffer support is always true + m_backendSupport.caps.bits.bDepthStencilSupported = true; + // constant buffers support is always true + m_backendSupport.caps.bits.bConstantBufferSupported = true; + m_backendSupport.caps.bits.bStandardDerivativesSupported = true; + m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; + m_backendSupport.caps.bits.bTextureLodSupported = true; + + if (!isESCompatible()) { + // render to float textures is always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + // multisampled texture is always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bMsTextureSupported = true; + // timer queries are always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } + + // query hardware + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); + + // internal state tracker + m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); + + // finally setup caps based on device + setAndInspectHardwareCaps(); + + // Initialize extensions +#if defined(QT_OPENGL_ES_2) + m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#else + m_timerExtension = new QOpenGLExtension_ARB_timer_query; + m_timerExtension->initializeOpenGLFunctions(); + m_tessellationShader = new QOpenGLExtension_ARB_tessellation_shader; + m_tessellationShader->initializeOpenGLFunctions(); + m_multiSample = new QOpenGLExtension_ARB_texture_multisample; + m_multiSample->initializeOpenGLFunctions(); + m_qt3dsExtensions = new Qt3DSOpenGLExtensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#endif + } + /// destructor + NVRenderBackendGL3Impl::~NVRenderBackendGL3Impl() + { + if (m_pCurrentMiscState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); +#if !defined(QT_OPENGL_ES_2) + if (m_timerExtension) + delete m_timerExtension; + if (m_tessellationShader) + delete m_tessellationShader; + if (m_multiSample) + delete m_multiSample; +#endif + if (m_qt3dsExtensions) + delete m_qt3dsExtensions; + } + + void NVRenderBackendGL3Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) + { +// Not supported by ES 3 yet +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(samples); + NVRENDER_BACKEND_UNUSED(internalFormat); + NVRENDER_BACKEND_UNUSED(width); + NVRENDER_BACKEND_UNUSED(height); + NVRENDER_BACKEND_UNUSED(fixedsamplelocations); +#else + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + GL_CALL_MULTISAMPLE_EXT(glTexImage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, + (GLsizei)width, (GLsizei)height, fixedsamplelocations)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +#endif + } + + void NVRenderBackendGL3Impl::SetTextureData3D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, + QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + (GLsizei)depth, border, glformat, gltype, hostPtr)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGL3Impl::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) + { + + // Satisfy the compiler + // These are not available in GLES 3 and we don't use them right now + QT3DS_ASSERT(lodBias == 0.0); + QT3DS_ASSERT(!borderColor); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(borderColor); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_R, + m_Conversion.fromTextureCoordOpToGL(wrapR))); + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MIN_LOD, minLod)); + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_LOD, maxLod)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_MODE, + m_Conversion.fromTextureCompareModeToGL(compareMode))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_FUNC, + m_Conversion.fromTextureCompareFuncToGL(compareFunc))); + + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + qMin(anisotropy, m_maxAnisotropy))); + } + } + + void NVRenderBackendGL3Impl::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) + { + NVRENDER_BACKEND_UNUSED(to); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); + } + + void NVRenderBackendGL3Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) + { + NVRENDER_BACKEND_UNUSED(to); + if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { + GLint glSwizzle[4]; + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); +#if defined(QT_OPENGL_ES) + // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); +#else + GL_CALL_EXTRA_FUNCTION(glTexParameteriv(glTarget, GL_TEXTURE_SWIZZLE_RGBA, glSwizzle)); +#endif + } + } + + QT3DSU32 + NVRenderBackendGL3Impl::GetDepthBits() const + { + QT3DSI32 depthBits; + GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv( + GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); + + return depthBits; + } + + QT3DSU32 + NVRenderBackendGL3Impl::GetStencilBits() const + { + QT3DSI32 stencilBits; + GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilBits)); + + return stencilBits; + } + + void NVRenderBackendGL3Impl::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum /*genType*/) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + bool NVRenderBackendGL3Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) + { + if (iao == NULL) { + // unbind and return; + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(0)); + return true; + } + + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + NVDataRef shaderAttribBuffer; + if (pProgram->m_shaderInput) + shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; + + if (attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) + return false; + + if (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot) { + QT3DS_ASSERT(false); + return false; + } + + if (inputAssembler->m_VaoID == 0) { + // generate vao + GL_CALL_EXTRA_FUNCTION(glGenVertexArrays(1, &inputAssembler->m_VaoID)); + QT3DS_ASSERT(inputAssembler->m_VaoID); + } + + // set patch parameter count if changed + if (m_backendSupport.caps.bits.bTessellationSupported + && m_pCurrentMiscState->m_PatchVertexCount != inputAssembler->m_PatchVertexCount) { + m_pCurrentMiscState->m_PatchVertexCount = inputAssembler->m_PatchVertexCount; +#if defined(QT_OPENGL_ES) + GL_CALL_TESSELATION_EXT(glPatchParameteriEXT(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); +#else + GL_CALL_TESSELATION_EXT(glPatchParameteri(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); +#endif + } + + if (inputAssembler->m_cachedShaderHandle != programID) { + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); + inputAssembler->m_cachedShaderHandle = programID; + + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents) { + qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + return false; + } else { + entryData.m_AttribIndex = attrib.m_AttribLocation; + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + + // disable max possible used first + // this is currently sufficient since we always re-arrange input attributes from 0 + for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); + } + + // setup all attribs + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); + if (entry) { + const NVRenderBackendLayoutEntryGL &entryData(*entry); + GLuint id = HandleToID_cast( + GLuint, size_t, + inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); + GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); + GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; + GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; + GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( + entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, + stride, (const void *)(entryData.m_Offset + offset))); + + } else { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); + } + } + + // setup index buffer. + if (inputAssembler->m_IndexbufferHandle) { + GL_CALL_EXTRA_FUNCTION(glBindBuffer( + GL_ELEMENT_ARRAY_BUFFER, + HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); + } else { + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + } else { + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); + } +#ifdef _DEBUG + if (inputAssembler->m_VaoID) { + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents + || entryData.m_AttribIndex != attrib.m_AttribLocation) { + qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + } +#endif // _DEBUG + + return true; + } + + void NVRenderBackendGL3Impl::ReleaseInputAssembler( + NVRenderBackend::NVRenderBackendInputAssemblerObject iao) + { + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + if (inputAssembler->m_VaoID) + GL_CALL_EXTRA_FUNCTION(glDeleteVertexArrays(1, &inputAssembler->m_VaoID)); + NVDelete(m_Foundation.getAllocator(), inputAssembler); + } + + void NVRenderBackendGL3Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) + { + NVRENDER_BACKEND_UNUSED(rto); + + m_DrawBuffersArray.clear(); + + for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { + if (inDrawBufferSet[idx] < 0) + m_DrawBuffersArray.push_back(GL_NONE); + else + m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); + } + + GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), m_DrawBuffersArray.data())); + } + + void NVRenderBackendGL3Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) + { + NVRENDER_BACKEND_UNUSED(rto); + + GL_CALL_EXTRA_FUNCTION(glReadBuffer(m_Conversion.fromReadFacesToGL(inReadFace))); + } + + void NVRenderBackendGL3Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) + { + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_EXTRA_FUNCTION(glFramebufferTextureLayer(GL_FRAMEBUFFER, glAttach, texID, level, layer)) + } + + void NVRenderBackendGL3Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) + { + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + if (!fboID) + fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject(); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); + } + + void NVRenderBackendGL3Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) + { + GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + m_Conversion.fromClearFlagsToGL(flags), + m_Conversion.fromTextureMagnifyingOpToGL(filter))); + } + + void *NVRenderBackendGL3Impl::MapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t length, NVRenderBufferAccessFlags accessFlags) + { + void *ret = NULL; + ret = GL_CALL_EXTRA_FUNCTION(glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, + length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); + + return ret; + } + + bool NVRenderBackendGL3Impl::UnmapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags) + { + GLboolean ret; + + ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); + + return (ret) ? true : false; + } + + QT3DSI32 NVRenderBackendGL3Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) + { + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLint numUniformBuffers; + GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBuffers)); + + return numUniformBuffers; + } + + QT3DSI32 + NVRenderBackendGL3Impl::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + GLuint blockIndex = GL_INVALID_INDEX; + + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, nameBuf)); + + if (*length > 0) { + blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); + if (blockIndex != GL_INVALID_INDEX) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); + } + } + + return blockIndex; + } + + void + NVRenderBackendGL3Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (indices) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices)); + } + } + + void NVRenderBackendGL3Impl::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(count); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + if (count && indices) { + if (type) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_TYPE, type)); + // convert to UIC types + QT3DS_FOREACH(idx, count) + { + type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); + } + } + if (size) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_SIZE, size)); + } + if (offset) { + GL_CALL_EXTRA_FUNCTION( + glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); + } + } + } + + void NVRenderBackendGL3Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); + } + + void NVRenderBackendGL3Impl::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { + QT3DS_ASSERT(bo); + + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); + } + + NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGL3Impl::CreateQuery() + { + QT3DSU32 glQueryID = 0; + + GL_CALL_EXTRA_FUNCTION(glGenQueries(1, &glQueryID)); + + return (NVRenderBackendQueryObject)glQueryID; + } + + void NVRenderBackendGL3Impl::ReleaseQuery(NVRenderBackendQueryObject qo) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + GL_CALL_EXTRA_FUNCTION(glDeleteQueries(1, &queryID)); + } + + void NVRenderBackendGL3Impl::BeginQuery(NVRenderBackendQueryObject qo, + NVRenderQueryType::Enum type) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + GL_CALL_EXTRA_FUNCTION(glBeginQuery(m_Conversion.fromQueryTypeToGL(type), queryID)); + } + + void NVRenderBackendGL3Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum type) + { + GL_CALL_EXTRA_FUNCTION(glEndQuery(m_Conversion.fromQueryTypeToGL(type))); + } + + void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, + QT3DSU32 *params) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + if (params) + GL_CALL_EXTRA_FUNCTION(glGetQueryObjectuiv( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); + } + + void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, + QT3DSU64 *params) + { + if (m_backendSupport.caps.bits.bTimerQuerySupported) { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + if (params) +#if defined(QT_OPENGL_ES) + GL_CALL_TIMER_EXT(glGetQueryObjectui64vEXT( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); +#else + GL_CALL_TIMER_EXT(glGetQueryObjectui64v( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); +#endif + } + } + + void NVRenderBackendGL3Impl::SetQueryTimer(NVRenderBackendQueryObject qo) + { + if (m_backendSupport.caps.bits.bTimerQuerySupported) { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); +#if defined(QT_OPENGL_ES) + GL_CALL_TIMER_EXT(glQueryCounterEXT(queryID, GL_TIMESTAMP_EXT)); +#else + GL_CALL_TIMER_EXT(glQueryCounter(queryID, GL_TIMESTAMP)); +#endif + } + } + + NVRenderBackend::NVRenderBackendSyncObject + NVRenderBackendGL3Impl::CreateSync(NVRenderSyncType::Enum syncType, NVRenderSyncFlags) + { + GLsync syncID = 0; + + syncID = GL_CALL_EXTRA_FUNCTION(glFenceSync(m_Conversion.fromSyncTypeToGL(syncType), 0)); + + return NVRenderBackendSyncObject(syncID); + } + + void NVRenderBackendGL3Impl::ReleaseSync(NVRenderBackendSyncObject so) + { + GLsync syncID = (GLsync)so; + + GL_CALL_EXTRA_FUNCTION(glDeleteSync(syncID)); + } + + void NVRenderBackendGL3Impl::WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags, + QT3DSU64) + { + GLsync syncID = (GLsync)so; + + GL_CALL_EXTRA_FUNCTION(glWaitSync(syncID, 0, GL_TIMEOUT_IGNORED)); + } +} +} diff --git a/src/render/backends/gl/Qt3DSRenderBackendGL3.h b/src/render/backends/gl/Qt3DSRenderBackendGL3.h new file mode 100644 index 0000000..ea77270 --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendGL3.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL3_H +#define QT3DS_RENDER_BACKEND_GL3_H + +/// @file Qt3DSRenderBackendGL3.h +/// NVRender OpenGL 3 backend definition. + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +#include +#include + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendMiscStateGL; + + using namespace foundation; + + class NVRenderBackendGL3Impl : public NVRenderBackendGLBase + { + public: + /// constructor + NVRenderBackendGL3Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGL3Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override; + + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) override; + + void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef inDrawBufferSet) override; + void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) override; + + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; + void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; + + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + protected: + NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state +#if defined(QT_OPENGL_ES_2) + Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; +#else + QOpenGLExtension_ARB_timer_query *m_timerExtension; + QOpenGLExtension_ARB_tessellation_shader *m_tessellationShader; + QOpenGLExtension_ARB_texture_multisample *m_multiSample; + Qt3DSOpenGLExtensions *m_qt3dsExtensions; +#endif + }; +} +} + +#endif diff --git a/src/render/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/render/backends/gl/Qt3DSRenderBackendGL4.cpp new file mode 100644 index 0000000..083fc35 --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendGL4.cpp @@ -0,0 +1,875 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGL4.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +#if defined(QT_OPENGL_ES) +#define GL_CALL_NVPATH_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_NVPATH_EXT(x) m_nvPathRendering->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_DIRECTSTATE_EXT(x) m_directStateAccess->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#endif + +#ifndef GL_GEOMETRY_SHADER_EXT +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#endif + +namespace qt3ds { +namespace render { + + /// constructor + NVRenderBackendGL4Impl::NVRenderBackendGL4Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGL3Impl(fnd, stringTable, format) + { + eastl::string extTess("GL_ARB_tessellation_shader"); + eastl::string extGeometry("GL_EXT_geometry_shader4"); + eastl::string arbCompute("GL_ARB_compute_shader"); + eastl::string arbStorageBuffer("GL_ARB_shader_storage_buffer_object"); + eastl::string arbAtomicCounterBuffer("GL_ARB_shader_atomic_counters"); + eastl::string arbProgInterface("GL_ARB_program_interface_query"); + eastl::string arbShaderImageLoadStore("GL_ARB_shader_image_load_store"); + eastl::string nvPathRendering("GL_NV_path_rendering"); + eastl::string nvBlendAdvanced("GL_NV_blend_equation_advanced"); + eastl::string khrBlendAdvanced("GL_KHR_blend_equation_advanced"); + eastl::string nvBlendAdvancedCoherent("GL_NV_blend_equation_advanced_coherent"); + eastl::string khrBlendAdvancedCoherent("GL_KHR_blend_equation_advanced_coherent"); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + // get extension count + GLint numExtensions = 0; + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); + + // search for extension + if (!m_backendSupport.caps.bits.bTessellationSupported + && extTess.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTessellationSupported = true; + } else if (!m_backendSupport.caps.bits.bComputeSupported + && arbCompute.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bComputeSupported = true; + } else if (!m_backendSupport.caps.bits.bGeometrySupported + && extGeometry.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGeometrySupported = true; + } else if (!m_backendSupport.caps.bits.bStorageBufferSupported + && arbStorageBuffer.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bStorageBufferSupported = true; + } else if (!m_backendSupport.caps.bits.bAtomicCounterBufferSupported + && arbAtomicCounterBuffer.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; + } else if (!m_backendSupport.caps.bits.bProgramInterfaceSupported + && arbProgInterface.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bProgramInterfaceSupported = true; + } else if (!m_backendSupport.caps.bits.bShaderImageLoadStoreSupported + && arbShaderImageLoadStore.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; + } else if (!m_backendSupport.caps.bits.bNVPathRenderingSupported + && nvPathRendering.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVPathRenderingSupported = true; + } else if (!m_backendSupport.caps.bits.bNVAdvancedBlendSupported + && nvBlendAdvanced.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVAdvancedBlendSupported = true; + } else if (!m_backendSupport.caps.bits.bNVBlendCoherenceSupported + && nvBlendAdvancedCoherent.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVBlendCoherenceSupported = true; + } else if (!m_backendSupport.caps.bits.bKHRAdvancedBlendSupported + && khrBlendAdvanced.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported = true; + } else if (!m_backendSupport.caps.bits.bKHRBlendCoherenceSupported + && khrBlendAdvancedCoherent.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bKHRBlendCoherenceSupported = true; + } + } + + // always true for GL4.1 and GLES 3.1 devices + m_backendSupport.caps.bits.bMsTextureSupported = true; + m_backendSupport.caps.bits.bProgramPipelineSupported = true; + + if (!isESCompatible()) { + // TODO: investigate GL 4.0 support + // we expect minimum GL 4.1 context anything beyond is handeled via extensions + // Tessellation is always supported on none ES systems which support >=GL4 + m_backendSupport.caps.bits.bTessellationSupported = true; + // geometry shader is always supported on none ES systems which support >=GL4 ( actually + // 3.2 already ) + m_backendSupport.caps.bits.bGeometrySupported = true; + } else { + // always true for GLES 3.1 devices + m_backendSupport.caps.bits.bComputeSupported = true; + m_backendSupport.caps.bits.bProgramInterfaceSupported = true; + m_backendSupport.caps.bits.bStorageBufferSupported = true; + m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; + m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; + } + +#if !defined(QT_OPENGL_ES) + // Initialize extensions + m_nvPathRendering = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_NV_path_rendering)(); + m_nvPathRendering->initializeOpenGLFunctions(); + m_directStateAccess = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_EXT_direct_state_access)(); + m_directStateAccess->initializeOpenGLFunctions(); +#endif + } + + /// destructor + NVRenderBackendGL4Impl::~NVRenderBackendGL4Impl() + { +#if !defined(QT_OPENGL_ES) + if (m_nvPathRendering) + NVDelete(m_Foundation.getAllocator(), m_nvPathRendering); + if (m_directStateAccess) + NVDelete(m_Foundation.getAllocator(), m_directStateAccess); +#endif + } + + void NVRenderBackendGL4Impl::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) + { + GL_CALL_EXTRA_FUNCTION( + glDrawArraysIndirect(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + indirect)); + } + + void NVRenderBackendGL4Impl::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) + { + GL_CALL_EXTRA_FUNCTION(glDrawElementsIndirect( + m_Conversion.fromDrawModeToGL(drawMode, + m_backendSupport.caps.bits.bTessellationSupported), + m_Conversion.fromIndexBufferComponentsTypesToGL(type), indirect)); + } + + void NVRenderBackendGL4Impl::CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + // up to now compressed is not supported + QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + GL_CALL_EXTRA_FUNCTION( + glTexStorage2D(glTarget, levels, glInternalFormat, (GLsizei)width, (GLsizei)height)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGL4Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + GL_CALL_EXTRA_FUNCTION(glTexStorage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, + (GLsizei)width, (GLsizei)height, + fixedsamplelocations)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + NVRenderBackend::NVRenderBackendTessControlShaderObject + NVRenderBackendGL4Impl::CreateTessControlShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { +#if !defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_CONTROL_SHADER)); +#else + GLuint shaderID = 0; +#endif + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendTessControlShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendTessEvaluationShaderObject + NVRenderBackendGL4Impl::CreateTessEvaluationShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { +#if !defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_EVALUATION_SHADER)); +#else + GLuint shaderID = 0; +#endif + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendGeometryShaderObject + NVRenderBackendGL4Impl::CreateGeometryShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { +#if defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER_EXT)); +#else + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER)); +#endif + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendGeometryShaderObject)shaderID; + } + + void NVRenderBackendGL4Impl::SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, + QT3DSU32 count) + { + QT3DS_ASSERT(iao); + QT3DS_ASSERT(count); + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + inputAssembler->m_PatchVertexCount = count; + } + + void NVRenderBackendGL4Impl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) + { + GL_CALL_EXTRA_FUNCTION(glMemoryBarrier(m_Conversion.fromMemoryBarrierFlagsToGL(barriers))); + } + + void NVRenderBackendGL4Impl::BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, + QT3DSI32 level, bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + GL_CALL_EXTRA_FUNCTION(glBindImageTexture(unit, texID, level, layered, layer, + m_Conversion.fromImageAccessToGL(access), + m_Conversion.fromImageFormatToGL(format))); + } + + QT3DSI32 NVRenderBackendGL4Impl::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) + { + GLint numStorageBuffers = 0; + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) + GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_SHADER_STORAGE_BLOCK, + GL_ACTIVE_RESOURCES, &numStorageBuffers)); +#endif + return numStorageBuffers; + } + + QT3DSI32 + NVRenderBackendGL4Impl::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) + { + GLint bufferIndex = GL_INVALID_INDEX; + + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + QT3DS_ASSERT(bufferSize); + QT3DS_ASSERT(paramCount); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_SHADER_STORAGE_BLOCK, id, nameBufSize, + length, nameBuf)); + + if (*length > 0) { +#define QUERY_COUNT 3 + GLsizei actualCount; + GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, + GL_NUM_ACTIVE_VARIABLES }; + GLint params[QUERY_COUNT]; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_SHADER_STORAGE_BLOCK, id, + QUERY_COUNT, props, QUERY_COUNT, &actualCount, + params)); + + QT3DS_ASSERT(actualCount == QUERY_COUNT); + + bufferIndex = params[0]; + *bufferSize = params[1]; + *paramCount = params[2]; + } + } +#endif + return bufferIndex; + } + + void NVRenderBackendGL4Impl::ProgramSetStorageBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + GL_CALL_EXTRA_FUNCTION( + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); +#endif + } + + QT3DSI32 NVRenderBackendGL4Impl::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) + { + GLint numAtomicCounterBuffers = 0; + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) + GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_ATOMIC_COUNTER_BUFFER, + GL_ACTIVE_RESOURCES, &numAtomicCounterBuffers)); +#endif + return numAtomicCounterBuffers; + } + + QT3DSI32 + NVRenderBackendGL4Impl::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + GLint bufferIndex = GL_INVALID_INDEX; + + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + QT3DS_ASSERT(bufferSize); + QT3DS_ASSERT(paramCount); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { + { +#define QUERY_COUNT 3 + GLsizei actualCount; + GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, + GL_NUM_ACTIVE_VARIABLES }; + GLint params[QUERY_COUNT]; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_ATOMIC_COUNTER_BUFFER, id, + QUERY_COUNT, props, QUERY_COUNT, &actualCount, + params)); + + QT3DS_ASSERT(actualCount == QUERY_COUNT); + + bufferIndex = params[0]; + *bufferSize = params[1]; + *paramCount = params[2]; + + GLenum props1[1] = { GL_ATOMIC_COUNTER_BUFFER_INDEX }; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_UNIFORM, id, 1, props1, 1, + &actualCount, params)); + + QT3DS_ASSERT(actualCount == 1); + + *nameBuf = '\0'; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_UNIFORM, params[0], nameBufSize, + length, nameBuf)); + } + } +#endif + return bufferIndex; + } + + void NVRenderBackendGL4Impl::ProgramSetAtomicCounterBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + GL_CALL_EXTRA_FUNCTION( + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); +#endif + } + + void NVRenderBackendGL4Impl::SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); + + switch (glType) { + case GL_FLOAT: + GL_CALL_EXTRA_FUNCTION(glProgramUniform1fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC2: + GL_CALL_EXTRA_FUNCTION(glProgramUniform2fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC3: + GL_CALL_EXTRA_FUNCTION(glProgramUniform3fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC4: + GL_CALL_EXTRA_FUNCTION(glProgramUniform4fv(programID, id, count, (GLfloat *)value)); + break; + case GL_INT: + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, (GLint *)value)); + break; + case GL_BOOL: + { + GLint boolValue = *(GLboolean *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, &boolValue)); + } + break; + case GL_INT_VEC2: + case GL_BOOL_VEC2: + GL_CALL_EXTRA_FUNCTION(glProgramUniform2iv(programID, id, count, (GLint *)value)); + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + GL_CALL_EXTRA_FUNCTION(glProgramUniform3iv(programID, id, count, (GLint *)value)); + break; + case GL_INT_VEC4: + case GL_BOOL_VEC4: + GL_CALL_EXTRA_FUNCTION(glProgramUniform4iv(programID, id, count, (GLint *)value)); + break; + case GL_FLOAT_MAT3: + GL_CALL_EXTRA_FUNCTION( + glProgramUniformMatrix3fv(programID, id, count, transpose, (GLfloat *)value)); + break; + case GL_FLOAT_MAT4: + GL_CALL_EXTRA_FUNCTION( + glProgramUniformMatrix4fv(programID, id, count, transpose, (GLfloat *)value)); + break; + case GL_IMAGE_2D: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_CUBE: { + if (count <= 1) { + GLint sampler = *(GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1i(programID, id, sampler)); + } else { + GLint *sampler = (GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, sampler)); + } + } break; + default: + qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); + QT3DS_ASSERT(false); + break; + } + } + + NVRenderBackend::NVRenderBackendComputeShaderObject + NVRenderBackendGL4Impl::CreateComputeShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) + { + GLuint shaderID = 0; +#if defined(GL_COMPUTE_SHADER) + shaderID = m_glExtraFunctions->glCreateShader(GL_COMPUTE_SHADER); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } +#endif + return (NVRenderBackend::NVRenderBackendComputeShaderObject)shaderID; + } + + void NVRenderBackendGL4Impl::DispatchCompute(NVRenderBackendShaderProgramObject, + QT3DSU32 numGroupsX, QT3DSU32 numGroupsY, + QT3DSU32 numGroupsZ) + { + GL_CALL_EXTRA_FUNCTION(glDispatchCompute(numGroupsX, numGroupsY, numGroupsZ)); + } + + NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGL4Impl::CreateProgramPipeline() + { + GLuint pipeline; + GL_CALL_EXTRA_FUNCTION(glGenProgramPipelines(1, &pipeline)); + + return NVRenderBackend::NVRenderBackendProgramPipeline(pipeline); + } + + void NVRenderBackendGL4Impl::ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + GL_CALL_EXTRA_FUNCTION(glDeleteProgramPipelines(1, &pipeline)); + } + + void NVRenderBackendGL4Impl::SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + + GL_CALL_EXTRA_FUNCTION(glBindProgramPipeline(pipeline)); + } + + void NVRenderBackendGL4Impl::SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + GLuint programID = 0; + + if (po) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + programID = static_cast(pProgram->m_ProgramID); + } + + GL_CALL_EXTRA_FUNCTION( + glUseProgramStages(pipeline, m_Conversion.fromShaderTypeFlagsToGL(flags), programID)); + } + + void NVRenderBackendGL4Impl::SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) + { + if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported || + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported) + GL_CALL_EXTRA_FUNCTION(glBlendEquation(m_Conversion.fromBlendEquationToGL( + pBlendEquArg.m_RGBEquation, m_backendSupport.caps.bits.bNVAdvancedBlendSupported, + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported))); + } + + void NVRenderBackendGL4Impl::SetBlendBarrier(void) + { + if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported) + GL_CALL_QT3DS_EXT(glBlendBarrierNV()); + } + + NVRenderBackend::NVRenderBackendPathObject + NVRenderBackendGL4Impl::CreatePathNVObject(size_t range) + { + GLuint pathID = GL_CALL_NVPATH_EXT(glGenPathsNV((GLsizei)range)); + + return NVRenderBackend::NVRenderBackendPathObject(pathID); + } + void NVRenderBackendGL4Impl::SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef inPathCommands, + NVConstDataRef inPathCoords) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, inPathObject); + GL_CALL_NVPATH_EXT(glPathCommandsNV(pathID, inPathCommands.size(), inPathCommands.begin(), + inPathCoords.size(), GL_FLOAT, inPathCoords.begin())); + } + + NVBounds3 + NVRenderBackendGL4Impl::GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_OBJECT_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + NVBounds3 NVRenderBackendGL4Impl::GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_FILL_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + NVBounds3 NVRenderBackendGL4Impl::GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_STROKE_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + void NVRenderBackendGL4Impl::SetStrokeWidth(NVRenderBackendPathObject inPathObject, + QT3DSF32 inStrokeWidth) + { +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glPathParameterfNV(HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_STROKE_WIDTH_NV, inStrokeWidth)); +#endif + } + + void NVRenderBackendGL4Impl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) + { +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(inPathProjection); +#else + GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_PROJECTION, inPathProjection.front())); +#endif + } + + void NVRenderBackendGL4Impl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) + { +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(inPathModelview); +#else + GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_MODELVIEW, inPathModelview.front())); +#endif + } + + void NVRenderBackendGL4Impl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) + { + GL_CALL_NVPATH_EXT(glPathStencilDepthOffsetNV(inSlope, inBias)); + } + + void NVRenderBackendGL4Impl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) + { + GL_CALL_NVPATH_EXT(glPathCoverDepthFuncNV(m_Conversion.fromBoolOpToGL(inDepthFunction))); + } + + void NVRenderBackendGL4Impl::StencilStrokePath(NVRenderBackendPathObject inPathObject) + { + GL_CALL_NVPATH_EXT(glStencilStrokePathNV(HandleToID_cast(GLuint, size_t, inPathObject), 0x1, (GLuint)~0)); + } + + void NVRenderBackendGL4Impl::StencilFillPath(NVRenderBackendPathObject inPathObject) + { +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glStencilFillPathNV(HandleToID_cast(GLuint, size_t, inPathObject), + GL_COUNT_UP_NV, (GLuint)~0)); +#endif + } + + void NVRenderBackendGL4Impl::ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glDeletePathsNV(pathID, (GLsizei)range)); + } + + void NVRenderBackendGL4Impl::StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glStencilFillPathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathFillModeToGL(fillMode), stencilMask, + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::StencilStrokePathInstancedN( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glStencilStrokePathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, stencilRef, + stencilMask, m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::CoverFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glCoverFillPathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathCoverModeToGL(coverMode), + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::CoverStrokePathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glCoverStrokePathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathCoverModeToGL(coverMode), + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::LoadPathGlyphs( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + + GL_CALL_NVPATH_EXT(glPathGlyphsNV(pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), (GLsizei)numGlyphs, + m_Conversion.fromPathTypeToGL(type), charCodes, + m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), + pathTemplateID, emScale)); + } + + NVRenderPathReturnValues::Enum NVRenderBackendGL4Impl::LoadPathGlyphsIndexed( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + GLenum glRet = 0; + + glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexArrayNV( + pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyphIndex, + (GLsizei)numGlyphs, pathTemplateID, emScale)); + + return m_Conversion.fromGLToPathFontReturn(glRet); + } + + NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGL4Impl::LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale, QT3DSU32 *count) + { + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + GLenum glRet = 0; + GLuint baseAndCount[2] = { 0, 0 }; + + glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexRangeNV(m_Conversion.fromPathFontTargetToGL(fontTarget), + fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), + pathTemplateID, emScale, baseAndCount)); + + if (count) + *count = baseAndCount[1]; + + return NVRenderBackend::NVRenderBackendPathObject(baseAndCount[0]); + } + + void NVRenderBackendGL4Impl::LoadPathGlyphRange( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + + GL_CALL_NVPATH_EXT(glPathGlyphRangeNV( + pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyph, (GLsizei)numGlyphs, + m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), pathTemplateID, emScale)); + } + + void NVRenderBackendGL4Impl::GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, + const void *charCodes, size_t stride, + QT3DSF32 *metrics) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathMetricsNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), + charCodes, pathID, (GLsizei)stride, metrics)); + } + + void + NVRenderBackendGL4Impl::GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathMetricRangeNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), + pathID, (GLsizei)numPaths, (GLsizei)stride, metrics)); + } + + void NVRenderBackendGL4Impl::GetPathSpacing( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, QT3DSF32 advanceScale, + QT3DSF32 kerningScale, NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathSpacingNV(m_Conversion.fromPathListModeToGL(pathListMode), + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), + charCodes, pathID, advanceScale, kerningScale, + m_Conversion.fromPathTransformToGL(transformType), spacing)); + } +} +} diff --git a/src/render/backends/gl/Qt3DSRenderBackendGL4.h b/src/render/backends/gl/Qt3DSRenderBackendGL4.h new file mode 100644 index 0000000..bfdc03b --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendGL4.h @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL4_H +#define QT3DS_RENDER_BACKEND_GL4_H + +/// @file Qt3DSRenderBackendGL4.h +/// NVRender OpenGL 4 backend definition. + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + class NVRenderBackendGL4Impl : public NVRenderBackendGL3Impl + { + public: + /// constructor + NVRenderBackendGL4Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGL4Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; + void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, const void *indirect) override; + + void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, const void *value, + bool transpose) override; + + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) override; + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) override; + + virtual NVRenderBackendComputeShaderObject + CreateComputeShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + + NVRenderBackendProgramPipeline CreateProgramPipeline() override; + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) override; + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) override; + void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) override; + + void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; + void SetBlendBarrier(void) override; + + NVRenderBackendPathObject CreatePathNVObject(size_t range) override; + void SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef inPathCommands, + NVConstDataRef inPathCoords) override; + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) override; + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) override; + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) override; + void SetStrokeWidth(NVRenderBackendPathObject inPathObject, QT3DSF32 inStrokeWidth) override; + + void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override; + void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override; + void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override; + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) override; + void StencilStrokePath(NVRenderBackendPathObject inPathObject) override; + void StencilFillPath(NVRenderBackendPathObject inPathObject) override; + void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; + + void StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) override; + void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, + QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void LoadPathGlyphs(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, + NVRenderPathFormatType::Enum type, const void *charCodes, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, + QT3DSU32 *count) override; + void LoadPathGlyphRange(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) override; + void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, const void *charCodes, + size_t stride, QT3DSF32 *metrics) override; + void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) override; + void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, + QT3DSF32 advanceScale, QT3DSF32 kerningScale, + NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) override; + private: +#if !defined(QT_OPENGL_ES) + QOpenGLExtension_NV_path_rendering *m_nvPathRendering; + QOpenGLExtension_EXT_direct_state_access *m_directStateAccess; +#endif + }; +} +} + +#endif diff --git a/src/render/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/render/backends/gl/Qt3DSRenderBackendGLBase.cpp new file mode 100644 index 0000000..0fe6e0f --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendGLBase.cpp @@ -0,0 +1,2230 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "foundation/StringTable.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_FUNCTION(x) m_glFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +namespace qt3ds { +namespace render { + +#ifndef GL_PROGRAM_SEPARABLE +#define GL_PROGRAM_SEPARABLE 0x8258 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif + +#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + +/// constructor +NVRenderBackendGLBase::NVRenderBackendGLBase(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : mRefCount(0) + , m_Foundation(fnd) + , m_StringTable(stringTable) + , m_Conversion() + , m_MaxAttribCount(0) + , m_DrawBuffersArray(m_Foundation.getAllocator(), + "NVRenderBackendGLBase::m_DrawBuffersArray") + , m_format(format) +{ + m_glFunctions = new QOpenGLFunctions; + m_glFunctions->initializeOpenGLFunctions(); + m_glExtraFunctions = new QOpenGLExtraFunctions; + m_glExtraFunctions->initializeOpenGLFunctions(); + + // internal state tracker + m_pCurrentRasterizerState = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendRasterizerStateGL)(); + m_pCurrentDepthStencilState = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)(); + + m_glFunctions->glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &m_maxAnisotropy); +} +/// destructor +NVRenderBackendGLBase::~NVRenderBackendGLBase() +{ + if (m_pCurrentRasterizerState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentRasterizerState); + if (m_pCurrentDepthStencilState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentDepthStencilState); + if (m_glFunctions) + delete m_glFunctions; + if (m_glExtraFunctions) + delete m_glExtraFunctions; +} + +NVRenderContextType NVRenderBackendGLBase::GetRenderContextType() const +{ + if (m_format.renderableType() == QSurfaceFormat::OpenGLES) { + if (m_format.majorVersion() == 2) + return NVRenderContextValues::GLES2; + + if (m_format.majorVersion() == 3) { + if (m_format.minorVersion() >= 1) + return NVRenderContextValues::GLES3PLUS; + else + return NVRenderContextValues::GLES3; + } + } else if (m_format.majorVersion() == 2) { + return NVRenderContextValues::GL2; + } else if (m_format.majorVersion() == 3) { + return NVRenderContextValues::GL3; + } else if (m_format.majorVersion() == 4) { + return NVRenderContextValues::GL4; + } + + return NVRenderContextValues::NullContext; +} + +bool NVRenderBackendGLBase::isESCompatible() const +{ + return m_format.renderableType() == QSurfaceFormat::OpenGLES; +} + +const char *NVRenderBackendGLBase::GetShadingLanguageVersion() +{ + const char *retval = (const char *)GL_CALL_FUNCTION( + glGetString(GL_SHADING_LANGUAGE_VERSION)); + if (retval == nullptr) + return ""; + + return retval; +} + +QT3DSU32 +NVRenderBackendGLBase::GetMaxCombinedTextureUnits() +{ + QT3DSI32 maxUnits; + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxUnits)); + return maxUnits; +} + +bool NVRenderBackendGLBase::GetRenderBackendCap( + NVRenderBackend::NVRenderBackendCaps::Enum inCap) const +{ + bool bSupported = false; + + switch (inCap) { + case NVRenderBackendCaps::FpRenderTarget: + bSupported = m_backendSupport.caps.bits.bFPRenderTargetsSupported; + break; + case NVRenderBackendCaps::DepthStencilTexture: + bSupported = m_backendSupport.caps.bits.bDepthStencilSupported; + break; + case NVRenderBackendCaps::ConstantBuffer: + bSupported = m_backendSupport.caps.bits.bConstantBufferSupported; + break; + case NVRenderBackendCaps::DxtImages: + bSupported = m_backendSupport.caps.bits.bDXTImagesSupported; + break; + case NVRenderBackendCaps::MsTexture: + bSupported = m_backendSupport.caps.bits.bMsTextureSupported; + break; + case NVRenderBackendCaps::TexSwizzle: + bSupported = m_backendSupport.caps.bits.bTextureSwizzleSupported; + break; + case NVRenderBackendCaps::FastBlits: + bSupported = m_backendSupport.caps.bits.bFastBlitsSupported; + break; + case NVRenderBackendCaps::Tessellation: + bSupported = m_backendSupport.caps.bits.bTessellationSupported; + break; + case NVRenderBackendCaps::Compute: + bSupported = m_backendSupport.caps.bits.bComputeSupported; + break; + case NVRenderBackendCaps::Geometry: + bSupported = m_backendSupport.caps.bits.bGeometrySupported; + break; + case NVRenderBackendCaps::SampleQuery: { + // On the following context sample query is not supported + NVRenderContextType noSamplesQuerySupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noSamplesQuerySupportedContextFlags); + } break; + case NVRenderBackendCaps::TimerQuery: + bSupported = m_backendSupport.caps.bits.bTimerQuerySupported; + break; + case NVRenderBackendCaps::CommandSync: { + // On the following context sync objects are not supported + NVRenderContextType noSyncObjectSupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noSyncObjectSupportedContextFlags); + } break; + case NVRenderBackendCaps::TextureArray: { + // On the following context texture arrays are not supported + NVRenderContextType noTextureArraySupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noTextureArraySupportedContextFlags); + } break; + case NVRenderBackendCaps::StorageBuffer: + bSupported = m_backendSupport.caps.bits.bStorageBufferSupported; + break; + case NVRenderBackendCaps::AtomicCounterBuffer: + bSupported = m_backendSupport.caps.bits.bAtomicCounterBufferSupported; + break; + case NVRenderBackendCaps::ShaderImageLoadStore: + bSupported = m_backendSupport.caps.bits.bShaderImageLoadStoreSupported; + break; + case NVRenderBackendCaps::ProgramPipeline: + bSupported = m_backendSupport.caps.bits.bProgramPipelineSupported; + break; + case NVRenderBackendCaps::PathRendering: + bSupported = m_backendSupport.caps.bits.bNVPathRenderingSupported; + break; + case NVRenderBackendCaps::AdvancedBlend: + bSupported = m_backendSupport.caps.bits.bNVAdvancedBlendSupported | + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; + break; + case NVRenderBackendCaps::AdvancedBlendKHR: + bSupported = m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; + break; + case NVRenderBackendCaps::BlendCoherency: + bSupported = m_backendSupport.caps.bits.bNVBlendCoherenceSupported | + m_backendSupport.caps.bits.bKHRBlendCoherenceSupported; + break; + case NVRenderBackendCaps::gpuShader5: + bSupported = m_backendSupport.caps.bits.bGPUShader5ExtensionSupported; + break; + case NVRenderBackendCaps::VertexArrayObject: + bSupported = m_backendSupport.caps.bits.bVertexArrayObjectSupported; + break; + case NVRenderBackendCaps::StandardDerivatives: + bSupported = m_backendSupport.caps.bits.bStandardDerivativesSupported; + break; + case NVRenderBackendCaps::TextureLod: + bSupported = m_backendSupport.caps.bits.bTextureLodSupported; + break; + default: + QT3DS_ASSERT(false); + bSupported = false; + break; + } + + return bSupported; +} + +void NVRenderBackendGLBase::GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, + QT3DSI32 *params) const +{ + if (!params) + return; + switch (inQuery) { + case NVRenderBackendQuery::MaxTextureSize: + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_TEXTURE_SIZE, params)); + break; + case NVRenderBackendQuery::MaxTextureArrayLayers: { + NVRenderContextType noTextureArraySupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noTextureArraySupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, params)); + } else { + *params = 0; + } + } break; + case NVRenderBackendQuery::MaxConstantBufferSlots: { + NVRenderContextType noConstantBufferSupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noConstantBufferSupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, params)); + } else { + *params = 0; + } + } break; + case NVRenderBackendQuery::MaxConstantBufferBlockSize: { + NVRenderContextType noConstantBufferSupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noConstantBufferSupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, params)); + } else { + *params = 0; + } + } break; + default: + QT3DS_ASSERT(false); + *params = 0; + break; + } +} + +QT3DSU32 +NVRenderBackendGLBase::GetDepthBits() const +{ + QT3DSI32 depthBits; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_BITS, &depthBits)); + return depthBits; +} + +QT3DSU32 +NVRenderBackendGLBase::GetStencilBits() const +{ + QT3DSI32 stencilBits; + GL_CALL_FUNCTION(glGetIntegerv(GL_STENCIL_BITS, &stencilBits)); + return stencilBits; +} + +void NVRenderBackendGLBase::SetMultisample(bool bEnable) +{ + QT3DS_ASSERT(m_backendSupport.caps.bits.bMsTextureSupported || !bEnable); + // For GL ES explicit multisample enabling is not needed + // and does not exist + NVRenderContextType noMsaaEnableContextFlags(NVRenderContextValues::GLES2 + | NVRenderContextValues::GLES3 + | NVRenderContextValues::GLES3PLUS); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noMsaaEnableContextFlags)) { + SetRenderState(bEnable, NVRenderState::Multisample); + } +} + +void NVRenderBackendGLBase::SetRenderState(bool bEnable, const NVRenderState::Enum value) +{ + if (value == NVRenderState::DepthWrite) { + GL_CALL_FUNCTION(glDepthMask(bEnable)); + } else { + if (bEnable) { + GL_CALL_FUNCTION(glEnable(m_Conversion.fromRenderStateToGL(value))); + } else { + GL_CALL_FUNCTION(glDisable(m_Conversion.fromRenderStateToGL(value))); + } + } +} + +NVRenderBackend::NVRenderBackendDepthStencilStateObject +NVRenderBackendGLBase::CreateDepthStencilState( + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) +{ + NVRenderBackendDepthStencilStateGL *retval = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)( + enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack, + depthStencilOpFront, depthStencilOpBack); + + return (NVRenderBackend::NVRenderBackendDepthStencilStateObject)retval; +} + +void NVRenderBackendGLBase::ReleaseDepthStencilState( + NVRenderBackendDepthStencilStateObject inDepthStencilState) +{ + NVRenderBackendDepthStencilStateGL *inputState = + (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; + if (inputState) + NVDelete(m_Foundation.getAllocator(), inputState); +} + +NVRenderBackend::NVRenderBackendRasterizerStateObject +NVRenderBackendGLBase::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) +{ + NVRenderBackendRasterizerStateGL *retval = + QT3DS_NEW(m_Foundation.getAllocator(), + NVRenderBackendRasterizerStateGL)(depthBias, depthScale, cullFace); + + return (NVRenderBackend::NVRenderBackendRasterizerStateObject)retval; +} + +void NVRenderBackendGLBase::ReleaseRasterizerState( + NVRenderBackendRasterizerStateObject rasterizerState) +{ + NVRenderBackendRasterizerStateGL *inputState = + (NVRenderBackendRasterizerStateGL *)rasterizerState; + if (inputState) + NVDelete(m_Foundation.getAllocator(), inputState); +} + +void NVRenderBackendGLBase::SetDepthStencilState( + NVRenderBackendDepthStencilStateObject inDepthStencilState) +{ + NVRenderBackendDepthStencilStateGL *inputState = + (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; + if (inputState && !(*m_pCurrentDepthStencilState == *inputState)) { + // we check on a per single state base + if (inputState->m_DepthEnable != m_pCurrentDepthStencilState->m_DepthEnable) { + SetRenderState(inputState->m_DepthEnable, NVRenderState::DepthTest); + m_pCurrentDepthStencilState->m_DepthEnable = inputState->m_DepthEnable; + } + if (inputState->m_StencilEnable != m_pCurrentDepthStencilState->m_StencilEnable) { + SetRenderState(inputState->m_StencilEnable, NVRenderState::StencilTest); + m_pCurrentDepthStencilState->m_StencilEnable = inputState->m_StencilEnable; + } + + if (inputState->m_DepthMask != m_pCurrentDepthStencilState->m_DepthMask) { + GL_CALL_FUNCTION(glDepthMask(inputState->m_DepthMask)); + m_pCurrentDepthStencilState->m_DepthMask = inputState->m_DepthMask; + } + + if (inputState->m_DepthFunc != m_pCurrentDepthStencilState->m_DepthFunc) { + GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(inputState->m_DepthFunc))); + m_pCurrentDepthStencilState->m_DepthFunc = inputState->m_DepthFunc; + } + + if (!(inputState->m_DepthStencilOpFront + == m_pCurrentDepthStencilState->m_DepthStencilOpFront)) { + GL_CALL_FUNCTION(glStencilOpSeparate( + GL_FRONT, + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_StencilFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthPass))); + m_pCurrentDepthStencilState->m_DepthStencilOpFront = + inputState->m_DepthStencilOpFront; + } + + if (!(inputState->m_DepthStencilOpBack + == m_pCurrentDepthStencilState->m_DepthStencilOpBack)) { + GL_CALL_FUNCTION(glStencilOpSeparate( + GL_BACK, + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_StencilFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthPass))); + m_pCurrentDepthStencilState->m_DepthStencilOpBack = + inputState->m_DepthStencilOpBack; + } + + if (!(inputState->m_StencilFuncFront + == m_pCurrentDepthStencilState->m_StencilFuncFront)) { + GL_CALL_FUNCTION(glStencilFuncSeparate( + GL_FRONT, + m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncFront.m_Function), + inputState->m_StencilFuncFront.m_ReferenceValue, + inputState->m_StencilFuncFront.m_Mask)); + m_pCurrentDepthStencilState->m_StencilFuncFront = inputState->m_StencilFuncFront; + } + + if (!(inputState->m_StencilFuncBack + == m_pCurrentDepthStencilState->m_StencilFuncBack)) { + GL_CALL_FUNCTION(glStencilFuncSeparate( + GL_BACK, m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncBack.m_Function), + inputState->m_StencilFuncBack.m_ReferenceValue, + inputState->m_StencilFuncBack.m_Mask)); + m_pCurrentDepthStencilState->m_StencilFuncBack = inputState->m_StencilFuncBack; + } + } +} + +void +NVRenderBackendGLBase::SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) +{ + NVRenderBackendRasterizerStateGL *inputState = + (NVRenderBackendRasterizerStateGL *)rasterizerState; + if (inputState && !(*m_pCurrentRasterizerState == *inputState)) { + // store current state + *m_pCurrentRasterizerState = *inputState; + + if (m_pCurrentRasterizerState->m_DepthBias != 0.0 + || m_pCurrentRasterizerState->m_DepthScale != 0.0) { + GL_CALL_FUNCTION(glEnable(GL_POLYGON_OFFSET_FILL)); + } else { + GL_CALL_FUNCTION(glDisable(GL_POLYGON_OFFSET_FILL)); + } + + GL_CALL_FUNCTION(glPolygonOffset(m_pCurrentRasterizerState->m_DepthBias, + m_pCurrentRasterizerState->m_DepthScale)); + + GL_CALL_FUNCTION( + glCullFace(m_Conversion.fromFacesToGL(m_pCurrentRasterizerState->m_CullFace))); + } +} + +bool NVRenderBackendGLBase::GetRenderState(const NVRenderState::Enum value) +{ + bool enabled = GL_CALL_FUNCTION(glIsEnabled(m_Conversion.fromRenderStateToGL(value))); + return enabled; +} + +NVRenderBoolOp::Enum NVRenderBackendGLBase::GetDepthFunc() +{ + QT3DSI32 value; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_FUNC, &value)); + return m_Conversion.fromGLToBoolOp(value); +} + +void NVRenderBackendGLBase::SetDepthFunc(const NVRenderBoolOp::Enum func) +{ + GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(func))); +} + +bool NVRenderBackendGLBase::GetDepthWrite() +{ + QT3DSI32 value; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_WRITEMASK, (GLint *)&value)); + return value ? true : false; +} + +void NVRenderBackendGLBase::SetDepthWrite(bool bEnable) +{ + GL_CALL_FUNCTION(glDepthMask(bEnable)); +} + +void NVRenderBackendGLBase::SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) +{ + GL_CALL_FUNCTION(glColorMask(bRed, bGreen, bBlue, bAlpha)); +} + +void NVRenderBackendGLBase::GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) +{ + QT3DS_ASSERT(pBlendFuncArg); + QT3DSI32_4 values; + + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&values.x)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&values.y)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&values.z)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&values.w)); + + pBlendFuncArg->m_SrcRGB = m_Conversion.fromGLToSrcBlendFunc(values.x); + pBlendFuncArg->m_SrcAlpha = m_Conversion.fromGLToSrcBlendFunc(values.y); + pBlendFuncArg->m_DstRGB = m_Conversion.fromGLToDstBlendFunc(values.z); + pBlendFuncArg->m_DstAlpha = m_Conversion.fromGLToDstBlendFunc(values.w); +} + +void NVRenderBackendGLBase::SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) +{ + QT3DSI32_4 values; + + values.x = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcRGB); + values.y = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstRGB); + values.z = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcAlpha); + values.w = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstAlpha); + + GL_CALL_FUNCTION(glBlendFuncSeparate(values.x, values.y, values.z, values.w)); +} + +void NVRenderBackendGLBase::SetBlendEquation(const NVRenderBlendEquationArgument &) +{ + // needs GL4 / GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::SetBlendBarrier() +{ + // needs GL4 / GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::GetScissorRect(NVRenderRect *pRect) +{ + QT3DS_ASSERT(pRect); + GL_CALL_FUNCTION(glGetIntegerv(GL_SCISSOR_BOX, (GLint *)pRect)); +} + +void NVRenderBackendGLBase::SetScissorRect(const NVRenderRect &rect) +{ + GL_CALL_FUNCTION(glScissor(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height)); +} + +void NVRenderBackendGLBase::GetViewportRect(NVRenderRect *pRect) +{ + QT3DS_ASSERT(pRect); + GL_CALL_FUNCTION(glGetIntegerv(GL_VIEWPORT, (GLint *)pRect)); +} + +void NVRenderBackendGLBase::SetViewportRect(const NVRenderRect &rect) +{ + GL_CALL_FUNCTION(glViewport(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height);); +} + +void NVRenderBackendGLBase::SetClearColor(const QT3DSVec4 *pClearColor) +{ + QT3DS_ASSERT(pClearColor); + + GL_CALL_FUNCTION(glClearColor(pClearColor->x, pClearColor->y, + pClearColor->z, pClearColor->w)); +} + +void NVRenderBackendGLBase::Clear(NVRenderClearFlags flags) +{ + GL_CALL_FUNCTION(glClear(m_Conversion.fromClearFlagsToGL(flags))); +} + +NVRenderBackend::NVRenderBackendBufferObject +NVRenderBackendGLBase::CreateBuffer(size_t size, NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, const void *hostPtr) +{ + GLuint bufID = 0; + + GL_CALL_FUNCTION(glGenBuffers(1, &bufID)); + + if (bufID && size) { + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + if (target != GL_INVALID_ENUM) { + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferData(target, size, hostPtr, + m_Conversion.fromBufferUsageTypeToGL(usage))); + } else { + GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); + bufID = 0; + qCCritical(GL_ERROR, GLConversion::processGLError(target)); + } + } + + return (NVRenderBackend::NVRenderBackendBufferObject)bufID; +} + +void NVRenderBackendGLBase::BindBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_FUNCTION(glBindBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags), bufID)); +} + +void NVRenderBackendGLBase::ReleaseBuffer(NVRenderBackendBufferObject bo) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); +} + +void NVRenderBackendGLBase::UpdateBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t size, + NVRenderBufferUsageType::Enum usage, const void *data) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferData(target, size, data, m_Conversion.fromBufferUsageTypeToGL(usage))); +} + +void NVRenderBackendGLBase::UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferSubData(target, offset, size, data)); +} + +void *NVRenderBackendGLBase::MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, + size_t, size_t, NVRenderBufferAccessFlags) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return nullptr; +} + +bool NVRenderBackendGLBase::UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return true; +} + +void NVRenderBackendGLBase::SetMemoryBarrier(NVRenderBufferBarrierFlags) +{ + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLBase::CreateQuery() +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackendQueryObject(0); +} + +void NVRenderBackendGLBase::ReleaseQuery(NVRenderBackendQueryObject) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, QT3DSU32 *) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, QT3DSU64 *) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::SetQueryTimer(NVRenderBackendQueryObject) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +NVRenderBackend::NVRenderBackendSyncObject + NVRenderBackendGLBase::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackendSyncObject(0); +} + +void NVRenderBackendGLBase::ReleaseSync(NVRenderBackendSyncObject) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, + QT3DSU64) +{ + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLBase::CreateRenderTarget() +{ + GLuint fboID = 0; + + GL_CALL_FUNCTION(glGenFramebuffers(1, &fboID)); + + return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; +} + +void NVRenderBackendGLBase::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + if (fboID) { + GL_CALL_FUNCTION(glDeleteFramebuffers(1, &fboID)); + } +} + +void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) +{ + // rto must be the current render target + GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, rbID)); +} + +void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target) +{ + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D + || m_backendSupport.caps.bits.bMsTextureSupported); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, 0)) +} + +void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) +{ + // Needs GL3 or GLES 3 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::SetRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + if (!fboID) + fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject(); + + GL_CALL_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); +} + +bool NVRenderBackendGLBase::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) +{ + // rto must be the current render target + GLenum completeStatus = GL_CALL_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); + switch (completeStatus) { +#define HANDLE_INCOMPLETE_STATUS(x) \ +case x: \ + qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ + return false; + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) +#undef HANDLE_INCOMPLETE_STATUS + } + return true; +} + +NVRenderBackend::NVRenderBackendRenderbufferObject +NVRenderBackendGLBase::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + GLuint bufID = 0; + + GL_CALL_FUNCTION(glGenRenderbuffers(1, &bufID)); + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + bufID = 0; + } + + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; +} + +void NVRenderBackendGLBase::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + if (bufID) { + GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + } +} + +bool NVRenderBackendGLBase::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + bool success = true; + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + QT3DS_ASSERT(bufID); + + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + success = false; + } + + return success; +} + +NVRenderBackend::NVRenderBackendTextureObject NVRenderBackendGLBase::CreateTexture() +{ + GLuint texID = 0; + + GL_CALL_FUNCTION(glGenTextures(1, &texID)); + return (NVRenderBackend::NVRenderBackendTextureObject)texID; +} + +void NVRenderBackendGLBase::BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0 + unit)); + GL_CALL_FUNCTION(glBindTexture(m_Conversion.fromTextureTargetToGL(target), texID)); +} + +void NVRenderBackendGLBase::BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, + QT3DSI32, NVRenderImageAccessType::Enum, + NVRenderTextureFormats::Enum) +{ + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::ReleaseTexture(NVRenderBackendTextureObject to) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GL_CALL_FUNCTION(glDeleteTextures(1, &texID)); +} + +void NVRenderBackendGLBase::SetTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + border, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); +} + +// This will look very SetTextureData2D, but the target for glBindTexture will be different from +// the target for +// glTexImage2D. +void NVRenderBackendGLBase::SetTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GLenum glTexTarget = + m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + // for es2 internal format must be same as format + if (GetRenderContextType() == NVRenderContextValues::GLES2) + glInternalFormat = glformat; + + GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + border, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); +} + +void NVRenderBackendGLBase::CreateTextureStorage2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t) +{ + // you need GL 4.2 or GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, + size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + format = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), format, + swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = 0; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + GL_CALL_FUNCTION(glTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, + (GLsizei)height, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLBase::SetCompressedTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, + (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLBase::SetCompressedTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GLenum glTexTarget = + m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, + (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); +} + +void NVRenderBackendGLBase::SetCompressedTextureSubData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(format); + GL_CALL_FUNCTION(glCompressedTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, + (GLsizei)height, glformat, (GLsizei)imageSize, + hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLBase::SetTextureData3D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, + size_t, QT3DSI32, NVRenderTextureFormats::Enum, + const void *) +{ + // needs GL3 or GLES3 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glValue = GLConversion::fromHintToGL(genType); + GL_CALL_FUNCTION(glHint(GL_GENERATE_MIPMAP_HINT, glValue)); + GL_CALL_FUNCTION(glGenerateMipmap(glTarget)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); +} + +NVRenderTextureSwizzleMode::Enum +NVRenderBackendGLBase::GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const +{ + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), inFormat, swizzleMode); + + return swizzleMode; +} + +NVRenderBackend::NVRenderBackendSamplerObject NVRenderBackendGLBase::CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSI32 minLod, QT3DSI32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) +{ + // Satisfy the compiler + // We don"t setup the state here for GL + // but we need to pass on the variables here + // to satisfy the interface + NVRENDER_BACKEND_UNUSED(minFilter); + NVRENDER_BACKEND_UNUSED(magFilter); + NVRENDER_BACKEND_UNUSED(wrapS); + NVRENDER_BACKEND_UNUSED(wrapT); + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + NVRENDER_BACKEND_UNUSED(anisotropy); + NVRENDER_BACKEND_UNUSED(borderColor); + + // return a dummy handle + return (NVRenderBackend::NVRenderBackendSamplerObject)0x0001; +} + +void NVRenderBackendGLBase::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) +{ + // Satisfy the compiler + // These are not available in GLES 2 and we don't use them right now + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + NVRENDER_BACKEND_UNUSED(borderColor); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + qMin(m_maxAnisotropy, anisotropy))); + } +} + +void NVRenderBackendGLBase::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(baseLevel); + NVRENDER_BACKEND_UNUSED(maxLevel); +} + +void NVRenderBackendGLBase::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + + // Nothing to do here still might be called + QT3DS_ASSERT(swizzleMode == NVRenderTextureSwizzleMode::NoSwizzle); + + NVRENDER_BACKEND_UNUSED(swizzleMode); +} + +void NVRenderBackendGLBase::ReleaseSampler(NVRenderBackendSamplerObject so) +{ + GLuint samplerID = HandleToID_cast(GLuint, size_t, so); + if (!samplerID) + return; + // otherwise nothing to do +} + +NVRenderBackend::NVRenderBackendAttribLayoutObject +NVRenderBackendGLBase::CreateAttribLayout(NVConstDataRef attribs) +{ + QT3DSU32 attribLayoutSize = sizeof(NVRenderBackendAttributeLayoutGL); + QT3DSU32 entrySize = sizeof(NVRenderBackendLayoutEntryGL) * attribs.size(); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), + attribLayoutSize + entrySize, + "BackendAttributeLayoutGL"); + NVDataRef entryRef = + PtrAtOffset(newMem, attribLayoutSize, entrySize); + QT3DSU32 maxInputSlot = 0; + + // copy data + QT3DS_FOREACH(idx, attribs.size()) + { + entryRef[idx].m_AttribName = m_StringTable->RegisterStr(attribs.mData[idx].m_Name); + entryRef[idx].m_Normalize = 0; + entryRef[idx].m_AttribIndex = 0; // will be set later + entryRef[idx].m_Type = m_Conversion.fromComponentTypeAndNumCompsToAttribGL( + attribs.mData[idx].m_ComponentType, attribs.mData[idx].m_NumComponents); + entryRef[idx].m_NumComponents = attribs.mData[idx].m_NumComponents; + entryRef[idx].m_InputSlot = attribs.mData[idx].m_InputSlot; + entryRef[idx].m_Offset = attribs.mData[idx].m_FirstItemOffset; + + if (maxInputSlot < entryRef[idx].m_InputSlot) + maxInputSlot = entryRef[idx].m_InputSlot; + } + + NVRenderBackendAttributeLayoutGL *retval = + new (newMem) NVRenderBackendAttributeLayoutGL(entryRef, maxInputSlot); + + return (NVRenderBackend::NVRenderBackendAttribLayoutObject)retval; +} + +void NVRenderBackendGLBase::ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) +{ + NVRenderBackendAttributeLayoutGL *attribLayout = (NVRenderBackendAttributeLayoutGL *)ao; + + NVDelete(m_Foundation.getAllocator(), attribLayout); +}; + +NVRenderBackend::NVRenderBackendInputAssemblerObject +NVRenderBackendGLBase::CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, + NVConstDataRef offsets, + QT3DSU32 patchVertexCount) +{ + NVRenderBackendAttributeLayoutGL *attribLayoutGL = + (NVRenderBackendAttributeLayoutGL *)attribLayout; + + NVRenderBackendInputAssemblerGL *retval = QT3DS_NEW(m_Foundation.getAllocator(), + NVRenderBackendInputAssemblerGL)( + m_Foundation, attribLayoutGL, buffers, indexBuffer, strides, offsets, patchVertexCount); + + return (NVRenderBackend::NVRenderBackendInputAssemblerObject)retval; +} + +void NVRenderBackendGLBase::ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) +{ + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVDelete(m_Foundation.getAllocator(), inputAssembler); +} + +bool NVRenderBackendGLBase::compileSource(GLuint shaderID, NVConstDataRef source, + eastl::string &errorMessage, bool binary) +{ + GLint shaderSourceSize = static_cast(source.size()); + const char *shaderSourceData = (const char *)source.begin(); + GLint shaderStatus = GL_TRUE; + + if (!binary) { + + GL_CALL_FUNCTION(glShaderSource(shaderID, 1, &shaderSourceData, &shaderSourceSize)); + GL_CALL_FUNCTION(glCompileShader(shaderID)); + + GLint logLen; + GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_COMPILE_STATUS, &shaderStatus)); + GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLen)); + + // Check if some log exists. We also write warnings here + // Should at least contain more than the null termination + if (logLen > 2) { + errorMessage.resize(logLen + 1); + + GLint lenWithoutNull; + GL_CALL_FUNCTION(glGetShaderInfoLog(shaderID, logLen, &lenWithoutNull, + (char *)errorMessage.c_str())); + } + } else { + GL_CALL_FUNCTION(glShaderBinary(1, &shaderID, GL_NVIDIA_PLATFORM_BINARY_NV, shaderSourceData, + shaderSourceSize)); + GLenum binaryError = m_glFunctions->glGetError(); + if (binaryError != GL_NO_ERROR) { + shaderStatus = GL_FALSE; + qCCritical(GL_ERROR, GLConversion::processGLError(binaryError)); + } + } + + return (shaderStatus == GL_TRUE); +} + +NVRenderBackend::NVRenderBackendVertexShaderObject +NVRenderBackendGLBase::CreateVertexShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) +{ + GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_VERTEX_SHADER)); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendVertexShaderObject)shaderID; +} + +NVRenderBackend::NVRenderBackendFragmentShaderObject +NVRenderBackendGLBase::CreateFragmentShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) +{ + GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_FRAGMENT_SHADER)); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendFragmentShaderObject)shaderID; +} + +NVRenderBackend::NVRenderBackendTessControlShaderObject +NVRenderBackendGLBase::CreateTessControlShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) +{ + // needs GL 4 or GLES EXT_tessellation_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendTessControlShaderObject)0; +} + +NVRenderBackend::NVRenderBackendTessEvaluationShaderObject +NVRenderBackendGLBase::CreateTessEvaluationShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) +{ + // needs GL 4 or GLES EXT_tessellation_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)0; +} + +NVRenderBackend::NVRenderBackendGeometryShaderObject +NVRenderBackendGLBase::CreateGeometryShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) +{ + // needs GL 4 or GLES EXT_geometry_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendGeometryShaderObject)0; +} + +NVRenderBackend::NVRenderBackendComputeShaderObject +NVRenderBackendGLBase::CreateComputeShader(NVConstDataRef source, + eastl::string &errorMessage, bool binary) +{ + // needs GL 4.3 or GLES3.1 support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendComputeShaderObject)0; +} + +void NVRenderBackendGLBase::ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) +{ + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); +} + +void NVRenderBackendGLBase::ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) +{ + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); +} + +void +NVRenderBackendGLBase::ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) +{ + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); +} + +void NVRenderBackendGLBase::ReleaseTessEvaluationShader( + NVRenderBackendTessEvaluationShaderObject teso) +{ + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); +} + +void NVRenderBackendGLBase::ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) +{ + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); +} + +void NVRenderBackendGLBase::ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) +{ + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); +} + +void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glAttachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glDetachShader(static_cast(pProgram->m_ProgramID), shaderID)); +} + +NVRenderBackend::NVRenderBackendShaderProgramObject +NVRenderBackendGLBase::CreateShaderProgram(bool isSeparable) +{ + NVRenderBackendShaderProgramGL *theProgram = nullptr; + GLuint programID = GL_CALL_FUNCTION(glCreateProgram()); + + if (programID) { + theProgram = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendShaderProgramGL)(programID); + + if (!theProgram) { + GL_CALL_FUNCTION(glDeleteProgram(programID)); + } else if (isSeparable && m_backendSupport.caps.bits.bProgramPipelineSupported) { + GL_CALL_EXTRA_FUNCTION(glProgramParameteri(programID, GL_PROGRAM_SEPARABLE, GL_TRUE)); + } + } + + return (NVRenderBackend::NVRenderBackendShaderProgramObject)theProgram; +} + +void NVRenderBackendGLBase::ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_FUNCTION(glDeleteProgram(programID)); + + if (pProgram->m_shaderInput) { + NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); + pProgram->m_shaderInput = nullptr; + } + + NVDelete(m_Foundation.getAllocator(), pProgram); +} + +bool NVRenderBackendGLBase::LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GL_CALL_FUNCTION(glLinkProgram(programID)); + + GLint linkStatus, logLen; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_LINK_STATUS, &linkStatus)); + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLen)); + + // if successfully linked get the attribute information + if (linkStatus) { + // release old stuff + if (pProgram->m_shaderInput) { + NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); + pProgram->m_shaderInput = nullptr; + } + + GLint numAttribs; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTES, &numAttribs)); + + if (numAttribs) { + NVRenderBackendShaderInputEntryGL *tempShaderInputEntry = + (NVRenderBackendShaderInputEntryGL *)QT3DS_ALLOC( + m_Foundation.getAllocator(), + sizeof(NVRenderBackendShaderInputEntryGL) * m_MaxAttribCount, + "BackendShaderInputEntryGL"); + + GLint maxLength; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength)); + QT3DSI8 *nameBuf = + (QT3DSI8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), maxLength, "LinkProgram"); + + // fill in data + QT3DSU32 count = 0; + QT3DS_FOREACH(idx, numAttribs) + { + GLint size = 0; + GLenum glType; + NVRenderComponentTypes::Enum compType = NVRenderComponentTypes::Unknown; + QT3DSU32 numComps = 0; + + GL_CALL_FUNCTION(glGetActiveAttrib(programID, idx, maxLength, nullptr, &size, + &glType, (char *)nameBuf)); + // Skip anything named with gl_ + if (memcmp(nameBuf, "gl_", 3) == 0) + continue; + + m_Conversion.fromAttribGLToComponentTypeAndNumComps(glType, compType, numComps); + + tempShaderInputEntry[count].m_AttribName = + m_StringTable->RegisterStr((char *)nameBuf); + tempShaderInputEntry[count].m_AttribLocation = + GL_CALL_FUNCTION(glGetAttribLocation(programID, (char *)nameBuf)); + tempShaderInputEntry[count].m_Type = glType; + tempShaderInputEntry[count].m_NumComponents = numComps; + + ++count; + } + + // Now allocate space for the actuall entries + QT3DSU32 shaderInputSize = sizeof(NVRenderBackendShaderInputGL); + QT3DSU32 entrySize = sizeof(NVRenderBackendShaderInputEntryGL) * count; + QT3DSU8 *newMem = + (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), shaderInputSize + entrySize, + "BackendShaderInputEntryGL"); + NVDataRef entryRef = + PtrAtOffset(newMem, shaderInputSize, + entrySize); + // fill data + QT3DS_FOREACH(idx, count) + { + entryRef[idx].m_AttribName = tempShaderInputEntry[idx].m_AttribName; + entryRef[idx].m_AttribLocation = tempShaderInputEntry[idx].m_AttribLocation; + entryRef[idx].m_Type = tempShaderInputEntry[idx].m_Type; + entryRef[idx].m_NumComponents = tempShaderInputEntry[idx].m_NumComponents; + } + + // placement new + NVRenderBackendShaderInputGL *shaderInput = + new (newMem) NVRenderBackendShaderInputGL(entryRef); + // set the pointer + pProgram->m_shaderInput = shaderInput; + + QT3DS_FREE(m_Foundation.getAllocator(), nameBuf); + QT3DS_FREE(m_Foundation.getAllocator(), tempShaderInputEntry); + } + } + + // Check if some log exists. We also write warnings here + // Should at least contain more than the null termination + if (logLen > 2) { + errorMessage.resize(logLen + 1); + + GLint lenWithoutNull; + GL_CALL_FUNCTION(glGetProgramInfoLog(programID, logLen, &lenWithoutNull, + (char *)errorMessage.c_str())); + } + + return (linkStatus == GL_TRUE); +} + +void NVRenderBackendGLBase::SetActiveProgram(NVRenderBackendShaderProgramObject po) +{ + GLuint programID = 0; + + if (po) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + programID = static_cast(pProgram->m_ProgramID); + } + + GL_CALL_FUNCTION(glUseProgram(programID)); +} + +NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGLBase::CreateProgramPipeline() +{ + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + return NVRenderBackend::NVRenderBackendProgramPipeline(0); +} + +void NVRenderBackendGLBase::ReleaseProgramPipeline(NVRenderBackendProgramPipeline) +{ + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::SetActiveProgramPipeline(NVRenderBackendProgramPipeline) +{ + // needs GL 4 context + //TODO: should be fixed? + // QT3DS_ASSERT(false); +} + +void NVRenderBackendGLBase::SetProgramStages(NVRenderBackendProgramPipeline, + NVRenderShaderTypeFlags, + NVRenderBackendShaderProgramObject) +{ + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSU32) +{ + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +QT3DSI32 NVRenderBackendGLBase::GetConstantCount(NVRenderBackendShaderProgramObject po) +{ + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLint numUniforms; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORMS, &numUniforms)); + + return numUniforms; +} + +QT3DSI32 NVRenderBackendGLBase::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) +{ + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; +} + +QT3DSI32 +NVRenderBackendGLBase::GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) +{ + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast(pProgram->m_ProgramID); + + GLenum glType; + GL_CALL_FUNCTION(glGetActiveUniform(programID, id, bufSize, nullptr, numElem, &glType, nameBuf)); + *type = m_Conversion.fromShaderGLToPropertyDataTypes(glType); + + QT3DSI32 uniformLoc = GL_CALL_FUNCTION(glGetUniformLocation(programID, nameBuf)); + + // get unit binding point + *binding = -1; + if (uniformLoc != -1 && (glType == GL_IMAGE_2D || glType == GL_UNSIGNED_INT_IMAGE_2D + || glType == GL_UNSIGNED_INT_ATOMIC_COUNTER)) { + GL_CALL_FUNCTION(glGetUniformiv(programID, uniformLoc, binding)); + } + + return uniformLoc; +} + +QT3DSI32 +NVRenderBackendGLBase::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) +{ + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; +} + +void NVRenderBackendGLBase::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) +{ + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(indices); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) +{ + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(count); + NVRENDER_BACKEND_UNUSED(indices); + NVRENDER_BACKEND_UNUSED(type); + NVRENDER_BACKEND_UNUSED(size); + NVRENDER_BACKEND_UNUSED(offset); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) +{ + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(blockIndex); + NVRENDER_BACKEND_UNUSED(binding); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) +{ + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +QT3DSI32 NVRenderBackendGLBase::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; +} + +QT3DSI32 +NVRenderBackendGLBase::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; +} + +void NVRenderBackendGLBase::ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); +} + +QT3DSI32 NVRenderBackendGLBase::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; +} + +QT3DSI32 +NVRenderBackendGLBase::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; +} + +void NVRenderBackendGLBase::ProgramSetAtomicCounterBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); +} + +void NVRenderBackendGLBase::SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) +{ + GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); + + switch (glType) { + case GL_FLOAT: + GL_CALL_FUNCTION(glUniform1fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC2: + GL_CALL_FUNCTION(glUniform2fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC3: + GL_CALL_FUNCTION(glUniform3fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC4: + GL_CALL_FUNCTION(glUniform4fv(id, count, (GLfloat *)value)); + break; + case GL_INT: + GL_CALL_FUNCTION(glUniform1iv(id, count, (GLint *)value)); + break; + case GL_BOOL: + { + GLint boolValue = *(GLboolean *)value; + GL_CALL_FUNCTION(glUniform1iv(id, count, &boolValue)); + } + break; + case GL_INT_VEC2: + case GL_BOOL_VEC2: + GL_CALL_FUNCTION(glUniform2iv(id, count, (GLint *)value)); + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + GL_CALL_FUNCTION(glUniform3iv(id, count, (GLint *)value)); + break; + case GL_INT_VEC4: + case GL_BOOL_VEC4: + GL_CALL_FUNCTION(glUniform4iv(id, count, (GLint *)value)); + break; + case GL_FLOAT_MAT3: + GL_CALL_FUNCTION(glUniformMatrix3fv(id, count, transpose, (GLfloat *)value)); + break; + case GL_FLOAT_MAT4: + GL_CALL_FUNCTION(glUniformMatrix4fv(id, count, transpose, (GLfloat *)value)); + break; + case GL_IMAGE_2D: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_CUBE: { + if (count > 1) { + GLint *sampler = (GLint *)value; + GL_CALL_FUNCTION(glUniform1iv(id, count, sampler)); + } else { + GLint sampler = *(GLint *)value; + GL_CALL_FUNCTION(glUniform1i(id, sampler)); + } + } break; + default: + qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); + QT3DS_ASSERT(false); + break; + } +} + +void NVRenderBackendGLBase::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) +{ + GL_CALL_FUNCTION(glDrawArrays(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + start, count)); +} + +void NVRenderBackendGLBase::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(drawMode); + NVRENDER_BACKEND_UNUSED(indirect); +} + +void NVRenderBackendGLBase::DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) +{ + GL_CALL_FUNCTION(glDrawElements(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + count, m_Conversion.fromIndexBufferComponentsTypesToGL(type), + indices)); +} + +void NVRenderBackendGLBase::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) +{ + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(drawMode); + NVRENDER_BACKEND_UNUSED(type); + NVRENDER_BACKEND_UNUSED(indirect); +} + +void NVRenderBackendGLBase::ReadPixel(NVRenderBackendRenderTargetObject /* rto */, QT3DSI32 x, + QT3DSI32 y, QT3DSI32 width, QT3DSI32 height, + NVRenderReadPixelFormats::Enum inFormat, void *pixels) +{ + GLuint glFormat; + GLuint glType; + if (m_Conversion.fromReadPixelsToGlFormatAndType(inFormat, &glFormat, &glType)) { + GL_CALL_FUNCTION(glReadPixels(x, y, width, height, glFormat, glType, pixels)); + } +} + +NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::CreatePathNVObject(size_t) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackend::NVRenderBackendPathObject(0); +} + +void NVRenderBackendGLBase::ReleasePathNVObject(NVRenderBackendPathObject, size_t) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::LoadPathGlyphs(NVRenderBackendPathObject, + NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, + NVRenderBackendPathObject, QT3DSF32) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::LoadPathGlyphRange(NVRenderBackendPathObject, + NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, + NVRenderBackendPathObject, QT3DSF32) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +NVRenderPathReturnValues::Enum NVRenderBackendGLBase::LoadPathGlyphsIndexed( + NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, QT3DSF32) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderPathReturnValues::FontUnavailable; +} + +NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::Enum, const void *, NVRenderPathFontStyleFlags, + NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) +{ + return NVRenderBackendPathObject(0); +} + +void NVRenderBackendGLBase::GetPathMetrics(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, + NVRenderPathFormatType::Enum, const void *, size_t, + QT3DSF32 *) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, + QT3DSF32 *) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::GetPathSpacing(NVRenderBackendPathObject, size_t, + NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, + QT3DSF32, NVRenderPathTransformType::Enum, QT3DSF32 *) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, + const void *, QT3DSI32, QT3DSU32, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +void NVRenderBackendGLBase::CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) +{ + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; +} + +///< private calls +const char *NVRenderBackendGLBase::getVersionString() +{ + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VERSION)); + if (retval == nullptr) + return ""; + + return retval; +} + +const char *NVRenderBackendGLBase::getVendorString() +{ + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VENDOR)); + if (retval == nullptr) + return ""; + + return retval; +} + +const char *NVRenderBackendGLBase::getRendererString() +{ + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_RENDERER)); + if (retval == nullptr) + return ""; + + return retval; +} + +const char *NVRenderBackendGLBase::getExtensionString() +{ + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_EXTENSIONS)); + if (retval == nullptr) + return ""; + + return retval; +} + +/** + * @brief This function inspects the various strings to setup + * HW capabilities of the device. + * We can do a lot of smart things here based on GL version + * renderer string and vendor. + * + * @return No return + */ +void NVRenderBackendGLBase::setAndInspectHardwareCaps() +{ + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + // we assume all GLES versions running on mobile with shared memory + // this means framebuffer blits are slow and should be optimized or avoided + if (apiVersion.find("OpenGL ES") == eastl::string::npos) { + // no ES device + m_backendSupport.caps.bits.bFastBlitsSupported = true; + } +} + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +void NVRenderBackendGLBase::checkGLError(const char *function, const char *file, + const unsigned int line) const +{ + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR) << GLConversion::processGLError(error) << " " + << function << " " << file << " " << line; + } +} +#else +void NVRenderBackendGLBase::checkGLError() const +{ +#if !defined(NDEBUG) || defined(_DEBUG) + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) + qCCritical(GL_ERROR) << GLConversion::processGLError(error); +#endif +} +#endif + +} +} diff --git a/src/render/backends/gl/Qt3DSRenderBackendGLBase.h b/src/render/backends/gl/Qt3DSRenderBackendGLBase.h new file mode 100644 index 0000000..28e4dbb --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendGLBase.h @@ -0,0 +1,531 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL_BASE_H +#define QT3DS_RENDER_BACKEND_GL_BASE_H + +/// @file Qt3DSRenderBackendGLBase.h +/// NVRender OpenGL Core backend definition. + +#include "foundation/Qt3DSContainers.h" +#include "foundation/StringTable.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/backends/gl/Qt3DSOpenGLUtil.h" +#include + +#include +#include +#include + +#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; + +// Enable this to log opengl errors instead of an assert +//#define RENDER_BACKEND_LOG_GL_ERRORS + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendRasterizerStateGL; + class NVRenderBackendDepthStencilStateGL; + + using namespace foundation; + + typedef eastl::basic_string TContextStr; + + class NVRenderBackendGLBase : public NVRenderBackend + { + public: + /// constructor + NVRenderBackendGLBase(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGLBase(); + + public: + /// API Interface + NVRenderContextType GetRenderContextType() const override; + bool isESCompatible() const; + + const char *GetShadingLanguageVersion() override; + /// get implementation depended values + QT3DSU32 GetMaxCombinedTextureUnits() override; + bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const override; + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override; + + /// state get/set functions + void SetRenderState(bool bEnable, const NVRenderState::Enum value) override; + bool GetRenderState(const NVRenderState::Enum value) override; + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) override; + virtual void + ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; + virtual NVRenderBackendRasterizerStateObject + CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) override; + void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; + virtual void + SetDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; + void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; + NVRenderBoolOp::Enum GetDepthFunc() override; + void SetDepthFunc(const NVRenderBoolOp::Enum func) override; + bool GetDepthWrite() override; + void SetDepthWrite(bool bEnable) override; + void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) override; + void SetMultisample(bool bEnable) override; + void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) override; + void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) override; + void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; + void SetBlendBarrier(void) override; + void GetScissorRect(NVRenderRect *pRect) override; + void SetScissorRect(const NVRenderRect &rect) override; + void GetViewportRect(NVRenderRect *pRect) override; + void SetViewportRect(const NVRenderRect &rect) override; + + void SetClearColor(const QT3DSVec4 *pClearColor) override; + void Clear(NVRenderClearFlags flags) override; + + /// resource handling + NVRenderBackendBufferObject CreateBuffer(size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, + const void *hostPtr = NULL) override; + void BindBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + void ReleaseBuffer(NVRenderBackendBufferObject bo) override; + void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t size, NVRenderBufferUsageType::Enum usage, + const void *data) override; + void UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) override; + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + NVRenderBackendRenderTargetObject CreateRenderTarget() override; + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) override; + void RenderTargetAttach( + NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; + void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; + + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) override; + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) override; + + NVRenderBackendTextureObject CreateTexture() override; + void BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) override; + void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) override; + void ReleaseTexture(NVRenderBackendTextureObject to) override; + void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void SetTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) override; + void SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void SetCompressedTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) override; + void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) override; + void SetCompressedTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, + size_t width, size_t height, + NVRenderTextureFormats::Enum format, + size_t imageSize, const void *hostPtr = NULL) override; + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override = 0; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const override; + + NVRenderBackendSamplerObject CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + void ReleaseSampler(NVRenderBackendSamplerObject so) override; + + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef attribs) override; + void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) override; + + virtual NVRenderBackendInputAssemblerObject + CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, + QT3DSU32 patchVertexCount) override; + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override = 0; + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override + { + QT3DS_ASSERT(false); + } + + // shader + virtual NVRenderBackendVertexShaderObject + CreateVertexShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendFragmentShaderObject + CreateFragmentShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendComputeShaderObject + CreateComputeShader(NVConstDataRef source, eastl::string &errorMessage, bool binary) override; + void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) override; + void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) override; + void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) override; + void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) override; + void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) override; + void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) override; + NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) override; + void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) override; + bool LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) override; + void SetActiveProgram(NVRenderBackendShaderProgramObject po) override; + void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + NVRenderBackendProgramPipeline CreateProgramPipeline() override; + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline po) override; + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline po) override; + void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) override; + + // uniforms + QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) override; + void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) override; + + // uniform buffers + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + // storage buffers + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + // atomic counter buffers + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + /// draw calls + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) override; + void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; + void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) override; + void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, const void *indirect) override; + + // read calls + void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, + QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, void *pixels) override; + + // NV path rendering + NVRenderBackendPathObject CreatePathNVObject(size_t range) override; + // Pathing requires gl4 backend. + void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef, + NVConstDataRef) override + { + } + + ///< Bounds of the fill and stroke + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + + /** + * Defaults to 0 if unset. + */ + void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} + void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} + void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} + void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} + void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} + void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} + void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; + + void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override; + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, + NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) override; + void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override; + void GetPathMetrics(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, NVRenderPathFormatType::Enum, + const void *, size_t, QT3DSF32 *) override; + void GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override; + void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, + NVRenderPathTransformType::Enum, QT3DSF32 *) override; + + void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, QT3DSI32, + QT3DSU32, NVRenderPathTransformType::Enum, + const QT3DSF32 *) override; + void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + + QSurfaceFormat format() const override + { + return m_format; + } + + protected: + virtual NVFoundationBase &GetFoundation() { return m_Foundation; } + virtual bool compileSource(GLuint shaderID, NVConstDataRef source, + eastl::string &errorMessage, bool binary); + virtual const char *getVersionString(); + virtual const char *getVendorString(); + virtual const char *getRendererString(); + virtual const char *getExtensionString(); + + virtual void setAndInspectHardwareCaps(); + + protected: + volatile QT3DSI32 mRefCount; ///< reference count + NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things + NVScopedRefCounted + m_StringTable; ///< pointer to a string table + GLConversion m_Conversion; ///< Class for conversion from base type to GL types + QStringList m_extensions; ///< contains the OpenGL extension string + QT3DSI32 m_MaxAttribCount; ///< Maximum attributes which can be used + nvvector m_DrawBuffersArray; ///< Contains the drawbuffer enums + QSurfaceFormat m_format; + + NVRenderBackendRasterizerStateGL + *m_pCurrentRasterizerState; ///< this holds the current rasterizer state + NVRenderBackendDepthStencilStateGL + *m_pCurrentDepthStencilState; ///< this holds the current depth stencil state + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS + void checkGLError(const char *function, const char *file, const unsigned int line) const; +#else + void checkGLError() const; +#endif + QOpenGLFunctions *m_glFunctions; + QOpenGLExtraFunctions *m_glExtraFunctions; + GLfloat m_maxAnisotropy; + }; +} +} + +#endif diff --git a/src/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h b/src/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h new file mode 100644 index 0000000..e14111a --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H +#define QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/StringTable.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + struct NVRenderBackendLayoutEntryGL + { + CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader + QT3DSU8 m_Normalize; ///< normalize parameter + QT3DSU32 m_AttribIndex; ///< attribute index + QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT + QT3DSU32 m_NumComponents; ///< component count. max 4 + QT3DSU32 m_InputSlot; ///< Input slot where to fetch the data from + QT3DSU32 m_Offset; ///< offset in byte + }; + + ///< this class handles the vertex attribute layout setup + class NVRenderBackendAttributeLayoutGL + { + public: + ///< constructor + NVRenderBackendAttributeLayoutGL(NVDataRef entries, + QT3DSU32 maxInputSlot) + : m_LayoutAttribEntries(entries) + , m_MaxInputSlot(maxInputSlot) + { + } + ///< destructor + ~NVRenderBackendAttributeLayoutGL(){} + + NVRenderBackendLayoutEntryGL *getEntryByName(CRegisteredString entryName) const + { + QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) + { + if (m_LayoutAttribEntries[idx].m_AttribName == entryName) + return &m_LayoutAttribEntries.mData[idx]; + } + return NULL; + } + + Option getEntryByAttribIndex(QT3DSU32 attribIndex) const + { + QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) + { + if (m_LayoutAttribEntries[idx].m_AttribIndex == attribIndex) + return m_LayoutAttribEntries[idx]; + } + return Empty(); + } + + NVDataRef + m_LayoutAttribEntries; ///< vertex attribute layout entries + QT3DSU32 m_MaxInputSlot; ///< max used input slot + }; + + ///< this class handles the input assembler setup + class NVRenderBackendInputAssemblerGL + { + public: + ///< constructor + NVRenderBackendInputAssemblerGL( + NVFoundationBase &fnd, NVRenderBackendAttributeLayoutGL *attribLayout, + NVConstDataRef buffers, + const NVRenderBackend::NVRenderBackendBufferObject indexBuffer, + NVConstDataRef strides, NVConstDataRef offsets, QT3DSU32 patchVertexCount) + : m_Foundation(fnd) + , m_attribLayout(attribLayout) + , m_VertexbufferHandles(buffers) + , m_IndexbufferHandle(indexBuffer) + , m_VaoID(0) + , m_cachedShaderHandle(0) + , m_PatchVertexCount(patchVertexCount) + { + QT3DSU32 *strideMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), + "BackendAttributeLayoutGL:m_strides"); + QT3DSU32 *offsetMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), + "BackendAttributeLayoutGL:m_strides"); + // copy offsets and strides + QT3DS_FOREACH(idx, strides.size()) + { + strideMem[idx] = strides.mData[idx]; + offsetMem[idx] = offsets.mData[idx]; + } + + m_strides = toDataRef(strideMem, strides.size()); + m_offsets = toDataRef(offsetMem, offsets.size()); + } + ///< destructor + ~NVRenderBackendInputAssemblerGL() + { + QT3DS_FREE(m_Foundation.getAllocator(), m_strides.mData); + QT3DS_FREE(m_Foundation.getAllocator(), m_offsets.mData); + }; + + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackendAttributeLayoutGL *m_attribLayout; ///< pointer to attribute layout + NVConstDataRef + m_VertexbufferHandles; ///< opaque vertex buffer backend handles + NVRenderBackend::NVRenderBackendBufferObject + m_IndexbufferHandle; ///< opaque index buffer backend handles + QT3DSU32 m_VaoID; ///< this is only used if GL version is greater or equal 3 + QT3DSU32 m_cachedShaderHandle; ///< this is the shader id which was last used with this object + QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive + NVDataRef m_strides; ///< buffer strides + NVDataRef m_offsets; ///< buffer offsets + }; +} +} + +#endif diff --git a/src/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h b/src/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h new file mode 100644 index 0000000..3a74a8e --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H +#define QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + ///< this class handles the shader input variables + class NVRenderBackendDepthStencilStateGL + { + public: + ///< constructor + NVRenderBackendDepthStencilStateGL(bool enableDepth, bool depthMask, + NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + : m_DepthEnable(enableDepth) + , m_DepthMask(depthMask) + , m_DepthFunc(depthFunc) + , m_StencilEnable(enableStencil) + , m_StencilFuncFront(stencilFuncFront) + , m_StencilFuncBack(stencilFuncBack) + , m_DepthStencilOpFront(depthStencilOpFront) + , m_DepthStencilOpBack(depthStencilOpBack) + { + } + + ///< constructor + NVRenderBackendDepthStencilStateGL() + : m_DepthEnable(true) + , m_DepthMask(true) + , m_DepthFunc(NVRenderBoolOp::LessThanOrEqual) + , m_StencilEnable(false) + { + } + + ///< destructor + ~NVRenderBackendDepthStencilStateGL(){} + + ///< assignement + NVRenderBackendDepthStencilStateGL &operator=(const NVRenderBackendDepthStencilStateGL &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_DepthEnable = rhs.m_DepthEnable; + m_DepthMask = rhs.m_DepthMask; + m_DepthFunc = rhs.m_DepthFunc; + m_StencilEnable = rhs.m_StencilEnable; + m_StencilFuncFront = rhs.m_StencilFuncFront; + m_StencilFuncBack = rhs.m_StencilFuncBack; + m_DepthStencilOpFront = rhs.m_DepthStencilOpFront; + m_DepthStencilOpBack = rhs.m_DepthStencilOpBack; + + return *this; + } + + bool operator==(const NVRenderBackendDepthStencilStateGL &other) const + { + return (m_DepthEnable == other.m_DepthEnable && m_DepthMask == other.m_DepthMask + && m_DepthFunc == other.m_DepthFunc && m_StencilEnable == other.m_StencilEnable + && m_StencilFuncFront == other.m_StencilFuncFront + && m_StencilFuncBack == other.m_StencilFuncBack + && m_DepthStencilOpFront == other.m_DepthStencilOpFront + && m_DepthStencilOpBack == other.m_DepthStencilOpBack); + } + + bool m_DepthEnable; ///< depth test enabled + bool m_DepthMask; ///< enable / disable depth writes + NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func + bool m_StencilEnable; ///< enable disable stencil test + NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup for front faces + NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup for back faces + NVRenderStencilOperationArgument + m_DepthStencilOpFront; ///< depth stencil operation for front faces + NVRenderStencilOperationArgument + m_DepthStencilOpBack; ///< depth stencil operation for back faces + }; + + class NVRenderBackendMiscStateGL + { + public: + ///< constructor + NVRenderBackendMiscStateGL() + : m_PatchVertexCount(1) + { + } + + QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive + }; + + class NVRenderBackendRasterizerStateGL + { + public: + ///< constructor + NVRenderBackendRasterizerStateGL(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + : m_DepthBias(depthBias) + , m_DepthScale(depthScale) + , m_CullFace(cullFace) + { + } + ///< constructor + NVRenderBackendRasterizerStateGL() + : m_DepthBias(0.0) + , m_DepthScale(0.0) + , m_CullFace(NVRenderFaces::Back) + { + } + + NVRenderBackendRasterizerStateGL &operator=(const NVRenderBackendRasterizerStateGL &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_DepthBias = rhs.m_DepthBias; + m_DepthScale = rhs.m_DepthScale; + m_CullFace = rhs.m_CullFace; + + return *this; + } + + bool operator==(const NVRenderBackendRasterizerStateGL &other) const + { + return (m_DepthBias == other.m_DepthBias && m_DepthScale == other.m_DepthScale + && m_CullFace == other.m_CullFace); + } + + QT3DSF32 m_DepthBias; ///< depth bias + QT3DSF32 m_DepthScale; ///< mulitply constant + NVRenderFaces::Enum m_CullFace; ///< cull face front or back + }; +} +} + +#endif diff --git a/src/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h b/src/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h new file mode 100644 index 0000000..f7caffd --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H +#define QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + struct NVRenderBackendShaderInputEntryGL + { + CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader + QT3DSU32 m_AttribLocation; ///< attribute index + QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT + QT3DSU32 m_NumComponents; ///< component count. max 4 + }; + + ///< this class handles the shader input variables + class NVRenderBackendShaderInputGL + { + public: + ///< constructor + NVRenderBackendShaderInputGL(NVDataRef entries) + : m_ShaderInputEntries(entries) + { + } + ///< destructor + ~NVRenderBackendShaderInputGL(){} + + NVRenderBackendShaderInputEntryGL *getEntryByName(CRegisteredString entryName) const + { + QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) + { + if (m_ShaderInputEntries[idx].m_AttribName == entryName) + return &m_ShaderInputEntries.mData[idx]; + } + return NULL; + } + + Option + getEntryByAttribLocation(QT3DSU32 attribLocation) const + { + QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) + { + if (m_ShaderInputEntries[idx].m_AttribLocation == attribLocation) + return m_ShaderInputEntries[idx]; + } + return Empty(); + } + + NVDataRef m_ShaderInputEntries; ///< shader input entries + }; + + ///< this class represents the internals of a GL program + class NVRenderBackendShaderProgramGL + { + public: + ///< constructor + NVRenderBackendShaderProgramGL(QT3DSU32 programID) + : m_ProgramID(programID) + , m_shaderInput(NULL) + { + } + + ///< destructor + ~NVRenderBackendShaderProgramGL(){} + + QT3DSU32 m_ProgramID; ///< this is the OpenGL object ID + NVRenderBackendShaderInputGL *m_shaderInput; ///< pointer to shader input object + }; +} +} + +#endif diff --git a/src/render/backends/gl/Qt3DSRenderContextGL.cpp b/src/render/backends/gl/Qt3DSRenderContextGL.cpp new file mode 100644 index 0000000..88670ef --- /dev/null +++ b/src/render/backends/gl/Qt3DSRenderContextGL.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSMat44.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Utils.h" +#include "EASTL/set.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace eastl; + +namespace qt3ds { +namespace render { + + NVRenderContext &NVRenderContext::CreateGL(NVFoundationBase &foundation, + IStringTable &inStringTable, + const QSurfaceFormat &format) + { + NVRenderContext *retval = NULL; + + QT3DS_ASSERT(format.majorVersion() >= 2); + + // create backend + NVScopedRefCounted theStringTable(inStringTable); + NVScopedRefCounted theBackend; + bool isES = format.renderableType() == QSurfaceFormat::OpenGLES; + if (isES && (format.majorVersion() == 2 + || (format.majorVersion() == 3 && format.minorVersion() == 0))) { + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGLES2Impl)(foundation, + *theStringTable, + format); + } else if (format.majorVersion() == 3 && format.minorVersion() >= 1 && !isES) { + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, + *theStringTable, + format); + } else if (format.majorVersion() == 4 + || (isES && format.majorVersion() == 3 && format.minorVersion() >= 1)) { +#ifdef Q_OS_MACOS + // TODO: macOS crashes with glTextStorage2DMultisample, so fall back to OpenGL3 + // for now (QT3DS-590) + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, + *theStringTable, + format); +#else + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL4Impl)(foundation, + *theStringTable, + format); +#endif + } else { + QT3DS_ASSERT(false); + qCCritical(INTERNAL_ERROR) << "Can't find a suitable OpenGL version for" << format; + } + + + retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, + *theStringTable); + + return *retval; + } +} +} diff --git a/src/render/backends/software/Qt3DSRenderBackendNULL.cpp b/src/render/backends/software/Qt3DSRenderBackendNULL.cpp new file mode 100644 index 0000000..af93e92 --- /dev/null +++ b/src/render/backends/software/Qt3DSRenderBackendNULL.cpp @@ -0,0 +1,588 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "render/backends/software/Qt3DSRenderBackendNULL.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" + +#include + +using namespace qt3ds::render; +using namespace qt3ds::foundation; +using namespace qt3ds; + +namespace { +struct SNullBackend : public NVRenderBackend +{ + NVFoundationBase &m_Foundation; + QT3DSI32 mRefCount; + + SNullBackend(NVFoundationBase &fnd) + : m_Foundation(fnd) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + /// backend interface + + NVRenderContextType GetRenderContextType() const override + { + return NVRenderContextValues::NullContext; + } + const char *GetShadingLanguageVersion() override { return ""; } + QT3DSU32 GetMaxCombinedTextureUnits() override { return 32; } + bool GetRenderBackendCap(NVRenderBackendCaps::Enum) const override { return false; } + void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override + { + if (params) { + switch (inQuery) { + case NVRenderBackendQuery::MaxTextureSize: + *params = 4096; + break; + case NVRenderBackendQuery::MaxTextureArrayLayers: + *params = 0; + break; + default: + QT3DS_ASSERT(false); + *params = 0; + break; + } + } + } + QT3DSU32 GetDepthBits() const override { return 16; } + QT3DSU32 GetStencilBits() const override { return 0; } + void SetRenderState(bool, const NVRenderState::Enum) override {} + bool GetRenderState(const NVRenderState::Enum) override { return false; } + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool, bool, NVRenderBoolOp::Enum, bool, + NVRenderStencilFunctionArgument &, NVRenderStencilFunctionArgument &, + NVRenderStencilOperationArgument &, NVRenderStencilOperationArgument &) override + { + return NVRenderBackendDepthStencilStateObject(1); + } + void ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} + NVRenderBackendRasterizerStateObject CreateRasterizerState(QT3DSF32, QT3DSF32, + NVRenderFaces::Enum) override + { + return NVRenderBackendRasterizerStateObject(1); + } + void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject) override {} + void SetDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} + void SetRasterizerState(NVRenderBackendRasterizerStateObject) override {} + NVRenderBoolOp::Enum GetDepthFunc() override { return NVRenderBoolOp::Equal; } + void SetDepthFunc(const NVRenderBoolOp::Enum) override {} + bool GetDepthWrite() override { return false; } + + void SetDepthWrite(bool) override {} + void SetColorWrites(bool, bool, bool, bool) override {} + void SetMultisample(bool) override {} + void GetBlendFunc(NVRenderBlendFunctionArgument *) override {} + void SetBlendFunc(const NVRenderBlendFunctionArgument &) override {} + void SetBlendEquation(const NVRenderBlendEquationArgument &) override {} + void SetBlendBarrier(void) override {} + void GetScissorRect(NVRenderRect *) override {} + void SetScissorRect(const NVRenderRect &) override {} + void GetViewportRect(NVRenderRect *) override {} + void SetViewportRect(const NVRenderRect &) override {} + void SetClearColor(const QT3DSVec4 *) override {} + void Clear(NVRenderClearFlags) override {} + NVRenderBackendBufferObject CreateBuffer(size_t, NVRenderBufferBindFlags, + NVRenderBufferUsageType::Enum, const void *) override + { + return NVRenderBackendBufferObject(1); + } + void BindBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override {} + void ReleaseBuffer(NVRenderBackendBufferObject) override {} + + void UpdateBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, + NVRenderBufferUsageType::Enum, const void *) override + { + } + void UpdateBufferRange(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, + const void *) override + { + } + void *MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, + NVRenderBufferAccessFlags) override + { + return NULL; + } + bool UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override { return true; } + void SetMemoryBarrier(NVRenderBufferBarrierFlags) override {} + NVRenderBackendQueryObject CreateQuery() override { return NVRenderBackendQueryObject(1); } + void ReleaseQuery(NVRenderBackendQueryObject) override {} + void BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} + void EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} + void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, + QT3DSU32 *) override {} + void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, + QT3DSU64 *) override {} + void SetQueryTimer(NVRenderBackendQueryObject) override {} + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) override + { + return NVRenderBackendSyncObject(1); + }; + void ReleaseSync(NVRenderBackendSyncObject) override {} + void WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, QT3DSU64) override {} + NVRenderBackendRenderTargetObject CreateRenderTarget() override + { + return NVRenderBackendRenderTargetObject(1); + } + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject) override {} + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendRenderbufferObject) override + { + } + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum) override + { + } + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) override + { + } + void SetRenderTarget(NVRenderBackendRenderTargetObject) override {} + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject) override { return false; } + void SetReadTarget(NVRenderBackendRenderTargetObject) override {} + void SetDrawBuffers(NVRenderBackendRenderTargetObject, NVConstDataRef) override {} + void SetReadBuffer(NVRenderBackendRenderTargetObject, NVReadFaces::Enum) override {} + + void BlitFramebuffer(QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, + NVRenderClearFlags, NVRenderTextureMagnifyingOp::Enum) override + { + } + NVRenderBackendRenderbufferObject CreateRenderbuffer(NVRenderRenderBufferFormats::Enum, + size_t, size_t) override + { + return NVRenderBackendRenderbufferObject(1); + } + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject) override {} + + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject, + NVRenderRenderBufferFormats::Enum, size_t, size_t) override + { + return false; + } + NVRenderBackendTextureObject CreateTexture() override { return NVRenderBackendTextureObject(1); } + + void SetTextureData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + NVRenderTextureFormats::Enum, const void *) override + { + } + void SetTextureDataCubeFace(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + NVRenderTextureFormats::Enum, const void *) override + { + } + void CreateTextureStorage2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t) override + { + } + void SetTextureSubData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, QT3DSI32, QT3DSI32, size_t, size_t, + NVRenderTextureFormats::Enum, const void *) override + { + } + void SetCompressedTextureData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + size_t, const void *) override + { + } + void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, + QT3DSI32, size_t, const void *) override + { + } + void SetCompressedTextureSubData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, QT3DSI32, QT3DSI32, + size_t, size_t, NVRenderTextureFormats::Enum, size_t, + const void *) override + { + } + void SetMultisampledTextureData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, size_t, + NVRenderTextureFormats::Enum, size_t, size_t, bool) override + { + } + void SetTextureData3D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, size_t, + QT3DSI32, NVRenderTextureFormats::Enum, const void *) override + { + } + void GenerateMipMaps(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + NVRenderHint::Enum) override + { + } + void BindTexture(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, QT3DSU32) override + { + } + void BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, QT3DSI32, + NVRenderImageAccessType::Enum, NVRenderTextureFormats::Enum) override + { + } + void ReleaseTexture(NVRenderBackendTextureObject) override {} + + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum) const override + { + return NVRenderTextureSwizzleMode::NoSwizzle; + } + + virtual NVRenderBackendSamplerObject + CreateSampler(NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, + NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, + NVRenderTextureCoordOp::Enum, QT3DSI32, QT3DSI32, QT3DSF32, + NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, QT3DSF32, QT3DSF32 *) override + { + return NVRenderBackendSamplerObject(1); + } + + void UpdateSampler(NVRenderBackendSamplerObject, NVRenderTextureTargetType::Enum, + NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, + NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, + NVRenderTextureCoordOp::Enum, QT3DSF32, QT3DSF32, QT3DSF32, + NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, + QT3DSF32, QT3DSF32 *) override + { + } + + void UpdateTextureObject(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSI32, QT3DSI32) override + { + } + + void UpdateTextureSwizzle(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + NVRenderTextureSwizzleMode::Enum) override + { + } + + void ReleaseSampler(NVRenderBackendSamplerObject) override {} + + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef) override + { + return NVRenderBackendAttribLayoutObject(1); + } + + void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject) override {} + + NVRenderBackendInputAssemblerObject CreateInputAssembler( + NVRenderBackendAttribLayoutObject, NVConstDataRef, + const NVRenderBackendBufferObject, NVConstDataRef, NVConstDataRef, QT3DSU32) override + { + return NVRenderBackendInputAssemblerObject(1); + } + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject) override {} + bool SetInputAssembler(NVRenderBackendInputAssemblerObject, + NVRenderBackendShaderProgramObject) override + { + return false; + } + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override {} + NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendVertexShaderObject(1); + } + void ReleaseVertexShader(NVRenderBackendVertexShaderObject) override {} + NVRenderBackendFragmentShaderObject CreateFragmentShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendFragmentShaderObject(1); + } + void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject) override {} + NVRenderBackendTessControlShaderObject CreateTessControlShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendTessControlShaderObject(1); + } + void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject) override {} + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef, eastl::string &, bool) override + { + return NVRenderBackendTessEvaluationShaderObject(1); + } + void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject) override {} + NVRenderBackendGeometryShaderObject CreateGeometryShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendGeometryShaderObject(1); + } + void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject) override {} + NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef, + eastl::string &, bool) override + { + return NVRenderBackendComputeShaderObject(1); + } + void ReleaseComputeShader(NVRenderBackendComputeShaderObject) override {} + void AttachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendFragmentShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessControlShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessEvaluationShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendGeometryShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendComputeShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendFragmentShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessControlShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessEvaluationShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendGeometryShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendComputeShaderObject) override + { + } + NVRenderBackendShaderProgramObject CreateShaderProgram(bool) override + { + return NVRenderBackendShaderProgramObject(1); + } + void ReleaseShaderProgram(NVRenderBackendShaderProgramObject) override {} + NVRenderBackendProgramPipeline CreateProgramPipeline() override + { + return NVRenderBackendProgramPipeline(1); + } + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline) override {} + + bool LinkProgram(NVRenderBackendShaderProgramObject, eastl::string &) override { return false; } + void SetActiveProgram(NVRenderBackendShaderProgramObject) override {} + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline) override {} + void SetProgramStages(NVRenderBackendProgramPipeline, NVRenderShaderTypeFlags, + NVRenderBackendShaderProgramObject) override {} + void DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSU32) override {} + QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSI32 *, + NVRenderShaderDataTypes::Enum *, QT3DSI32 *, char *) override + { + return 0; + } + + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return 0; + } + + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSI32 *) override + { + } + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject, QT3DSU32, + QT3DSU32 *, QT3DSI32 *, QT3DSI32 *, QT3DSI32 *) override {} + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32) override {} + void ProgramSetConstantBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject) override { return 0; }; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return -1; + } + void ProgramSetStorageBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return -1; + }; + void ProgramSetAtomicCounterBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + void SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32, + NVRenderShaderDataTypes::Enum, QT3DSI32, const void *, bool) override + { + } + + void Draw(NVRenderDrawMode::Enum, QT3DSU32, QT3DSU32) override {} + void DrawIndirect(NVRenderDrawMode::Enum, const void *) override {} + + void DrawIndexed(NVRenderDrawMode::Enum, QT3DSU32, NVRenderComponentTypes::Enum, + const void *) override + { + } + void DrawIndexedIndirect(NVRenderDrawMode::Enum, NVRenderComponentTypes::Enum, + const void *) override + { + } + + void ReadPixel(NVRenderBackendRenderTargetObject, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, + NVRenderReadPixelFormats::Enum, void *) override + { + } + + NVRenderBackendPathObject CreatePathNVObject(size_t) override + { + return NVRenderBackendPathObject(1); + }; + void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef, + NVConstDataRef) override + { + } + + ///< Bounds of the fill and stroke + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + + /** + * Defaults to 0 if unset. + */ + void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} + void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} + void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} + + void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} + void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} + void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} + void ReleasePathNVObject(NVRenderBackendPathObject, size_t) override {} + + void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, QT3DSF32) override + { + } + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, + QT3DSF32) override + { + return NVRenderPathReturnValues::FontUnavailable; + } + NVRenderBackendPathObject LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, + const void *, + NVRenderPathFontStyleFlags, + NVRenderBackendPathObject, QT3DSF32, + QT3DSU32 *) override + { + return NVRenderBackendPathObject(1); + } + void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override + { + } + void GetPathMetrics(NVRenderBackendPathObject, size_t, NVRenderPathGlyphFontMetricFlags, + NVRenderPathFormatType::Enum, const void *, size_t, QT3DSF32 *) override + { + } + void GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override + { + } + void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, + NVRenderPathTransformType::Enum, QT3DSF32 *) override + { + } + + void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, QT3DSI32, + QT3DSU32, NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + QSurfaceFormat format() const override + { + return QSurfaceFormat(); + } +}; +} + +NVRenderBackend &NVRenderBackendNULL::CreateBackend(NVFoundationBase &foundation) +{ + return *QT3DS_NEW(foundation.getAllocator(), SNullBackend)(foundation); +} diff --git a/src/render/backends/software/Qt3DSRenderBackendNULL.h b/src/render/backends/software/Qt3DSRenderBackendNULL.h new file mode 100644 index 0000000..397ecfb --- /dev/null +++ b/src/render/backends/software/Qt3DSRenderBackendNULL.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_NULL_H +#define QT3DS_RENDER_BACKEND_NULL_H +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderBackendNULL : public NVRenderBackend + { + public: + static NVRenderBackend &CreateBackend(NVFoundationBase &foundation); + }; +} +} + +#endif \ No newline at end of file -- cgit v1.2.3