summaryrefslogtreecommitdiffstats
path: root/tests/auto/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/runtime')
-rw-r--r--tests/auto/runtime/Qt3DSRenderTestBase.cpp101
-rw-r--r--tests/auto/runtime/Qt3DSRenderTestBase.h164
-rw-r--r--tests/auto/runtime/Qt3DSRenderTestMathUtil.cpp118
-rw-r--r--tests/auto/runtime/Qt3DSRenderTestMathUtil.h50
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.cpp248
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.h59
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.cpp251
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.h59
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.cpp332
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.h62
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestClear.cpp131
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestClear.h56
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.cpp847
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.h63
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.cpp358
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.h60
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestPrimitives.cpp321
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestPrimitives.h77
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.cpp401
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.h60
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestTexture2D.cpp288
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestTexture2D.h67
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.cpp436
-rw-r--r--tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.h64
-rw-r--r--tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.cpp636
-rw-r--r--tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.h61
-rw-r--r--tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.cpp299
-rw-r--r--tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.h67
-rw-r--r--tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.cpp390
-rw-r--r--tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.h60
-rw-r--r--tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.cpp367
-rw-r--r--tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.h66
-rw-r--r--tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.cpp560
-rw-r--r--tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.h60
-rw-r--r--tests/auto/runtime/images/NVRenderTestAttribBuffers.pngbin0 -> 3820 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestBackendQuery.pngbin0 -> 2355 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestClear.pngbin0 -> 2327 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestComputeShader.pngbin0 -> 3889 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestDrawIndirectBuffer.pngbin0 -> 2355 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestFboMsaa.pngbin0 -> 3168 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestGeometryShader.pngbin0 -> 3311 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestOcclusionQuery.pngbin0 -> 2355 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestProgramPipeline.pngbin0 -> 3224 bytes
-rw-r--r--tests/auto/runtime/images/NVRenderTestTexture2D.pngbin0 -> 2991 bytes
-rw-r--r--tests/auto/runtime/runtime.pro82
-rw-r--r--tests/auto/runtime/runtime.qrc14
-rw-r--r--tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp469
-rw-r--r--tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.h55
-rw-r--r--tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.cpp574
-rw-r--r--tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.h56
-rw-r--r--tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.cpp155
-rw-r--r--tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.h55
-rw-r--r--tests/auto/runtime/tst_qt3dsruntime.cpp727
-rw-r--r--tests/auto/runtime/tst_qt3dsruntime.h144
54 files changed, 9570 insertions, 0 deletions
diff --git a/tests/auto/runtime/Qt3DSRenderTestBase.cpp b/tests/auto/runtime/Qt3DSRenderTestBase.cpp
new file mode 100644
index 0000000..f4ab079
--- /dev/null
+++ b/tests/auto/runtime/Qt3DSRenderTestBase.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestBase.h"
+
+#include "Qt3DSDMPrefix.h"
+#include "EASTL/allocator.h"
+
+namespace eastl
+{
+void AssertionFailure(const char* pExpression)
+{
+ Q_UNUSED(pExpression);
+}
+EmptyString gEmptyString;
+void* gpEmptyBucketArray[2] = { nullptr, (void*)uintptr_t(~0) };
+}
+
+namespace qt3ds {
+
+void Qt3DSAssert(const char *exp, const char *file, int line, bool *ignore)
+{
+ Q_UNUSED(ignore)
+ qFatal("Assertion thrown %s(%d): %s", file, line, exp);
+}
+
+namespace render {
+SEndlType Endl;
+}
+}
+
+void *operator new[](size_t size, const char *, int, unsigned, const char *, int)
+{
+ return malloc(size);
+}
+
+void *operator new[](size_t size, size_t, size_t, const char *, int, unsigned, const char *, int)
+{
+ return malloc(size);
+}
+
+using namespace qt3ds::render;
+
+namespace qt3ds {
+namespace render {
+
+NVRenderTestBase::~NVRenderTestBase()
+{
+ delete m_renderImpl;
+}
+
+bool NVRenderTestBase::initializeQt3DSRenderer(QSurfaceFormat format)
+{
+ m_coreFactory = qt3ds::render::IQt3DSRenderFactoryCore::CreateRenderFactoryCore("", m_windowSystem,
+ m_timeProvider);
+ m_factory = m_coreFactory->CreateRenderFactory(format, false);
+ m_rc = m_factory->GetQt3DSRenderContext();
+ m_renderImpl = new qt3ds::render::Qt3DSRendererImpl(*m_rc);
+
+ return true;
+}
+
+Qt3DSRendererImpl *NVRenderTestBase::qt3dsRenderer()
+{
+ return m_renderImpl;
+}
+
+Q3DStudio::IRuntimeMetaData *NVRenderTestBase::metadata()
+{
+ if (m_metaData.mPtr == NULL)
+ m_metaData = &Q3DStudio::IRuntimeMetaData::Create(m_coreFactory->GetInputStreamFactory());
+ return m_metaData.mPtr;
+}
+
+}
+}
diff --git a/tests/auto/runtime/Qt3DSRenderTestBase.h b/tests/auto/runtime/Qt3DSRenderTestBase.h
new file mode 100644
index 0000000..bde0948
--- /dev/null
+++ b/tests/auto/runtime/Qt3DSRenderTestBase.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_BASE_H
+#define QT3DS_RENDER_TEST_BASE_H
+#include "foundation/Qt3DS.h"
+#include "foundation/Qt3DSAssert.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderContext.h"
+#include "Qt3DSWindowSystem.h"
+#include "Qt3DSTypes.h"
+#include "Qt3DSTimer.h"
+#include "Qt3DSRenderRuntimeBinding.h"
+#include "Qt3DSRenderRuntimeBindingImpl.h"
+#include "Qt3DSRenderContextCore.h"
+#include "rendererimpl/Qt3DSRendererImpl.h"
+#include "Qt3DSMetadata.h"
+
+namespace qt3ds {
+namespace render {
+class IQt3DSRenderer;
+class Qt3DSRendererImpl;
+class IQt3DSRenderFactoryCore;
+class IQt3DSRenderFactory;
+}
+}
+
+namespace qt3ds {
+namespace render {
+
+ class IQt3DSRenderFactoryCore;
+ class IQt3DSRenderFactory;
+ class Qt3DSRenderer;
+
+ typedef struct SUSER_CONTEXT_DATA
+ {
+ unsigned int winWidth;
+ unsigned int winHeight;
+ } userContextData;
+
+ struct SNullTimeProvider : public Q3DStudio::ITimeProvider
+ {
+ virtual Q3DStudio::INT64 GetCurrentTimeMicroSeconds() { return 0; }
+ };
+
+ struct SNullWindowSystem : public Q3DStudio::IWindowSystem
+ {
+ virtual QSize GetWindowDimensions() { return QSize(); }
+
+ virtual void SetWindowDimensions(const QSize &) {}
+ // For platforms that support it, we get the egl info for render plugins
+ // Feel free to return NULL.
+ virtual Q3DStudio::SEGLInfo *GetEGLInfo() { return NULL; }
+
+ // on some systems we allow our default render target to be a offscreen buffer
+ // otherwise return 0;
+ virtual int GetDefaultRenderTargetID() { return 0; }
+ // returns the depth buffer bit count for the render window
+ // does not really matter here
+ virtual int GetDepthBitCount() { return 16; }
+ };
+
+ /// this is the base class for all tests
+ class NVRenderTestBase
+ {
+ public:
+ /// constructor
+ NVRenderTestBase(){}
+ /// destructor
+ virtual ~NVRenderTestBase();
+
+ /// Checks if this test is supported
+ ///
+ /// @return true if supported
+ virtual bool isSupported(NVRenderContext *context) = 0;
+
+ /// This runs the test
+ ///
+ /// @param context (in) Pointer to a NVRenderContext context
+ /// @param pUserData (in) Pointer to pUserData
+ ///
+ /// @return false if failed
+ virtual bool run(NVRenderContext *context, userContextData *pUserData) = 0;
+
+ /// This cleans up state after the test if needed
+ ///
+ /// @param context (in) Pointer to a NVRenderContext context
+ /// @param pUserData (in) Pointer to pUserData
+ ///
+ /// @return false if failed
+ virtual void cleanup(NVRenderContext *context, userContextData *pUserData) = 0;
+
+ /// This runs the performance test
+ ///
+ /// @param context (in) Pointer to a NVRenderContext context
+ /// @param pUserData (in) Pointer to pUserData
+ ///
+ /// @return false if failed
+ virtual bool runPerformance(NVRenderContext *context, userContextData *pContextData) = 0;
+
+ /// This is a query to determine if we run on a ES context
+ ///
+ /// @param context (in) Pointer to a NVRenderContext context
+ ///
+ /// @return false if failed
+ virtual const bool isGLESContext(NVRenderContext *context)
+ {
+ NVRenderContextType ctxType = context->GetRenderContextType();
+
+ // Need minimum of GL3 or GLES3
+ if (ctxType == NVRenderContextValues::GLES2 || ctxType == NVRenderContextValues::GLES3
+ || ctxType == NVRenderContextValues::GLES3PLUS) {
+ return true;
+ }
+
+ return false;
+ }
+
+ bool initializeQt3DSRenderer(QSurfaceFormat format);
+ qt3ds::render::Qt3DSRendererImpl *qt3dsRenderer();
+ Q3DStudio::IRuntimeMetaData *metadata();
+
+ private:
+
+ NVScopedRefCounted<qt3ds::render::IQt3DSRenderFactoryCore> m_coreFactory;
+ NVScopedRefCounted<qt3ds::render::IQt3DSRenderFactory> m_factory;
+ NVScopedRefCounted<qt3ds::render::IQt3DSRenderContext> m_rc;
+ qt3ds::foundation::NVScopedReleasable<Q3DStudio::IRuntimeMetaData> m_metaData;
+ qt3ds::render::Qt3DSRendererImpl *m_renderImpl;
+
+ SNullTimeProvider m_timeProvider;
+ SNullWindowSystem m_windowSystem;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_BASE_H
diff --git a/tests/auto/runtime/Qt3DSRenderTestMathUtil.cpp b/tests/auto/runtime/Qt3DSRenderTestMathUtil.cpp
new file mode 100644
index 0000000..f216faa
--- /dev/null
+++ b/tests/auto/runtime/Qt3DSRenderTestMathUtil.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestMathUtil.h"
+#include <math.h>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+#define QT3DS_RENDER_TEST_PI 3.14159265358979323846f
+
+inline float degreeToRad(float degree)
+{
+ return (degree * QT3DS_RENDER_TEST_PI) / 180.0f;
+}
+
+void qt3ds::render::NvRenderTestMatrixFrustum(QT3DSMat44 *m, float l, float r, float b, float t, float n,
+ float f)
+{
+ float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv, twoNear;
+
+ rightMinusLeftInv = 1.0f / (r - l);
+ topMinusBottomInv = 1.0f / (t - b);
+ farMinusNearInv = 1.0f / (f - n);
+ twoNear = 2.0f * n;
+
+ m->column0 = QT3DSVec4(twoNear * rightMinusLeftInv, 0, 0, 0);
+ m->column1 = QT3DSVec4(0, twoNear * topMinusBottomInv, 0, 0);
+ m->column2 = QT3DSVec4((r + l) * rightMinusLeftInv, (t + b) * topMinusBottomInv,
+ -(f + n) * farMinusNearInv, -1.0f);
+ m->column3 = QT3DSVec4(0, 0, -(twoNear * f) * farMinusNearInv, 0.0f);
+}
+
+void qt3ds::render::NvGl2DemoMatrixOrtho(QT3DSMat44 *m, float l, float r, float b, float t, float n,
+ float f)
+{
+ float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv;
+
+ rightMinusLeftInv = 1.0f / (r - l);
+ topMinusBottomInv = 1.0f / (t - b);
+ farMinusNearInv = 1.0f / (f - n);
+
+ m->column0 = QT3DSVec4(2.0f * rightMinusLeftInv, 0, 0, 0);
+ m->column1 = QT3DSVec4(0, 2.0f * topMinusBottomInv, 0, 0);
+ m->column2 = QT3DSVec4(0, 0, -2.0f * farMinusNearInv, 0);
+ m->column3 = QT3DSVec4(-(r + l) * rightMinusLeftInv, -(t + b) * topMinusBottomInv,
+ -(f + n) * farMinusNearInv, 1.0f);
+}
+
+void qt3ds::render::NvRenderTestMatrixRotX(QT3DSMat44 *m, float angle)
+{
+ float rad = degreeToRad(angle);
+ float cosPhi = cos(rad);
+ float sinPhi = sin(rad);
+
+ m->column0 = QT3DSVec4(1.0, 0.0, 0.0, 0.0);
+ m->column1 = QT3DSVec4(0.0, cosPhi, -sinPhi, 0.0);
+ m->column2 = QT3DSVec4(0.0, sinPhi, cosPhi, 0.0);
+ m->column3 = QT3DSVec4(0.0, 0.0, 0.0, 1.0);
+}
+
+void qt3ds::render::NvRenderTestMatrixRotY(QT3DSMat44 *m, float angle)
+{
+ float rad = degreeToRad(angle);
+ float cosPhi = cos(rad);
+ float sinPhi = sin(rad);
+
+ m->column0 = QT3DSVec4(cosPhi, 0.0, sinPhi, 0.0);
+ m->column1 = QT3DSVec4(0.0, 1.0, 0.0, 0.0);
+ m->column2 = QT3DSVec4(-sinPhi, 0.0, cosPhi, 0.0);
+ m->column3 = QT3DSVec4(0.0, 0.0, 0.0, 1.0);
+}
+
+void qt3ds::render::NvRenderTestMatrixRotZ(QT3DSMat44 *m, float angle)
+{
+ float rad = degreeToRad(angle);
+ float cosPhi = cos(rad);
+ float sinPhi = sin(rad);
+
+ m->column0 = QT3DSVec4(cosPhi, -sinPhi, 0.0, 0.0);
+ m->column1 = QT3DSVec4(sinPhi, cosPhi, 0.0, 0.0);
+ m->column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0);
+ m->column3 = QT3DSVec4(0.0, 0.0, 0.0, 1.0);
+}
+
+void qt3ds::render::NvRenderTestMatrixTranslation(QT3DSMat44 *m, float x, float y, float z)
+{
+ m->column0 = QT3DSVec4(1.0, 0.0, 0.0, 0.0);
+ m->column1 = QT3DSVec4(0.0, 1.0, 0.0, 0.0);
+ m->column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0);
+ m->column3 = QT3DSVec4(x, y, z, 1.0);
+}
diff --git a/tests/auto/runtime/Qt3DSRenderTestMathUtil.h b/tests/auto/runtime/Qt3DSRenderTestMathUtil.h
new file mode 100644
index 0000000..739209e
--- /dev/null
+++ b/tests/auto/runtime/Qt3DSRenderTestMathUtil.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_MATH_UTIL_H
+#define QT3DS_RENDER_TEST_MATH_UTIL_H
+
+#include "foundation/Qt3DSMat44.h"
+
+namespace qt3ds {
+namespace render {
+
+ void NvRenderTestMatrixFrustum(QT3DSMat44 *m, float l, float r, float b, float t, float n,
+ float f);
+
+ void NvGl2DemoMatrixOrtho(QT3DSMat44 *m, float l, float r, float b, float t, float n, float f);
+
+ void NvRenderTestMatrixRotX(QT3DSMat44 *m, float angle);
+ void NvRenderTestMatrixRotY(QT3DSMat44 *m, float angle);
+ void NvRenderTestMatrixRotZ(QT3DSMat44 *m, float angle);
+
+ void NvRenderTestMatrixTranslation(QT3DSMat44 *m, float x, float y, float z);
+}
+}
+
+#endif
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.cpp b/tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.cpp
new file mode 100644
index 0000000..9f81214
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestAtomicCounterBuffer.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderAtomicCounterBuffer.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ prog += "layout(binding = 2, offset = 0) uniform atomic_uint ac_raster;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " uint counter = atomicCounterIncrement(ac_raster);\n"
+ " float g = (float(counter)/255.0) / 255.0;\n"
+ " fragColor = vec4(0.0, g, 0.0, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+NVRenderTestAtomicCounterBuffer::NVRenderTestAtomicCounterBuffer()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestAtomicCounterBuffer::~NVRenderTestAtomicCounterBuffer()
+{
+}
+
+bool NVRenderTestAtomicCounterBuffer::isSupported(NVRenderContext *context)
+{
+ // This is currently only supported on GL 4 and GLES 3.1
+ if (!context->IsAtomicCounterBufferSupported())
+ return false;
+
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestAtomicCounterBuffer::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= rasterizerTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestAtomicCounterBuffer::rasterizerTest(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) },
+ { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderAtomicCounterBuffer> mAtomicCounterBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create atomic counter buffer
+ QT3DSU32 acCounter = 0;
+ NVDataRef<QT3DSU8> acData((QT3DSU8 *)&acCounter, sizeof(QT3DSU32));
+ mAtomicCounterBuffer = context->CreateAtomicCounterBuffer(
+ "ac_buffer", NVRenderBufferUsageType::Static, sizeof(QT3DSU32), acData);
+ if (!mAtomicCounterBuffer) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create atomic counter buffer";
+ return false;
+ }
+ // add a parameter
+ CRegisteredString theACName(context->GetStringTable().RegisterStr("ac_raster"));
+ mAtomicCounterBuffer->AddParam(theACName, 0);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestAtomicCounterBuffer shader",
+ toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderAtomicCounterBuffer *> atomicBuffer(
+ "ac_buffer", *compResult.mShader);
+ atomicBuffer.Set();
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestAtomicCounterBuffer::runPerformance(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestAtomicCounterBuffer::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.h b/tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.h
new file mode 100644
index 0000000..87b0910
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestAtomicCounterBuffer.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_ATOMIC_COUNTER_BUFFER_H
+#define QT3DS_RENDER_TEST_ATOMIC_COUNTER_BUFFER_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestAtomicCounterBuffer : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestAtomicCounterBuffer();
+ ~NVRenderTestAtomicCounterBuffer();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool rasterizerTest(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_ATOMIC_COUNTER_BUFFER_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.cpp b/tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.cpp
new file mode 100644
index 0000000..805782f
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.cpp
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestAttribBuffers.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "in vec3 attr_col; // Vertex col\n"
+ "out vec3 color; // output color\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ " color = attr_col;\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ prog += "in vec3 color; // input color\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4( color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+NVRenderTestAttribBuffers::NVRenderTestAttribBuffers()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestAttribBuffers::~NVRenderTestAttribBuffers()
+{
+}
+
+bool NVRenderTestAttribBuffers::isSupported(NVRenderContext *context)
+{
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestAttribBuffers::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= multiAttribBufferTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestAttribBuffers::multiAttribBufferTest(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) },
+ { QT3DSVec3(0.0, 0.9, 0) } };
+
+ static const Vertex vertexColors[] = { { QT3DSVec3(0.0, 1.0, 0.0) },
+ { QT3DSVec3(0.0, 0.6, 0.0) },
+ { QT3DSVec3(0.0, 0.2, 0.0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderVertexBuffer> mColorBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVRenderVertexBuffer *attribBuffers[2];
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestAttribBuffers shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0, 0),
+ NVRenderVertexBufferEntry("attr_col", NVRenderComponentTypes::QT3DSF32, 3, 0, 1),
+ };
+
+ // position buffer
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create vertex buffer";
+ return false;
+ }
+ // color buffer
+ NVDataRef<QT3DSU8> colorData((QT3DSU8 *)vertexColors, bufSize);
+ mColorBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), colorData);
+ if (!mColorBuffer) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create color buffer";
+ return false;
+ }
+
+ attribBuffers[0] = mVertexBuffer;
+ attribBuffers[1] = mColorBuffer;
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 2));
+ // create input Assembler
+ QT3DSU32 strides[2];
+ QT3DSU32 offsets[2];
+ strides[0] = mVertexBuffer->GetStride();
+ offsets[0] = 0;
+ strides[1] = mColorBuffer->GetStride();
+ offsets[1] = 0;
+
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, NVConstDataRef<NVRenderVertexBuffer *>(attribBuffers, 2), NULL,
+ toConstDataRef(strides, 2), toConstDataRef(offsets, 2), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestAttribBuffers::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestAttribBuffers::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.h b/tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.h
new file mode 100644
index 0000000..47e898f
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestAttribBuffers.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_ATTRIB_BUFFERS_H
+#define QT3DS_RENDER_TEST_ATTRIB_BUFFERS_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestAttribBuffers : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestAttribBuffers();
+ ~NVRenderTestAttribBuffers();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool multiAttribBufferTest(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_ATTRIB_BUFFERS_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.cpp b/tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.cpp
new file mode 100644
index 0000000..30f2637
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.cpp
@@ -0,0 +1,332 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestBackendQuery.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *PassthroughVertShader()
+{
+ return "uniform mat4 mat_mvp;\n"
+ "attribute vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+}
+
+static const char *SimpleFragShader()
+{
+ return "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "uniform vec3 color;\n"
+ "void main()\n"
+ "{\n"
+ "gl_FragColor = vec4( color, 1);\n"
+ "}\n";
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+NVRenderTestBackendQuery::NVRenderTestBackendQuery()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestBackendQuery::~NVRenderTestBackendQuery()
+{
+}
+
+bool NVRenderTestBackendQuery::isSupported(NVRenderContext *context)
+{
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestBackendQuery::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= depthBitsTest(context, pUserData);
+ _curTest++;
+ success &= depthBitsFBOTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestBackendQuery::renderQuad(NVRenderContext *context, userContextData *pUserData,
+ QT3DSVec3 color)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestBackendQuery shader", toRef(PassthroughVertShader()),
+ toRef(SimpleFragShader()));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestBackendQuery::depthBitsTest: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestBackendQuery::depthBitsTest: Failed to create input assembler";
+ return false;
+ }
+
+ // check if default buffer bit size is in an acceptable size range
+ // we accept a range from 16 to 32
+ const QT3DSU32 bits = context->GetDepthBits();
+ bool passed = (bits >= 16 && bits <= 32);
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return passed;
+}
+
+bool NVRenderTestBackendQuery::depthBitsTest(NVRenderContext *context, userContextData *pUserData)
+{
+ QT3DSVec3 color(0.0, 0.0, 0.0);
+ // check if default buffer bit size is in an acceptable size range
+ // we accept a range from 16 to 32
+ const QT3DSU32 bits = context->GetDepthBits();
+ bool passed = (bits >= 16 && bits <= 32);
+ if (passed)
+ color.y = 1.0;
+ else
+ color.x = 1.0;
+
+ passed &= renderQuad(context, pUserData, color);
+
+ return passed;
+}
+
+bool NVRenderTestBackendQuery::depthBitsFBOTest(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ // depneding on the context we get different values
+ NVRenderContextType theContextFlags(NVRenderContextValues::GLES2 | NVRenderContextValues::GL2);
+ NVRenderContextType type = context->GetRenderContextType();
+ bool depth16_Only = (type & theContextFlags);
+ // create a FBO
+ NVScopedRefCounted<NVRenderFrameBuffer> m_FBO;
+ NVScopedRefCounted<NVRenderTexture2D> m_ColorTexture;
+ NVScopedRefCounted<NVRenderTexture2D> m_Depth16Texture;
+ NVScopedRefCounted<NVRenderTexture2D> m_Depth24Texture;
+ NVScopedRefCounted<NVRenderTexture2D> m_Depth32Texture;
+ NVScopedRefCounted<NVRenderTexture2D> m_Depth24Stencil8Texture;
+
+ m_ColorTexture = context->CreateTexture2D();
+ m_ColorTexture->SetTextureData(NVDataRef<QT3DSU8>(), 0, 256, 256, NVRenderTextureFormats::RGBA8);
+ m_Depth16Texture = context->CreateTexture2D();
+ m_Depth16Texture->SetTextureData(NVDataRef<QT3DSU8>(), 0, 256, 256,
+ NVRenderTextureFormats::Depth16);
+
+ m_FBO = context->CreateFrameBuffer();
+ m_FBO->Attach(NVRenderFrameBufferAttachments::Color0,
+ NVRenderTextureOrRenderBuffer(*m_ColorTexture));
+ m_FBO->Attach(NVRenderFrameBufferAttachments::Depth,
+ NVRenderTextureOrRenderBuffer(*m_Depth16Texture));
+
+ if (!m_FBO->IsComplete()) {
+ qWarning() << "NVRenderTestBackendQuery::depthBitsFBOTest: Failed to create FBO";
+ return false;
+ }
+
+ context->SetRenderTarget(m_FBO);
+
+ QT3DSVec3 color(0.0, 0.0, 0.0);
+ // check depth bit count
+ QT3DSU32 bits = context->GetDepthBits();
+ QT3DSU32 bitsExpected = 16;
+ bool passed = (bits == bitsExpected);
+
+ // detach depth
+ m_FBO->Attach(NVRenderFrameBufferAttachments::Depth, NVRenderTextureOrRenderBuffer());
+
+ m_Depth24Texture = context->CreateTexture2D();
+ m_Depth24Texture->SetTextureData(NVDataRef<QT3DSU8>(), 0, 256, 256,
+ NVRenderTextureFormats::Depth24);
+ m_FBO->Attach(NVRenderFrameBufferAttachments::Depth,
+ NVRenderTextureOrRenderBuffer(*m_Depth24Texture));
+ if (!m_FBO->IsComplete()) {
+ qWarning() << "NVRenderTestBackendQuery::depthBitsFBOTest: Failed to create FBO";
+ return false;
+ }
+ // check depth bit count
+ bits = context->GetDepthBits();
+ bitsExpected = (depth16_Only) ? 16 : 24;
+ passed &= (bits == bitsExpected);
+
+ // detach depth
+ m_FBO->Attach(NVRenderFrameBufferAttachments::Depth, NVRenderTextureOrRenderBuffer());
+
+ m_Depth32Texture = context->CreateTexture2D();
+ m_Depth32Texture->SetTextureData(NVDataRef<QT3DSU8>(), 0, 256, 256,
+ NVRenderTextureFormats::Depth32);
+ m_FBO->Attach(NVRenderFrameBufferAttachments::Depth,
+ NVRenderTextureOrRenderBuffer(*m_Depth32Texture));
+ if (!m_FBO->IsComplete()) {
+ qWarning() << "NVRenderTestBackendQuery::depthBitsFBOTest: Failed to create FBO";
+ return false;
+ }
+ // check depth bit count
+ bits = context->GetDepthBits();
+ bitsExpected = (depth16_Only) ? 16 : 32;
+ passed &= (bits == bitsExpected);
+
+ // detach depth
+ m_FBO->Attach(NVRenderFrameBufferAttachments::Depth, NVRenderTextureOrRenderBuffer());
+
+ // only test depth stencil if supported
+ if (context->IsDepthStencilSupported()) {
+ m_Depth24Stencil8Texture = context->CreateTexture2D();
+ m_Depth24Stencil8Texture->SetTextureData(NVDataRef<QT3DSU8>(), 0, 256, 256,
+ NVRenderTextureFormats::Depth24Stencil8);
+ m_FBO->Attach(NVRenderFrameBufferAttachments::DepthStencil,
+ NVRenderTextureOrRenderBuffer(*m_Depth24Stencil8Texture));
+ if (!m_FBO->IsComplete()) {
+ qWarning() << "NVRenderTestBackendQuery::depthBitsFBOTest: Failed to create FBO";
+ return false;
+ }
+ // check depth bit count
+ bits = context->GetDepthBits();
+ bitsExpected = (depth16_Only) ? 16 : 24;
+ passed &= (bits == bitsExpected);
+ }
+
+ context->SetRenderTarget(NULL);
+
+ if (passed)
+ color.y = 1.0;
+ else
+ color.x = 1.0;
+
+ passed &= renderQuad(context, pUserData, color);
+
+ return passed;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestBackendQuery::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestBackendQuery::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.h b/tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.h
new file mode 100644
index 0000000..e5fde64
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestBackendQuery.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_BACKEND_QUERY_H
+#define QT3DS_RENDER_TEST_BACKEND_QUERY_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestBackendQuery : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestBackendQuery();
+ ~NVRenderTestBackendQuery();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool depthBitsTest(NVRenderContext *context, userContextData *pUserData);
+ bool depthBitsFBOTest(NVRenderContext *context, userContextData *pUserData);
+
+ bool renderQuad(NVRenderContext *context, userContextData *pUserData, QT3DSVec3 color);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_CONSTANT_BUFFER_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestClear.cpp b/tests/auto/runtime/base/Qt3DSRenderTestClear.cpp
new file mode 100644
index 0000000..3e80d40
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestClear.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestClear.h"
+#include "foundation/Qt3DSVec4.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+NVRenderTestClear::NVRenderTestClear()
+{
+}
+
+NVRenderTestClear::~NVRenderTestClear()
+{
+}
+
+bool NVRenderTestClear::isSupported(NVRenderContext *context)
+{
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+static bool checkColor(int width, int height, unsigned char *pixels, const QT3DSVec3 &color)
+{
+ unsigned char *pSrc = pixels;
+
+ for (int h = 0; h < height; h++) {
+ for (int w = 0; w < width; w++) {
+ if (pSrc[0] != (unsigned char)color.x || pSrc[1] != (unsigned char)color.y
+ || pSrc[2] != (unsigned char)color.z) {
+ return false;
+ }
+
+ pSrc += 3;
+ }
+ }
+
+ return true;
+}
+
+bool NVRenderTestClear::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+
+ success &= testColorClear(context, pUserData);
+
+ // if successful draw green otherwise a red
+ if (success) {
+ // set clear color to green
+ context->SetClearColor(QT3DSVec4(0.0f, 1.0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color));
+ } else {
+ // set clear color to green
+ context->SetClearColor(QT3DSVec4(1.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color));
+ }
+
+ return success;
+}
+
+bool NVRenderTestClear::testColorClear(NVRenderContext *context, userContextData *pUserData)
+{
+ // allocate buffer for readback
+ NVAllocatorCallback &alloc(context->GetFoundation().getAllocator());
+ QT3DSU32 size = pUserData->winHeight * pUserData->winHeight * 3 * sizeof(QT3DSU8);
+ QT3DSU8 *pixels = (QT3DSU8 *)alloc.allocate(size, "testColorClear color clear", __FILE__, __LINE__);
+
+ if (!pixels)
+ return false;
+
+ // set clear color to yellow
+ context->SetClearColor(QT3DSVec4(1.0f, 1.0f, .0f, 0.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color));
+
+ // read back pixels
+ context->ReadPixels(NVRenderRect(0, 0, pUserData->winHeight, pUserData->winHeight),
+ NVRenderReadPixelFormats::RGB8, NVDataRef<QT3DSU8>(pixels, size));
+ // check color
+ bool passed =
+ checkColor(pUserData->winHeight, pUserData->winHeight, pixels, QT3DSVec3(255.0f, 255.0f, .0f));
+
+ alloc.deallocate(pixels);
+
+ return passed;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestClear::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestClear::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestClear.h b/tests/auto/runtime/base/Qt3DSRenderTestClear.h
new file mode 100644
index 0000000..6113b7b
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestClear.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_CLEAR_H
+#define QT3DS_RENDER_TEST_CLEAR_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the render target clearing
+ class NVRenderTestClear : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestClear();
+ ~NVRenderTestClear();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextDat);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ /// subtests
+ bool testColorClear(NVRenderContext *context, userContextData *pUserData);
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_CLEAR_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.cpp b/tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.cpp
new file mode 100644
index 0000000..8b6cb34
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.cpp
@@ -0,0 +1,847 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestConstantBuffer.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const char *scalarVertShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "layout (std140) uniform cbBuffer { \n"
+ "float red;\n"
+ "float green;\n"
+ "mat4 mat_mvp;\n"
+ "float blue;\n };\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *scalarFragShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "layout (std140) uniform cbBuffer { \n"
+ "float red;\n"
+ "float green;\n"
+ "mat4 mat_mvp;\n"
+ "float blue;\n };\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(red, green, blue, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *vectorVertShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "layout (std140) uniform cbBuffer { \n"
+ "vec2 rg;\n"
+ "mat4 mat_mvp;\n"
+ "vec2 ba;\n };\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *vectorFragShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "layout (std140) uniform cbBuffer { \n"
+ "vec2 rg;\n"
+ "mat4 mat_mvp;\n"
+ "vec2 ba;\n };\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(rg[0], rg[1], ba[0], ba[1]);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *structVertShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "struct sampleStruct {\n"
+ "vec2 rg;\n"
+ "mat4 mat_mvp;\n"
+ "float blue;\n"
+ "float alpha; };\n"
+ "layout (std140) uniform cbBuffer { \n"
+ "sampleStruct s[2]; };\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = s[0].mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *structFragShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "struct sampleStruct {\n"
+ "vec2 rg;\n"
+ "mat4 mat_mvp;\n"
+ "float blue;\n"
+ "float alpha; };\n"
+ "layout (std140) uniform cbBuffer { \n"
+ "sampleStruct s[2]; };\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(s[0].rg[0], s[0].rg[1], s[0].blue, s[0].alpha);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *multiCBVertShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "layout (std140) uniform cbBufferTrans { \n"
+ "mat4 mat_mvp;\n };\n"
+ "layout (std140) uniform cbBufferCol { \n"
+ "float red;\n"
+ "float green;\n"
+ "float blue;\n };\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *multiCBFragShader(bool bESContext, std::string &prog)
+{
+ if (bESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330 compatibility\n";
+ }
+
+ prog += "layout (std140) uniform cbBufferTrans { \n"
+ "mat4 mat_mvp;\n };\n"
+ "layout (std140) uniform cbBufferCol { \n"
+ "float red;\n"
+ "float green;\n"
+ "float blue;\n };\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(red, green, blue, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+NVRenderTestConstantBuffer::NVRenderTestConstantBuffer()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestConstantBuffer::~NVRenderTestConstantBuffer()
+{
+}
+
+bool NVRenderTestConstantBuffer::isSupported(NVRenderContext *context)
+{
+ NVRenderContextType ctxType = context->GetRenderContextType();
+ NVRenderContextType nonSupportedFlags(NVRenderContextValues::GL2
+ | NVRenderContextValues::GLES2);
+
+ // This is currently only supported on GL(Es) >= 3
+ if ((ctxType & nonSupportedFlags))
+ return false;
+
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestConstantBuffer::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= scalarTest(context, pUserData);
+ _curTest++;
+ success &= vectorTest(context, pUserData);
+ _curTest++;
+ success &= structTest(context, pUserData);
+ _curTest++;
+ success &= rawTest(context, pUserData);
+ _curTest++;
+ success &= multiCBTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestConstantBuffer::scalarTest(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderConstantBuffer> mConstantBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create constant buffer referred in the program
+ mConstantBuffer = context->CreateConstantBuffer("cbBuffer", NVRenderBufferUsageType::Static, 0,
+ NVDataRef<QT3DSU8>());
+ // buffer parameter. They must be in the order of appearance
+ CRegisteredString theRedName(context->GetStringTable().RegisterStr("red"));
+ mConstantBuffer->AddParam(theRedName, NVRenderShaderDataTypes::QT3DSF32, 1);
+ CRegisteredString theGreenName(context->GetStringTable().RegisterStr("green"));
+ mConstantBuffer->AddParam(theGreenName, NVRenderShaderDataTypes::QT3DSF32, 1);
+ CRegisteredString theMatName(context->GetStringTable().RegisterStr("mat_mvp"));
+ mConstantBuffer->AddParam(theMatName, NVRenderShaderDataTypes::QT3DSMat44, 1);
+ CRegisteredString theBlueName(context->GetStringTable().RegisterStr("blue"));
+ mConstantBuffer->AddParam(theBlueName, NVRenderShaderDataTypes::QT3DSF32, 1);
+
+ // set values
+ QT3DSF32 red = 0.0;
+ mConstantBuffer->UpdateParam("red", NVDataRef<QT3DSU8>((QT3DSU8 *)&red, 1));
+ QT3DSF32 green = 1.0;
+ mConstantBuffer->UpdateParam("green", NVDataRef<QT3DSU8>((QT3DSU8 *)&green, 1));
+ QT3DSF32 blue = 0.0;
+ mConstantBuffer->UpdateParam("blue", NVDataRef<QT3DSU8>((QT3DSU8 *)&blue, 1));
+ mConstantBuffer->UpdateParam("mat_mvp", NVDataRef<QT3DSU8>((QT3DSU8 *)mvp.front(), 1));
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestConstantBuffer::scalarTest",
+ toRef(scalarVertShader(isGLESContext(context), vtxProg)),
+ toRef(scalarFragShader(isGLESContext(context), frgProg)));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestConstantBuffer::scalarTest: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestConstantBuffer::scalarTest: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderConstantBuffer *> cb("cbBuffer",
+ *compResult.mShader);
+ mConstantBuffer->Update();
+ cb.Set();
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestConstantBuffer::vectorTest(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderConstantBuffer> mConstantBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create constant buffer referred in the program
+ mConstantBuffer = context->CreateConstantBuffer("cbBuffer", NVRenderBufferUsageType::Static, 0,
+ NVDataRef<QT3DSU8>());
+ // buffer parameter. They must be in the order of appearance
+ CRegisteredString theRGName(context->GetStringTable().RegisterStr("rg"));
+ mConstantBuffer->AddParam(theRGName, NVRenderShaderDataTypes::QT3DSVec2, 1);
+ CRegisteredString theMatName(context->GetStringTable().RegisterStr("mat_mvp"));
+ mConstantBuffer->AddParam(theMatName, NVRenderShaderDataTypes::QT3DSMat44, 1);
+ CRegisteredString theBAName(context->GetStringTable().RegisterStr("ba"));
+ mConstantBuffer->AddParam(theBAName, NVRenderShaderDataTypes::QT3DSVec2, 1);
+
+ // set values
+ QT3DSVec2 rg;
+ rg[0] = 0.0;
+ rg[1] = 1.0;
+ mConstantBuffer->UpdateParam("rg", NVDataRef<QT3DSU8>((QT3DSU8 *)&rg, 1));
+ QT3DSVec2 ba;
+ ba[0] = 0.0;
+ ba[1] = 1.0;
+ mConstantBuffer->UpdateParam("ba", NVDataRef<QT3DSU8>((QT3DSU8 *)&ba, 1));
+ mConstantBuffer->UpdateParam("mat_mvp", NVDataRef<QT3DSU8>((QT3DSU8 *)mvp.front(), 1));
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestConstantBuffer::vectorTest",
+ toRef(vectorVertShader(isGLESContext(context), vtxProg)),
+ toRef(vectorFragShader(isGLESContext(context), frgProg)));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestConstantBuffer::vectorTest: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestConstantBuffer::vectorTest: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderConstantBuffer *> cb("cbBuffer",
+ *compResult.mShader);
+ cb.Set();
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestConstantBuffer::structTest(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderConstantBuffer> mConstantBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create constant buffer referred in the program
+ mConstantBuffer = context->CreateConstantBuffer("cbBuffer", NVRenderBufferUsageType::Static, 0,
+ NVDataRef<QT3DSU8>());
+ // buffer parameter. They must be in the order of appearance
+ CRegisteredString theRGName(context->GetStringTable().RegisterStr("s[0].rg"));
+ mConstantBuffer->AddParam(theRGName, NVRenderShaderDataTypes::QT3DSVec2, 1);
+ CRegisteredString theMatName(context->GetStringTable().RegisterStr("s[0].mat_mvp"));
+ mConstantBuffer->AddParam(theMatName, NVRenderShaderDataTypes::QT3DSMat44, 1);
+ CRegisteredString theBlueName(context->GetStringTable().RegisterStr("s[0].blue"));
+ mConstantBuffer->AddParam(theBlueName, NVRenderShaderDataTypes::QT3DSF32, 1);
+ CRegisteredString theAlphaName(context->GetStringTable().RegisterStr("s[0].alpha"));
+ mConstantBuffer->AddParam(theAlphaName, NVRenderShaderDataTypes::QT3DSF32, 1);
+
+ // set values
+ QT3DSVec2 rg;
+ rg[0] = 0.0;
+ rg[1] = 1.0;
+ mConstantBuffer->UpdateParam("s[0].rg", NVDataRef<QT3DSU8>((QT3DSU8 *)&rg, 1));
+ QT3DSF32 blue, alpha;
+ blue = 0.0;
+ alpha = 1.0;
+ mConstantBuffer->UpdateParam("s[0].blue", NVDataRef<QT3DSU8>((QT3DSU8 *)&blue, 1));
+ mConstantBuffer->UpdateParam("s[0].alpha", NVDataRef<QT3DSU8>((QT3DSU8 *)&alpha, 1));
+ mConstantBuffer->UpdateParam("s[0].mat_mvp", NVDataRef<QT3DSU8>((QT3DSU8 *)mvp.front(), 1));
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestConstantBuffer::structTest",
+ toRef(structVertShader(isGLESContext(context), vtxProg)),
+ toRef(structFragShader(isGLESContext(context), frgProg)));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestConstantBuffer::structTest: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestConstantBuffer::structTest: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderConstantBuffer *> cb("cbBuffer",
+ *compResult.mShader);
+ cb.Set();
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestConstantBuffer::rawTest(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ struct sampleStruct
+ {
+ float rg[2];
+ float padding[2];
+ QT3DSMat44 mat_mvp; // matrices start on 16 byte boundaries
+ float blue;
+ float alpha;
+ } s;
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderConstantBuffer> mConstantBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ NVDataRef<QT3DSU8> cBuffer((QT3DSU8 *)&s, sizeof(sampleStruct));
+ // create constant buffer referred in the program
+ mConstantBuffer = context->CreateConstantBuffer("cbBuffer", NVRenderBufferUsageType::Static,
+ sizeof(sampleStruct), cBuffer);
+ // set values
+ s.rg[0] = 0.0;
+ s.rg[1] = 1.0;
+ s.mat_mvp = mvp;
+ s.blue = 0.0;
+ s.alpha = 0.0;
+ mConstantBuffer->UpdateRaw(0, cBuffer);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestConstantBuffer::rawTest",
+ toRef(structVertShader(isGLESContext(context), vtxProg)),
+ toRef(structFragShader(isGLESContext(context), frgProg)));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestConstantBuffer::rawTest: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestConstantBuffer::rawTest: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderConstantBuffer *> cb("cbBuffer",
+ *compResult.mShader);
+ cb.Set();
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+///< test of multiple constant buffers
+bool NVRenderTestConstantBuffer::multiCBTest(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderConstantBuffer> mConstantBufferTrans;
+ NVScopedRefCounted<NVRenderConstantBuffer> mConstantBufferCol;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create constant buffer referred in the program
+ mConstantBufferTrans = context->CreateConstantBuffer(
+ "cbBufferTrans", NVRenderBufferUsageType::Static, 0, NVDataRef<QT3DSU8>());
+ // buffer parameter. They must be in the order of appearance
+ CRegisteredString theMatName(context->GetStringTable().RegisterStr("mat_mvp"));
+ mConstantBufferTrans->AddParam(theMatName, NVRenderShaderDataTypes::QT3DSMat44, 1);
+
+ // create constant buffer referred in the program
+ mConstantBufferCol = context->CreateConstantBuffer(
+ "cbBufferCol", NVRenderBufferUsageType::Static, 0, NVDataRef<QT3DSU8>());
+ CRegisteredString theRedName(context->GetStringTable().RegisterStr("red"));
+ mConstantBufferCol->AddParam(theRedName, NVRenderShaderDataTypes::QT3DSF32, 1);
+ CRegisteredString theGreenName(context->GetStringTable().RegisterStr("green"));
+ mConstantBufferCol->AddParam(theGreenName, NVRenderShaderDataTypes::QT3DSF32, 1);
+ CRegisteredString theBlueName(context->GetStringTable().RegisterStr("blue"));
+ mConstantBufferCol->AddParam(theBlueName, NVRenderShaderDataTypes::QT3DSF32, 1);
+
+ // set values
+ mConstantBufferTrans->UpdateParam("mat_mvp", NVDataRef<QT3DSU8>((QT3DSU8 *)mvp.front(), 1));
+
+ QT3DSF32 red = 0.0;
+ mConstantBufferCol->UpdateParam("red", NVDataRef<QT3DSU8>((QT3DSU8 *)&red, 1));
+ QT3DSF32 green = 1.0;
+ mConstantBufferCol->UpdateParam("green", NVDataRef<QT3DSU8>((QT3DSU8 *)&green, 1));
+ QT3DSF32 blue = 0.0;
+ mConstantBufferCol->UpdateParam("blue", NVDataRef<QT3DSU8>((QT3DSU8 *)&blue, 1));
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestConstantBuffer::multiCBTest",
+ toRef(multiCBVertShader(isGLESContext(context), vtxProg)),
+ toRef(multiCBFragShader(isGLESContext(context), frgProg)));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestConstantBuffer::scalarTest: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestConstantBuffer::scalarTest: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderConstantBuffer *> cbTrans(
+ "cbBufferTrans", *compResult.mShader);
+ mConstantBufferTrans->Update();
+ cbTrans.Set();
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderConstantBuffer *> cbCol(
+ "cbBufferCol", *compResult.mShader);
+ mConstantBufferCol->Update();
+ cbCol.Set();
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestConstantBuffer::runPerformance(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestConstantBuffer::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.h b/tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.h
new file mode 100644
index 0000000..417e4bb
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestConstantBuffer.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_CONSTANT_BUFFER_H
+#define QT3DS_RENDER_TEST_CONSTANT_BUFFER_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestConstantBuffer : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestConstantBuffer();
+ ~NVRenderTestConstantBuffer();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool scalarTest(NVRenderContext *context, userContextData *pUserData);
+ bool vectorTest(NVRenderContext *context, userContextData *pUserData);
+ bool structTest(NVRenderContext *context, userContextData *pUserData);
+ bool rawTest(NVRenderContext *context, userContextData *pUserData);
+ bool multiCBTest(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_CONSTANT_BUFFER_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.cpp b/tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.cpp
new file mode 100644
index 0000000..4b8044d
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.cpp
@@ -0,0 +1,358 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestDrawIndirectBuffer.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderDrawIndirectBuffer.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ prog += "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+NVRenderTestDrawIndirectBuffer::NVRenderTestDrawIndirectBuffer()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestDrawIndirectBuffer::~NVRenderTestDrawIndirectBuffer()
+{
+}
+
+bool NVRenderTestDrawIndirectBuffer::isSupported(NVRenderContext *context)
+{
+ // This is currently only supported on GL 4 and GLES 3.1
+ // we have no direct check for this but this is the same version
+ if (!context->IsAtomicCounterBufferSupported())
+ return false;
+
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestDrawIndirectBuffer::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= drawArrayIndirect(context, pUserData);
+ _curTest++;
+ success &= drawElementsIndirect(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestDrawIndirectBuffer::drawArrayIndirect(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) },
+ { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderDrawIndirectBuffer> mDrawIndirectBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestDrawIndirectBuffer shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), NULL, toConstDataRef(&strides, 1),
+ toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create input assembler";
+ return false;
+ }
+
+ // create draw indirect buffer
+ DrawArraysIndirectCommand command;
+ command.baseInstance = 0;
+ command.count = 6;
+ command.first = 0;
+ command.primCount = 1;
+ QT3DSU32 commandBufSize = sizeof(DrawArraysIndirectCommand);
+ NVDataRef<QT3DSU8> commandData((QT3DSU8 *)&command, commandBufSize);
+ mDrawIndirectBuffer = context->CreateDrawIndirectBuffer(NVRenderBufferUsageType::Dynamic,
+ commandBufSize, commandData);
+
+ if (!mDrawIndirectBuffer) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create vertex buffer";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ mDrawIndirectBuffer->Bind();
+ context->DrawIndirect(mInputAssembler->GetPrimitiveType(), 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestDrawIndirectBuffer::drawElementsIndirect(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) },
+ { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ const unsigned short indices[] = { 0, 1, 2, 3, 4, 5 };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderDrawIndirectBuffer> mDrawIndirectBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestDrawIndirectBuffer shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create vertex buffer";
+ return false;
+ }
+
+ // index buffer
+ bufSize = 6 * sizeof(unsigned short);
+ NVDataRef<QT3DSU8> idxData((QT3DSU8 *)indices, bufSize);
+ mIndexBuffer = context->CreateIndexBuffer(
+ NVRenderBufferUsageType::Static, NVRenderComponentTypes::QT3DSU16, bufSize,
+ NVConstDataRef<QT3DSU8>(reinterpret_cast<const QT3DSU8 *>(indices), bufSize));
+ if (!mIndexBuffer) {
+ qWarning() << "NVRenderTestPrimitives::Triangles: Failed to create index buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create input assembler";
+ return false;
+ }
+
+ // create draw indirect buffer
+ DrawElementsIndirectCommand command;
+ command.baseInstance = 0;
+ command.count = 6;
+ command.firstIndex = 0;
+ command.baseVertex = 0;
+ command.primCount = 1;
+ QT3DSU32 commandBufSize = sizeof(DrawElementsIndirectCommand);
+ NVDataRef<QT3DSU8> commandData((QT3DSU8 *)&command, commandBufSize);
+ mDrawIndirectBuffer = context->CreateDrawIndirectBuffer(NVRenderBufferUsageType::Dynamic,
+ commandBufSize, commandData);
+
+ if (!mDrawIndirectBuffer) {
+ qWarning() << "NVRenderTestAtomicCounterBuffer: Failed to create vertex buffer";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ mDrawIndirectBuffer->Bind();
+ context->DrawIndirect(mInputAssembler->GetPrimitiveType(), 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestDrawIndirectBuffer::runPerformance(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestDrawIndirectBuffer::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.h b/tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.h
new file mode 100644
index 0000000..ee37a13
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestDrawIndirectBuffer.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_DRAW_INDIRECT_BUFFER_H
+#define QT3DS_RENDER_TEST_DRAW_INDIRECT_BUFFER_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestDrawIndirectBuffer : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestDrawIndirectBuffer();
+ ~NVRenderTestDrawIndirectBuffer();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool drawArrayIndirect(NVRenderContext *context, userContextData *pUserData);
+ bool drawElementsIndirect(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_ATOMIC_COUNTER_BUFFER_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestPrimitives.cpp b/tests/auto/runtime/base/Qt3DSRenderTestPrimitives.cpp
new file mode 100644
index 0000000..d3c2423
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestPrimitives.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestPrimitives.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *PassthroughVertShader()
+{
+ return "uniform mat4 mat_mvp;\n"
+ "attribute vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+}
+
+static const char *SimpleFragShader()
+{
+ return "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "void main()\n"
+ "{\n"
+ "gl_FragColor = vec4(0, 1, 0, 1);\n"
+ "}\n";
+}
+
+NVRenderTestPrimitives::NVRenderTestPrimitives()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestPrimitives::~NVRenderTestPrimitives()
+{
+}
+
+bool NVRenderTestPrimitives::isSupported(NVRenderContext *context)
+{
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestPrimitives::renderPrimitive(NVRenderContext *context,
+ userContextData *pContextData,
+ const Vertex *pVertexData, unsigned int vertexCount,
+ const unsigned short *pIndexData,
+ unsigned int indexCount,
+ NVRenderDrawMode::Enum primType)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestPrimitives shader", toRef(PassthroughVertShader()), toRef(SimpleFragShader()));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = vertexCount * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)pVertexData, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestPrimitives::Triangles: Failed to create vertex buffer";
+ return false;
+ }
+
+ // index buffer
+ if (pIndexData && indexCount) {
+ bufSize = indexCount * sizeof(unsigned short);
+ NVDataRef<QT3DSU8> idxData((QT3DSU8 *)pIndexData, bufSize);
+ mIndexBuffer = context->CreateIndexBuffer(
+ NVRenderBufferUsageType::Static, NVRenderComponentTypes::QT3DSU16, bufSize,
+ NVConstDataRef<QT3DSU8>(reinterpret_cast<const QT3DSU8 *>(pIndexData), bufSize));
+ if (!mIndexBuffer) {
+ qWarning() << "NVRenderTestPrimitives::Triangles: Failed to create index buffer";
+ return false;
+ }
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestPrimitives::Triangles: Failed to create inout assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ QT3DSU32 count = (mIndexBuffer.mPtr) ? indexCount : vertexCount;
+ context->Draw(primType, count, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestPrimitives::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= triangles(context, pUserData);
+ _curTest++;
+ success &= triangleStrip(context, pUserData);
+ _curTest++;
+ success &= lines(context, pUserData);
+ _curTest++;
+ success &= lineStrip(context, pUserData);
+ _curTest++;
+ success &= trianglesIndexed(context, pUserData);
+ _curTest++;
+ success &= triangleStripIndexed(context, pUserData);
+ _curTest++;
+ success &= linesIndexed(context, pUserData);
+ _curTest++;
+ success &= lineStripIndexed(context, pUserData);
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestPrimitives::triangles(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.85, -0.9, 0) }, { QT3DSVec3(-0.85, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 6, NULL, 0,
+ NVRenderDrawMode::Triangles);
+}
+
+bool NVRenderTestPrimitives::triangleStrip(NVRenderContext *context, userContextData *pUserData)
+{
+ const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0.0) },
+ { QT3DSVec3(-0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, 0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, -0.9f, 0.0f) } };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 4, NULL, 0,
+ NVRenderDrawMode::TriangleStrip);
+}
+
+bool NVRenderTestPrimitives::lines(NVRenderContext *context, userContextData *pUserData)
+{
+ const Vertex vertexPositions[] = {
+ { QT3DSVec3(0.9f, 0.9f, 0.0f) }, { QT3DSVec3(0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, -0.9f, 0.0f) }, { QT3DSVec3(-0.85f, -0.9f, 0.0f) },
+ { QT3DSVec3(-0.85f, -0.9f, 0.0f) }, { QT3DSVec3(0.9f, 0.9f, 0.0f) },
+ { QT3DSVec3(-0.9f, -0.9f, 0.0f) }, { QT3DSVec3(0.85f, 0.9f, 0.0f) },
+ { QT3DSVec3(0.85f, 0.9f, 0.0f) }, { QT3DSVec3(-0.9f, 0.9f, 0.0f) },
+ { QT3DSVec3(-0.9f, 0.9f, 0.0f) }, { QT3DSVec3(-0.9f, -0.9f, 0.0f) }
+ };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 12, NULL, 0,
+ NVRenderDrawMode::Lines);
+}
+
+bool NVRenderTestPrimitives::lineStrip(NVRenderContext *context, userContextData *pUserData)
+{
+ const Vertex vertexPositions[] = {
+ { QT3DSVec3(-0.9f, 0.9f, 0.0f) }, { QT3DSVec3(-0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, -0.9f, 0.0f) }, { QT3DSVec3(0.9f, 0.9f, 0.0f) },
+ { QT3DSVec3(-0.9f, 0.9f, 0.0f) },
+ };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 5, NULL, 0,
+ NVRenderDrawMode::LineStrip);
+}
+
+bool NVRenderTestPrimitives::trianglesIndexed(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.85, -0.9, 0) }, { QT3DSVec3(-0.85, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+ const unsigned short indices[] = { 0, 1, 2, 3, 4, 5 };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 6, indices, 6,
+ NVRenderDrawMode::Triangles);
+}
+
+bool NVRenderTestPrimitives::triangleStripIndexed(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0.0) },
+ { QT3DSVec3(-0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, 0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, -0.9f, 0.0f) } };
+
+ const unsigned short indices[] = { 0, 1, 2, 3 };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 4, indices, 4,
+ NVRenderDrawMode::TriangleStrip);
+}
+
+bool NVRenderTestPrimitives::linesIndexed(NVRenderContext *context, userContextData *pUserData)
+{
+ const Vertex vertexPositions[] = {
+ { QT3DSVec3(0.9f, 0.9f, 0.0f) }, { QT3DSVec3(0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(-0.85f, -0.9f, 0.0f) }, { QT3DSVec3(-0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(0.85f, 0.9f, 0.0f) }, { QT3DSVec3(-0.9f, 0.9f, 0.0f) },
+ };
+
+ const unsigned short indices[] = { 0, 1, 1, 2, 2, 0, 3, 4, 4, 5, 5, 3 };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 6, indices, 12,
+ NVRenderDrawMode::Lines);
+}
+
+bool NVRenderTestPrimitives::lineStripIndexed(NVRenderContext *context, userContextData *pUserData)
+{
+ const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0.0) },
+ { QT3DSVec3(-0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, -0.9f, 0.0f) },
+ { QT3DSVec3(0.9f, 0.9f, 0.0f) } };
+
+ const unsigned short indices[] = { 0, 1, 2, 3, 0 };
+
+ return renderPrimitive(context, pUserData, vertexPositions, 4, indices, 5,
+ NVRenderDrawMode::LineStrip);
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestPrimitives::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestPrimitives::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestPrimitives.h b/tests/auto/runtime/base/Qt3DSRenderTestPrimitives.h
new file mode 100644
index 0000000..4b6128e
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestPrimitives.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_PRIMITIVES_H
+#define QT3DS_RENDER_TEST_PRIMITIVES_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ struct Vertex
+ {
+ QT3DSVec3 positions;
+ };
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestPrimitives : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestPrimitives();
+ ~NVRenderTestPrimitives();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool triangles(NVRenderContext *context, userContextData *pUserData);
+ bool triangleStrip(NVRenderContext *context, userContextData *pUserData);
+ bool lines(NVRenderContext *context, userContextData *pUserData);
+ bool lineStrip(NVRenderContext *context, userContextData *pContextData);
+
+ bool trianglesIndexed(NVRenderContext *context, userContextData *pUserData);
+ bool triangleStripIndexed(NVRenderContext *context, userContextData *pUserData);
+ bool linesIndexed(NVRenderContext *context, userContextData *pUserData);
+ bool lineStripIndexed(NVRenderContext *context, userContextData *pContextData);
+
+ bool renderPrimitive(NVRenderContext *context, userContextData *pContextData,
+ const Vertex *pVertexData, unsigned int vertexCount,
+ const unsigned short *pIndexData, unsigned int indexCount,
+ NVRenderDrawMode::Enum primType);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_PRIMITIVES_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.cpp b/tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.cpp
new file mode 100644
index 0000000..a76bfa0
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.cpp
@@ -0,0 +1,401 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestProgramPipeline.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderProgramPipeline.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+
+ prog += "out gl_PerVertex\n"
+ "{\n"
+ "\tvec4 gl_Position;\n"
+ "\tfloat gl_PointSize;\n"
+ "\tfloat gl_ClipDistance[];\n"
+ "};\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "in vec3 attr_col; // Vertex col\n"
+ "out vec3 color; // output color\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ " color = attr_col;\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ prog += "in vec3 color; // input color\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4( color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+NVRenderTestProgramPipeline::NVRenderTestProgramPipeline()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestProgramPipeline::~NVRenderTestProgramPipeline()
+{
+}
+
+bool NVRenderTestProgramPipeline::isSupported(NVRenderContext *context)
+{
+ return context->IsProgramPipelineSupported();
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestProgramPipeline::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= vertFragSeparateTest(context, pUserData);
+ _curTest++;
+ success &= vertFragCombinedTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestProgramPipeline::vertFragSeparateTest(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) },
+ { QT3DSVec3(0.0, 0.9, 0) } };
+
+ static const Vertex vertexColors[] = { { QT3DSVec3(0.0, 1.0, 0.0) },
+ { QT3DSVec3(0.0, 1.0, 0.0) },
+ { QT3DSVec3(0.0, 1.0, 0.0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderVertexBuffer> mColorBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderProgramPipeline> mProgramPipeline;
+ NVRenderVertexBuffer *attribBuffers[2];
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult vtxResult = context->CompileSource(
+ "NVRenderTestProgramPipeline vertex shader",
+ toRef(vertShader(vtxProg, isGLESContext(context))), NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8>(), NVConstDataRef<QT3DSI8>(), NVConstDataRef<QT3DSI8>(), true);
+ if (!vtxResult.mShader) {
+ return false;
+ }
+
+ NVRenderVertFragCompilationResult fragResult = context->CompileSource(
+ "NVRenderTestProgramPipeline fragment shader", NVConstDataRef<QT3DSI8>(),
+ toRef(fragShader(frgProg, isGLESContext(context))), NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8>(), NVConstDataRef<QT3DSI8>(), true);
+
+ if (!fragResult.mShader) {
+ return false;
+ }
+
+ // setup program pipeline
+ mProgramPipeline = context->CreateProgramPipeline();
+ if (!mProgramPipeline) {
+ qWarning() << "NVRenderTestProgramPipeline: Failed to create program pipeline";
+ return false;
+ }
+
+ mProgramPipeline->SetProgramStages(vtxResult.mShader,
+ NVRenderShaderTypeFlags(NVRenderShaderTypeValue::Vertex));
+ mProgramPipeline->SetProgramStages(fragResult.mShader,
+ NVRenderShaderTypeFlags(NVRenderShaderTypeValue::Fragment));
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0, 0),
+ NVRenderVertexBufferEntry("attr_col", NVRenderComponentTypes::QT3DSF32, 3, 0, 1),
+ };
+
+ // position buffer
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create vertex buffer";
+ return false;
+ }
+ // color buffer
+ NVDataRef<QT3DSU8> colorData((QT3DSU8 *)vertexColors, bufSize);
+ mColorBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), colorData);
+ if (!mColorBuffer) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create color buffer";
+ return false;
+ }
+
+ attribBuffers[0] = mVertexBuffer;
+ attribBuffers[1] = mColorBuffer;
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 2));
+ // create input Assembler
+ QT3DSU32 strides[2];
+ QT3DSU32 offsets[2];
+ strides[0] = mVertexBuffer->GetStride();
+ offsets[0] = 0;
+ strides[1] = mColorBuffer->GetStride();
+ offsets[1] = 0;
+
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, NVConstDataRef<NVRenderVertexBuffer *>(attribBuffers, 2), NULL,
+ toConstDataRef(strides, 2), toConstDataRef(offsets, 2), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveProgramPipeline(mProgramPipeline);
+ vtxResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ vtxResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveProgramPipeline(0);
+ return true;
+}
+
+bool NVRenderTestProgramPipeline::vertFragCombinedTest(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) },
+ { QT3DSVec3(0.0, 0.9, 0) } };
+
+ static const Vertex vertexColors[] = { { QT3DSVec3(0.0, 1.0, 0.0) },
+ { QT3DSVec3(0.0, 1.0, 0.0) },
+ { QT3DSVec3(0.0, 1.0, 0.0) } };
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderVertexBuffer> mColorBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderProgramPipeline> mProgramPipeline;
+ NVRenderVertexBuffer *attribBuffers[2];
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestProgramPipeline vertex shader",
+ toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))), NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8>(), NVConstDataRef<QT3DSI8>(), true);
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ // setup program pipeline
+ mProgramPipeline = context->CreateProgramPipeline();
+ if (!mProgramPipeline) {
+ qWarning() << "NVRenderTestProgramPipeline: Failed to create program pipeline";
+ return false;
+ }
+
+ mProgramPipeline->SetProgramStages(
+ compResult.mShader, NVRenderShaderTypeFlags(NVRenderShaderTypeValue::Vertex
+ | NVRenderShaderTypeValue::Fragment));
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0, 0),
+ NVRenderVertexBufferEntry("attr_col", NVRenderComponentTypes::QT3DSF32, 3, 0, 1),
+ };
+
+ // position buffer
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create vertex buffer";
+ return false;
+ }
+ // color buffer
+ NVDataRef<QT3DSU8> colorData((QT3DSU8 *)vertexColors, bufSize);
+ mColorBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), colorData);
+ if (!mColorBuffer) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create color buffer";
+ return false;
+ }
+
+ attribBuffers[0] = mVertexBuffer;
+ attribBuffers[1] = mColorBuffer;
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 2));
+ // create input Assembler
+ QT3DSU32 strides[2];
+ QT3DSU32 offsets[2];
+ strides[0] = mVertexBuffer->GetStride();
+ offsets[0] = 0;
+ strides[1] = mColorBuffer->GetStride();
+ offsets[1] = 0;
+
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, NVConstDataRef<NVRenderVertexBuffer *>(attribBuffers, 2), NULL,
+ toConstDataRef(strides, 2), toConstDataRef(offsets, 2), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestAttribBuffers: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveProgramPipeline(mProgramPipeline);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveProgramPipeline(0);
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestProgramPipeline::runPerformance(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestProgramPipeline::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.h b/tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.h
new file mode 100644
index 0000000..eeec086
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestProgramPipeline.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_PROGRAM_PIPELINE_H
+#define QT3DS_RENDER_TEST_PROGRAM_PIPELINE_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestProgramPipeline : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestProgramPipeline();
+ ~NVRenderTestProgramPipeline();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool vertFragSeparateTest(NVRenderContext *context, userContextData *pUserData);
+ bool vertFragCombinedTest(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_PROGRAM_PIPELINE_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestTexture2D.cpp b/tests/auto/runtime/base/Qt3DSRenderTestTexture2D.cpp
new file mode 100644
index 0000000..6904955
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestTexture2D.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestTexture2D.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderTexture2D.h"
+#include "render/Qt3DSRenderTexture2DArray.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "in vec3 attr_uv; // texture coord\n"
+ "out vec3 varTexCoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ " varTexCoord = attr_uv;\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330\n";
+ }
+
+ prog += "uniform sampler2DArray inTex;\n"
+ "in vec3 varTexCoord;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = texture(inTex, varTexCoord);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+ QT3DSVec3 texCoord;
+};
+
+static const Vertex vertexPositionsL0[] = {
+ { QT3DSVec3(-0.9, 0.0, 0), QT3DSVec3(0, 0, 0) }, { QT3DSVec3(0.0, 0.9, 0), QT3DSVec3(1, 1, 0) },
+ { QT3DSVec3(-0.9, 0.9, 0), QT3DSVec3(0, 1, 0) }, { QT3DSVec3(-0.9, 0.0, 0), QT3DSVec3(0, 0, 0) },
+ { QT3DSVec3(0.0, 0.0, 0), QT3DSVec3(1, 0, 0) }, { QT3DSVec3(0.0, 0.9, 0), QT3DSVec3(1, 1, 0) }
+};
+
+static const Vertex vertexPositionsL1[] = {
+ { QT3DSVec3(0.0, -0.9, 0), QT3DSVec3(0, 0, 1) }, { QT3DSVec3(0.9, 0.0, 0), QT3DSVec3(1, 1, 1) },
+ { QT3DSVec3(0.0, 0.0, 0), QT3DSVec3(0, 1, 1) }, { QT3DSVec3(0.0, -0.9, 0), QT3DSVec3(0, 0, 1) },
+ { QT3DSVec3(0.9, -0.9, 0), QT3DSVec3(1, 0, 1) }, { QT3DSVec3(0.9, 0.0, 0), QT3DSVec3(1, 1, 1) }
+};
+
+#define TEXTURE_LAYER_SIZE 2
+#define TEXTURE_SIZE 64
+#define PATTERN_SIZE 0x8
+
+NVRenderTestTexture2D::NVRenderTestTexture2D()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+ _pTextureData = NULL;
+}
+
+NVRenderTestTexture2D::~NVRenderTestTexture2D()
+{
+}
+
+bool NVRenderTestTexture2D::isSupported(NVRenderContext *context)
+{
+ return context->IsTextureArraySupported();
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestTexture2D::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ // alloc data
+ _pTextureData = new unsigned char[TEXTURE_SIZE * TEXTURE_SIZE * 4 * TEXTURE_LAYER_SIZE];
+ CreateTexData(_pTextureData);
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= texArray2DTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ if (_pTextureData)
+ delete _pTextureData;
+
+ return success;
+}
+
+void NVRenderTestTexture2D::CreateTexData(unsigned char *_pOutData)
+{
+ if (!_pOutData)
+ return;
+
+ unsigned char *_pData = _pOutData;
+
+ // Create a checkerboard pattern
+ for (int i = 0; i < TEXTURE_LAYER_SIZE; i++) {
+ for (int j = 0; j < TEXTURE_SIZE; j++) {
+ for (int k = 0; k < TEXTURE_SIZE; k++) {
+ unsigned char c = (((j & PATTERN_SIZE) == 0) ^ ((k & PATTERN_SIZE) == 0)) * 255;
+ *_pData++ = 0x0;
+ *_pData++ = c >> i;
+ *_pData++ = 0x0;
+ *_pData++ = 0xFF;
+ }
+ }
+ }
+}
+
+bool NVRenderTestTexture2D::renderTexArrayQuad(NVRenderContext *context, userContextData *pUserData,
+ NVRenderTexture2DArray *pTex, QT3DSU8 *vertexPositions)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestTexture2D shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ NVRenderVertexBufferEntry("attr_uv", NVRenderComponentTypes::QT3DSF32, 3, 12),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData(vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 6 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestTexture2D: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 2));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler =
+ context->CreateInputAssembler(mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), NULL,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestTexture2D: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ NVRenderCachedShaderProperty<NVRenderTexture2DArray *> mArrayTexture("inTex",
+ *compResult.mShader);
+ mArrayTexture.Set(pTex);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestTexture2D::texArray2DTest(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // create texture
+ NVScopedRefCounted<NVRenderTexture2DArray> mArrayTexture;
+ mArrayTexture = context->CreateTexture2DArray();
+ mArrayTexture->SetTextureData(
+ NVDataRef<QT3DSU8>(_pTextureData, TEXTURE_SIZE * TEXTURE_SIZE * 4 * TEXTURE_LAYER_SIZE), 0,
+ TEXTURE_SIZE, TEXTURE_SIZE, TEXTURE_LAYER_SIZE, NVRenderTextureFormats::RGBA8);
+
+ success &= renderTexArrayQuad(context, pUserData, mArrayTexture, (QT3DSU8 *)vertexPositionsL0);
+ success &= renderTexArrayQuad(context, pUserData, mArrayTexture, (QT3DSU8 *)vertexPositionsL1);
+
+ return success;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestTexture2D::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestTexture2D::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestTexture2D.h b/tests/auto/runtime/base/Qt3DSRenderTestTexture2D.h
new file mode 100644
index 0000000..5c5de11
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestTexture2D.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_TEXTURE_2D_H
+#define QT3DS_RENDER_TEST_TEXTURE_2D_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderTexture2D;
+ class NVRenderTexture2DArray;
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestTexture2D : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestTexture2D();
+ ~NVRenderTestTexture2D();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool texArray2DTest(NVRenderContext *context, userContextData *pUserData);
+
+ bool renderTexArrayQuad(NVRenderContext *context, userContextData *pUserData,
+ NVRenderTexture2DArray *pTex, QT3DSU8 *vertexPositions);
+ void CreateTexData(unsigned char *_pOutData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ unsigned char *_pTextureData;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_TEXTURE_2D_H
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.cpp b/tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.cpp
new file mode 100644
index 0000000..bf8ff0e
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.cpp
@@ -0,0 +1,436 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestTimerQuery.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderTimerQuery.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330\n";
+ }
+
+ prog += "uniform vec3 color;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+NVRenderTestTimerQuery::NVRenderTestTimerQuery()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestTimerQuery::~NVRenderTestTimerQuery()
+{
+}
+
+bool NVRenderTestTimerQuery::isSupported(NVRenderContext *context)
+{
+ return context->IsTimerQuerySupported();
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestTimerQuery::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= timerTest(context, pUserData);
+ _curTest++;
+ success &= absoluteTimerTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestTimerQuery::renderQuad(NVRenderContext *context, userContextData *pUserData,
+ QT3DSVec3 color)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestTimerQuery shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestTimerQuery: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler =
+ context->CreateInputAssembler(mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), NULL,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestTimerQuery: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestTimerQuery::timerTest(NVRenderContext *context, userContextData *pUserData)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ QT3DSMat44 proj = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&proj, -1, 1, -1, 1, -10, 10);
+ QT3DSVec3 color(1.0, 1.0, 0.0);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestTimerQuery shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestTimerQuery: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler =
+ context->CreateInputAssembler(mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), NULL,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestTimerQuery: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+
+ // setup translation
+ QT3DSMat44 transZ;
+ NvRenderTestMatrixTranslation(&transZ, 0.0, 0.0, 0.2);
+ mvp = transZ * proj;
+
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ NVScopedRefCounted<NVRenderTimerQuery> pQuery = context->CreateTimerQuery();
+
+ // render 1000 quads this should take at least some amount of time
+ pQuery->Begin();
+ for (QT3DSI32 i = 0; i < 1000; i++) {
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+ }
+ pQuery->End();
+
+ // get elapsed time in nano seconds
+ QT3DSU64 result = 0;
+ pQuery->GetResult(&result);
+ // convert to milli second
+ QT3DSF64 elapsed = double(result) / 1e06;
+
+ /// it should take at least a fraction of a milli second
+ if (elapsed > 0.0)
+ color.x = 0.0; // right
+ else
+ color.y = 0.0; // wrong
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ renderQuad(context, pUserData, color);
+
+ return (elapsed > 0.0);
+}
+
+bool NVRenderTestTimerQuery::absoluteTimerTest(NVRenderContext *context, userContextData *pUserData)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ QT3DSMat44 proj = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&proj, -1, 1, -1, 1, -10, 10);
+ QT3DSVec3 color(1.0, 1.0, 0.0);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestTimerQuery shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestTimerQuery: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler =
+ context->CreateInputAssembler(mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), NULL,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestTimerQuery: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+
+ // setup translation
+ QT3DSMat44 transZ;
+ NvRenderTestMatrixTranslation(&transZ, 0.0, 0.0, 0.2);
+ mvp = transZ * proj;
+
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ NVScopedRefCounted<NVRenderTimerQuery> pQueryStart = context->CreateTimerQuery();
+ NVScopedRefCounted<NVRenderTimerQuery> pQueryEnd = context->CreateTimerQuery();
+
+ // render 1000 quads this should take at least some amount of time
+ pQueryStart->SetTimerQuery();
+ for (QT3DSI32 i = 0; i < 1000; i++) {
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+ }
+ pQueryEnd->SetTimerQuery();
+
+ // get absolute time in nano seconds
+ QT3DSU64 start = 0;
+ pQueryStart->GetResult(&start);
+ QT3DSU64 end = 0;
+ pQueryEnd->GetResult(&end);
+
+ // convert to milli second
+ QT3DSF64 elapsed = double(end - start) / 1e06;
+
+ // it should take at least a fraction of a milli second
+ if (elapsed > 0.0)
+ color.x = 0.0; // right
+ else
+ color.y = 0.0; // wrong
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ renderQuad(context, pUserData, color);
+
+ return (elapsed > 0.0);
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestTimerQuery::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestTimerQuery::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.h b/tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.h
new file mode 100644
index 0000000..127c25f
--- /dev/null
+++ b/tests/auto/runtime/base/Qt3DSRenderTestTimerQuery.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_TIMER_QUERY_H
+#define QT3DS_RENDER_TEST_TIMER_QUERY_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderTimerQuery;
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestTimerQuery : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestTimerQuery();
+ ~NVRenderTestTimerQuery();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool timerTest(NVRenderContext *context, userContextData *pUserData);
+ bool absoluteTimerTest(NVRenderContext *context, userContextData *pUserData);
+
+ bool renderQuad(NVRenderContext *context, userContextData *pUserData, QT3DSVec3 color);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_TIMER_QUERY_H
diff --git a/tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.cpp b/tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.cpp
new file mode 100644
index 0000000..15035b4
--- /dev/null
+++ b/tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.cpp
@@ -0,0 +1,636 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestComputeShader.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderImageTexture.h"
+#include "render/Qt3DSRenderStorageBuffer.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *vertTexShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "in vec2 attr_uv; // texture coord\n"
+ "out vec2 varTexCoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ " varTexCoord = attr_uv;\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform vec3 color;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragTexShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform sampler2D inTex;\n"
+ "in vec2 varTexCoord;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = texture(inTex, varTexCoord);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *computeShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_ARB_compute_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n"
+ "#extension GL_ARB_compute_shader : enable\n";
+ }
+
+ prog += "// Set workgroup layout;\n"
+ "layout (local_size_x =16, local_size_y = 16) in;\n\n"
+ "void main()\n"
+ "{\n"
+ " // do nothing\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *computeWorkShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_ARB_compute_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n"
+ "precision mediump image2D;\n";
+ } else {
+ prog += "#version 430\n"
+ "#extension GL_ARB_compute_shader : enable\n";
+ }
+
+ prog += "// Set workgroup layout;\n"
+ "layout (local_size_x = 32, local_size_y = 32) in;\n\n"
+ "layout (rgba8, binding = 2) uniform image2D outputImage;\n\n"
+ "void main()\n"
+ "{\n"
+ " imageStore( outputImage, ivec2(gl_GlobalInvocationID.xy), vec4( "
+ "vec2(gl_LocalInvocationID.xy) / vec2(gl_WorkGroupSize.xy), 0.0, 1.0 ) );\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *computeStorageShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_ARB_compute_shader : enable\n"
+ "#extension GL_ARB_shader_storage_buffer_object : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n"
+ "#extension GL_ARB_compute_shader : enable\n"
+ "#extension GL_ARB_shader_storage_buffer_object : enable\n";
+ }
+
+ prog += "layout( std140, binding=4 ) buffer Pos\n"
+ "{\n"
+ " vec4 Positions[ ]; // array of positions\n"
+ "};\n"
+ "// Set workgroup layout;\n"
+ "layout (local_size_x = 32, local_size_y = 1) in;\n\n"
+ "void main()\n"
+ "{\n"
+ " uint gid = gl_GlobalInvocationID.x;\n"
+ " if ( gid < uint(1000) ) {\n"
+ " Positions[gid].x = float(gl_GlobalInvocationID.x);\n"
+ " }\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+ QT3DSVec2 texCoord;
+};
+
+NVRenderTestComputeShader::NVRenderTestComputeShader()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestComputeShader::~NVRenderTestComputeShader()
+{
+}
+
+bool NVRenderTestComputeShader::isSupported(NVRenderContext *context)
+{
+ return context->IsComputeSupported();
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestComputeShader::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+
+ context->SetRenderTarget(NULL);
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= computeCompile(context, pUserData);
+ _curTest++;
+ success &= computeWorkgroup(context, pUserData);
+ _curTest++;
+ success &= computeStorage(context, pUserData);
+ _curTest++;
+
+ return success;
+}
+
+bool NVRenderTestComputeShader::computeCompile(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.0, 0.9, 0), QT3DSVec2(0, 0) } };
+
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestComputeShader shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 5 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create input assembler";
+ return false;
+ }
+
+ // create a compute shader which does nothing just as a compile check
+ std::string computeProg;
+ NVRenderVertFragCompilationResult computeResult = context->CompileComputeSource(
+ "Compute nothing shader", toRef(computeShader(computeProg, isGLESContext(context))));
+
+ if (!computeResult.mShader) {
+ color.x = 1.0;
+ color.y = 0.0;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+ if (computeResult.mShader)
+ computeResult.mShader->release();
+
+ return true;
+}
+
+#define WORKGROUP_SIZE 32
+
+bool NVRenderTestComputeShader::computeWorkgroup(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = {
+ { QT3DSVec3(-0.9, -0.9, 0), QT3DSVec2(0, 0) }, { QT3DSVec3(0.9, 0.9, 0), QT3DSVec2(1, 1) },
+ { QT3DSVec3(-0.9, 0.9, 0), QT3DSVec2(0, 1) }, { QT3DSVec3(-0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.9, -0.9, 0), QT3DSVec2(1, 0) }, { QT3DSVec3(0.9, 0.9, 0), QT3DSVec2(1, 1) }
+ };
+
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ // create texture
+ NVScopedRefCounted<NVRenderTexture2D> mColorTexture;
+ mColorTexture = context->CreateTexture2D();
+ mColorTexture->SetTextureStorage(1, pUserData->winWidth, pUserData->winHeight,
+ NVRenderTextureFormats::RGBA8);
+ // create a image buffer wrapper
+ NVScopedRefCounted<NVRenderImage2D> mColorImage;
+ mColorImage = context->CreateImage2D(mColorTexture, NVRenderImageAccessType::Write);
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestComputeShader shader", toRef(vertTexShader(vtxProg, isGLESContext(context))),
+ toRef(fragTexShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ NVRenderVertexBufferEntry("attr_uv", NVRenderComponentTypes::QT3DSF32, 2, 12),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 5 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 2));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create input assembler";
+ return false;
+ }
+
+ // create a compute shader which outputs the workgroups as color codes
+ std::string computeProg;
+ NVRenderVertFragCompilationResult computeResult = context->CompileComputeSource(
+ "Compute workgroup shader", toRef(computeWorkShader(computeProg, isGLESContext(context))));
+
+ if (!computeResult.mShader) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create compute shader";
+ return false;
+ }
+
+ // set program
+ context->SetActiveShader(computeResult.mShader);
+ NVRenderCachedShaderProperty<NVRenderImage2D *> mOutputImage("outputImage",
+ *computeResult.mShader);
+ mOutputImage.Set(mColorImage);
+ // run compute shader
+ context->DispatchCompute(computeResult.mShader, pUserData->winWidth / WORKGROUP_SIZE,
+ pUserData->winHeight / WORKGROUP_SIZE, 1);
+ NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderImageAccess);
+ // sync
+ context->SetMemoryBarrier(flags);
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+ // set texture
+ NVRenderCachedShaderProperty<NVRenderTexture2D *> mInputImage("inTex", *compResult.mShader);
+ mInputImage.Set(mColorTexture);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 6, 0);
+
+ context->SetActiveShader(0);
+
+ compResult.mShader->release();
+ if (computeResult.mShader)
+ computeResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestComputeShader::computeStorage(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.0, 0.9, 0), QT3DSVec2(0, 0) } };
+
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create vertex buffer for compute shader usage
+ NVScopedRefCounted<NVRenderVertexBuffer> mComputeVertexBuffer;
+ QT3DSF32 *storageData = new QT3DSF32[1000 * 4]; // vec 4 in shader program
+ NVDataRef<QT3DSU8> storData((QT3DSU8 *)storageData, 1000 * sizeof(QT3DSF32) * 4);
+ mComputeVertexBuffer = context->CreateVertexBuffer(
+ NVRenderBufferUsageType::Static, 1000 * sizeof(QT3DSF32) * 4, sizeof(QT3DSF32), storData);
+ if (!mComputeVertexBuffer) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create compute vertex buffer";
+ return false;
+ }
+ // create storage wrapper for vertex buffer
+ NVScopedRefCounted<NVRenderStorageBuffer> mComputeStorageBuffer;
+ mComputeStorageBuffer =
+ context->CreateStorageBuffer("Pos", NVRenderBufferUsageType::Static,
+ 1000 * sizeof(QT3DSF32) * 4, storData, mComputeVertexBuffer.mPtr);
+ if (!mComputeStorageBuffer) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create compute storage buffer";
+ return false;
+ }
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestComputeShader shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 5 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create input assembler";
+ return false;
+ }
+
+ // create a compute shader which places id's into the buffer
+ std::string computeProg;
+ NVRenderVertFragCompilationResult computeResult = context->CompileComputeSource(
+ "Compute storage shader", toRef(computeStorageShader(computeProg, isGLESContext(context))));
+
+ if (!computeResult.mShader) {
+ qWarning() << "NVRenderTestComputeShader: Failed to create compute shader";
+ return false;
+ }
+
+ // set and run compute program
+ context->SetActiveShader(computeResult.mShader);
+ qt3ds::render::NVRenderCachedShaderBuffer<NVRenderShaderStorageBuffer *> storageBuffer(
+ "Pos", *computeResult.mShader);
+ storageBuffer.Set();
+ // run compute shader
+ context->DispatchCompute(computeResult.mShader, 1024 / WORKGROUP_SIZE, 1, 1);
+ NVRenderBufferBarrierFlags flags(NVRenderBufferBarrierValues::ShaderStorage
+ | NVRenderBufferBarrierValues::VertexAttribArray);
+ // sync
+ context->SetMemoryBarrier(flags);
+
+ // check content
+ bool contentOK = true;
+ mComputeVertexBuffer->Bind();
+ NVDataRef<QT3DSU8> pData = mComputeVertexBuffer->MapBuffer();
+ QT3DSF32 *fData = (QT3DSF32 *)pData.begin();
+ QT3DSU32 size = pData.size() / 4;
+ for (QT3DSU32 i = 0, k = 0; i < size; i += 4, k++) {
+ if (fData[i] != (float)k)
+ contentOK = false;
+ }
+
+ mComputeVertexBuffer->UnmapBuffer();
+
+ if (!contentOK) {
+ color.x = 1.0;
+ color.y = 0.0;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+ if (computeResult.mShader)
+ computeResult.mShader->release();
+
+ delete storageData;
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestComputeShader::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestComputeShader::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.h b/tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.h
new file mode 100644
index 0000000..826fb9c
--- /dev/null
+++ b/tests/auto/runtime/compute/Qt3DSRenderTestComputeShader.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_COMPUTE_SHADER_H
+#define QT3DS_RENDER_TEST_COMPUTE_SHADER_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestComputeShader : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestComputeShader();
+ ~NVRenderTestComputeShader();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool computeCompile(NVRenderContext *context, userContextData *pUserData);
+ bool computeWorkgroup(NVRenderContext *context, userContextData *pUserData);
+ bool computeStorage(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif
diff --git a/tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.cpp b/tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.cpp
new file mode 100644
index 0000000..400cfc5
--- /dev/null
+++ b/tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.cpp
@@ -0,0 +1,299 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestFboMsaa.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *PassthroughVertShader()
+{
+ return "uniform mat4 mat_mvp;\n"
+ "attribute vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+}
+
+static const char *SimpleFragShader()
+{
+ return "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "uniform vec3 color;\n"
+ "void main()\n"
+ "{\n"
+ "gl_FragColor = vec4( color, 1.0);\n"
+ "}\n";
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) },
+ { QT3DSVec3(0.0, 0.9, 0) } };
+
+NVRenderTestFboMsaa::NVRenderTestFboMsaa()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestFboMsaa::~NVRenderTestFboMsaa()
+{
+}
+
+bool NVRenderTestFboMsaa::isSupported(NVRenderContext *context)
+{
+ NVRenderContextType ctxType = context->GetRenderContextType();
+ NVRenderContextType nonSupportedFlags(NVRenderContextValues::GL2 | NVRenderContextValues::GLES2
+ | NVRenderContextValues::GLES3);
+
+ // This is currently only supported on >= GL3 && >= GLES 3.1
+ if ((ctxType & nonSupportedFlags))
+ return false;
+
+ return true;
+}
+
+bool NVRenderTestFboMsaa::run(NVRenderContext *context, userContextData *pUserData)
+{
+ if (!setupResolveFbo(context, pUserData))
+ return false;
+
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetRenderTarget(NULL);
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= simpleMsaaTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestFboMsaa::renderTriangle(NVRenderContext *context, QT3DSVec3 color)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ NVRenderVertFragCompilationResult compResult =
+ context->CompileSource("NVRenderTestBackendQuery shader", toRef(PassthroughVertShader()),
+ toRef(SimpleFragShader()));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestFboMsaa: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestFboMsaa: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestFboMsaa::setupResolveFbo(NVRenderContext *context, userContextData *pUserData)
+{
+ // color texture
+ m_ResolveColorTexture = context->CreateTexture2D();
+ m_ResolveColorTexture->SetTextureData(NVDataRef<QT3DSU8>(), 0, pUserData->winWidth,
+ pUserData->winHeight, NVRenderTextureFormats::RGBA8);
+ // depth texture
+ m_ResolveDepthTexture = context->CreateTexture2D();
+ m_ResolveDepthTexture->SetTextureData(NVDataRef<QT3DSU8>(), 0, pUserData->winWidth,
+ pUserData->winHeight, NVRenderTextureFormats::Depth24);
+ // create resolve FBO
+ m_ResolveFbo = context->CreateFrameBuffer();
+ m_ResolveFbo->Attach(NVRenderFrameBufferAttachments::Color0,
+ NVRenderTextureOrRenderBuffer(*m_ResolveColorTexture));
+ m_ResolveFbo->Attach(NVRenderFrameBufferAttachments::Depth,
+ NVRenderTextureOrRenderBuffer(*m_ResolveDepthTexture));
+
+ return m_ResolveFbo->IsComplete();
+}
+
+bool NVRenderTestFboMsaa::simpleMsaaTest(NVRenderContext *context, userContextData *pUserData)
+{
+ // create a multisampled FBO
+ NVScopedRefCounted<NVRenderFrameBuffer> msFBO;
+ NVScopedRefCounted<NVRenderTexture2D> msColorTexture;
+ NVScopedRefCounted<NVRenderTexture2D> msDepth24Texture;
+
+ msColorTexture = context->CreateTexture2D();
+ msColorTexture->SetTextureDataMultisample(4, pUserData->winWidth, pUserData->winHeight,
+ NVRenderTextureFormats::RGBA8);
+ msDepth24Texture = context->CreateTexture2D();
+ msDepth24Texture->SetTextureDataMultisample(4, pUserData->winWidth, pUserData->winHeight,
+ NVRenderTextureFormats::Depth24);
+
+ msFBO = context->CreateFrameBuffer();
+ msFBO->Attach(NVRenderFrameBufferAttachments::Color0,
+ NVRenderTextureOrRenderBuffer(*msColorTexture),
+ NVRenderTextureTargetType::Texture2D_MS);
+ msFBO->Attach(NVRenderFrameBufferAttachments::Depth,
+ NVRenderTextureOrRenderBuffer(*msDepth24Texture),
+ NVRenderTextureTargetType::Texture2D_MS);
+
+ if (!msFBO->IsComplete())
+ return false;
+
+ // clear and draw to multisampled buffer
+ context->SetRenderTarget(msFBO);
+ context->SetMultisampleEnabled(true);
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+ renderTriangle(context, qt3ds::QT3DSVec3(0.0, 1.0, 0.0));
+ context->SetMultisampleEnabled(false);
+
+ // do resolve blit
+ // first we must setup the render target
+ context->SetRenderTarget(m_ResolveFbo);
+ // second setup read target
+ context->SetReadTarget(msFBO);
+ context->SetReadBuffer(NVReadFaces::Color0);
+
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ context->BlitFramebuffer(0, 0, pUserData->winWidth, pUserData->winHeight, 0, 0,
+ pUserData->winWidth, pUserData->winHeight, NVRenderClearValues::Color,
+ NVRenderTextureMagnifyingOp::Nearest);
+
+ // copy to default buffer
+ // first we must setup the render target
+ context->SetRenderTarget(NULL);
+ // second setup read target
+ context->SetReadTarget(m_ResolveFbo);
+ context->SetReadBuffer(NVReadFaces::Color0);
+
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ context->BlitFramebuffer(0, 0, pUserData->winWidth, pUserData->winHeight, 0, 0,
+ pUserData->winWidth, pUserData->winHeight, NVRenderClearValues::Color,
+ NVRenderTextureMagnifyingOp::Nearest);
+
+ context->SetReadTarget(NULL);
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestFboMsaa::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestFboMsaa::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ m_ResolveColorTexture->release();
+ m_ResolveDepthTexture->release();
+ m_ResolveFbo->release();
+
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ context->SetRenderTarget(NULL);
+}
diff --git a/tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.h b/tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.h
new file mode 100644
index 0000000..bf9ed84
--- /dev/null
+++ b/tests/auto/runtime/fbo/Qt3DSRenderTestFboMsaa.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_FBO_MSAA_H
+#define QT3DS_RENDER_TEST_FBO_MSAA_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestFboMsaa : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestFboMsaa();
+ ~NVRenderTestFboMsaa();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool setupResolveFbo(NVRenderContext *context, userContextData *pUserData);
+ bool renderTriangle(NVRenderContext *context, QT3DSVec3 color);
+
+ // tests
+ bool simpleMsaaTest(NVRenderContext *context, userContextData *pUserData);
+
+ NVScopedRefCounted<NVRenderFrameBuffer> m_ResolveFbo;
+ NVScopedRefCounted<NVRenderTexture2D> m_ResolveColorTexture;
+ NVScopedRefCounted<NVRenderTexture2D> m_ResolveDepthTexture;
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_FBO_MSAA_H
diff --git a/tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.cpp b/tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.cpp
new file mode 100644
index 0000000..1a1c34c
--- /dev/null
+++ b/tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.cpp
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestGeometryShader.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderImageTexture.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform vec3 color;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *geometryShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_EXT_geometry_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ // pass through shader
+ prog += "layout (triangles) in;\n"
+ "layout (triangle_strip, max_vertices = 3) out;\n"
+ "void main()\n"
+ "{\n"
+ " int i;\n"
+ " for(i=0; i<gl_in.length(); i++)\n"
+ " {\n"
+ " gl_Position = gl_in[i].gl_Position;\n"
+ " EmitVertex();\n"
+ " }\n"
+ " EndPrimitive();\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *wireframeShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_EXT_geometry_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 430\n";
+ }
+
+ // convert to wireframe
+ prog += "layout (triangles) in;\n"
+ "layout (line_strip, max_vertices = 4) out;\n"
+ "void main()\n"
+ "{\n"
+ " int i;\n"
+ " for(i=0; i<gl_in.length(); i++)\n"
+ " {\n"
+ " gl_Position = gl_in[i].gl_Position;\n"
+ " EmitVertex();\n"
+ " }\n"
+ " gl_Position = gl_in[0].gl_Position;\n"
+ " EmitVertex();\n"
+ " EndPrimitive();\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+ QT3DSVec2 texCoord;
+};
+
+NVRenderTestGeometryShader::NVRenderTestGeometryShader()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestGeometryShader::~NVRenderTestGeometryShader()
+{
+}
+
+bool NVRenderTestGeometryShader::isSupported(NVRenderContext *context)
+{
+ return context->IsGeometryStageSupported();
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestGeometryShader::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+
+ context->SetRenderTarget(NULL);
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= geometryCompile(context, pUserData);
+ _curTest++;
+ success &= wireframe(context, pUserData);
+ _curTest++;
+
+ return success;
+}
+
+bool NVRenderTestGeometryShader::geometryCompile(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.0, 0.9, 0), QT3DSVec2(0, 0) } };
+
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestGeometryShader shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 5 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestGeometryShader: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestGeometryShader: Failed to create input assembler";
+ return false;
+ }
+
+ // create a geometry shader which does nothing just as a compile check
+ std::string geomProg;
+ std::string vtxProgDummy;
+ std::string frgProgDummy;
+ NVRenderVertFragCompilationResult geomResult = context->CompileSource(
+ "NVRenderTestGeometryShader shader",
+ toRef(vertShader(vtxProgDummy, isGLESContext(context))),
+ toRef(fragShader(frgProgDummy, isGLESContext(context))), NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8>(), toRef(geometryShader(geomProg, isGLESContext(context))));
+
+ if (!geomResult.mShader) {
+ color.x = 1.0;
+ color.y = 0.0;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+ if (geomResult.mShader)
+ geomResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestGeometryShader::wireframe(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.9, -0.9, 0), QT3DSVec2(0, 0) },
+ { QT3DSVec3(0.0, 0.9, 0), QT3DSVec2(0, 0) } };
+
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ // geometry shader converts primitives from triangles to lines
+ std::string vtxProg;
+ std::string frgProg;
+ std::string geomProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestGeometryShader shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))), NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8>(), toRef(wireframeShader(geomProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 5 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestGeometryShader: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Triangles);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestGeometryShader: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestGeometryShader::runPerformance(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestGeometryShader::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.h b/tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.h
new file mode 100644
index 0000000..139a7e2
--- /dev/null
+++ b/tests/auto/runtime/geometry/Qt3DSRenderTestGeometryShader.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_GEOMETRY_SHADER_H
+#define QT3DS_RENDER_TEST_GEOMETRY_SHADER_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestGeometryShader : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestGeometryShader();
+ ~NVRenderTestGeometryShader();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool geometryCompile(NVRenderContext *context, userContextData *pUserData);
+ bool wireframe(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif
diff --git a/tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.cpp b/tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.cpp
new file mode 100644
index 0000000..1bb0b16
--- /dev/null
+++ b/tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.cpp
@@ -0,0 +1,367 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestOcclusionQuery.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderOcclusionQuery.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 330\n";
+ }
+
+ prog += "uniform vec3 color;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+};
+
+static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, 0.9, 0) }, { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(-0.9, 0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) }, { QT3DSVec3(0.9, 0.9, 0) } };
+
+static const Vertex largeQuadPositions[] = { { QT3DSVec3(-0.7, 0.7, 0) }, { QT3DSVec3(-0.7, -0.7, 0) },
+ { QT3DSVec3(0.7, -0.7, 0) }, { QT3DSVec3(-0.7, 0.7, 0) },
+ { QT3DSVec3(0.7, -0.7, 0) }, { QT3DSVec3(0.7, 0.7, 0) } };
+
+static const Vertex smallQuadPositions[] = { { QT3DSVec3(-0.5, 0.5, 0) }, { QT3DSVec3(-0.5, -0.5, 0) },
+ { QT3DSVec3(0.5, -0.5, 0) }, { QT3DSVec3(-0.5, 0.5, 0) },
+ { QT3DSVec3(0.5, -0.5, 0) }, { QT3DSVec3(0.5, 0.5, 0) } };
+
+NVRenderTestOcclusionQuery::NVRenderTestOcclusionQuery()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestOcclusionQuery::~NVRenderTestOcclusionQuery()
+{
+}
+
+bool NVRenderTestOcclusionQuery::isSupported(NVRenderContext *context)
+{
+ return context->IsSampleQuerySupported();
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestOcclusionQuery::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= occlusionPassTest(context, pUserData);
+ _curTest++;
+ success &= occlusionFailTest(context, pUserData);
+ _curTest++;
+
+ // cleanup
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+
+ return success;
+}
+
+bool NVRenderTestOcclusionQuery::renderQuad(NVRenderContext *context, userContextData *pUserData,
+ QT3DSVec3 color)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestOcclusionQuery shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 3 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestOcclusionQuery: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler =
+ context->CreateInputAssembler(mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), NULL,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestOcclusionQuery: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+void NVRenderTestOcclusionQuery::renderPrim(NVRenderContext *context, userContextData *pUserData,
+ void *pData, float zOffset, QT3DSVec3 color,
+ NVRenderOcclusionQuery *pQuery)
+{
+ NVScopedRefCounted<NVRenderVertexBuffer> mVB;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mIA;
+ Vertex *pVtxData = (Vertex *)pData;
+ QT3DSMat44 proj = QT3DSMat44::createIdentity();
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&proj, -1, 1, -1, 1, -10, 10);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestOcclusionQuery shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 6 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertDataSmall((QT3DSU8 *)pVtxData, bufSize);
+ mVB = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize, 3 * sizeof(QT3DSF32),
+ vertDataSmall);
+ if (!mVB)
+ qWarning() << "NVRenderTestOcclusionQuery: Failed to create vertex buffer";
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVB->GetStride();
+ QT3DSU32 offsets = 0;
+ mIA = context->CreateInputAssembler(mAttribLayout, toConstDataRef(&mVB.mPtr, 1), NULL,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1));
+ if (!mVB) {
+ qWarning() << "NVRenderTestOcclusionQuery: Failed to create input assembler";
+ return;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mIA);
+ // setup translation
+ QT3DSMat44 transZ;
+ NvRenderTestMatrixTranslation(&transZ, 0.0, 0.0, zOffset);
+ mvp = transZ * proj;
+
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+
+ // start query
+ if (pQuery)
+ pQuery->Begin();
+
+ context->Draw(NVRenderDrawMode::Triangles, 6, 0);
+
+ // end query
+ if (pQuery)
+ pQuery->End();
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+}
+
+bool NVRenderTestOcclusionQuery::occlusionPassTest(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ NVScopedRefCounted<NVRenderOcclusionQuery> pQuery = context->CreateOcclusionQuery();
+
+ renderPrim(context, pUserData, (void *)largeQuadPositions, 0.1, QT3DSVec3(0.0, 0.0, 1.0), NULL);
+ // this quad should be covered by the previous one
+ renderPrim(context, pUserData, (void *)smallQuadPositions, 0.2, QT3DSVec3(1.0, 1.0, 0.0), pQuery);
+ // check visibility
+ QT3DSU32 result = 0;
+ pQuery->GetResult(&result);
+
+ QT3DSVec3 color(0.0, 0.0, 0.0);
+ if (result)
+ color.x = 1.0; // wrong
+ else
+ color.y = 1.0; // right
+
+ renderQuad(context, pUserData, color);
+
+ return (result == 0);
+}
+
+bool NVRenderTestOcclusionQuery::occlusionFailTest(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ NVScopedRefCounted<NVRenderOcclusionQuery> pQuery = context->CreateOcclusionQuery();
+
+ renderPrim(context, pUserData, (void *)largeQuadPositions, 0.2, QT3DSVec3(0.0, 0.0, 1.0), NULL);
+ // this quad should be visible by the previous one
+ renderPrim(context, pUserData, (void *)smallQuadPositions, 0.1, QT3DSVec3(1.0, 1.0, 0.0), pQuery);
+ // check visibility
+ QT3DSU32 result = 0;
+ pQuery->GetResult(&result);
+
+ QT3DSVec3 color(0.0, 0.0, 0.0);
+ if (result == 0)
+ color.x = 1.0; // wrong
+ else
+ color.y = 1.0; // right
+
+ renderQuad(context, pUserData, color);
+
+ return (result == 1);
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestOcclusionQuery::runPerformance(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestOcclusionQuery::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(0.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.h b/tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.h
new file mode 100644
index 0000000..d540dad
--- /dev/null
+++ b/tests/auto/runtime/geometry/Qt3DSRenderTestOcclusionQuery.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2014 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_OCCLUSION_QUERY_H
+#define QT3DS_RENDER_TEST_OCCLUSION_QUERY_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderOcclusionQuery;
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestOcclusionQuery : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestOcclusionQuery();
+ ~NVRenderTestOcclusionQuery();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool occlusionPassTest(NVRenderContext *context, userContextData *pUserData);
+ bool occlusionFailTest(NVRenderContext *context, userContextData *pUserData);
+
+ bool renderQuad(NVRenderContext *context, userContextData *pUserData, QT3DSVec3 color);
+ void renderPrim(NVRenderContext *context, userContextData *pUserData, void *pData, float z,
+ QT3DSVec3 color, NVRenderOcclusionQuery *pQuery);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_OCCLUSION_QUERY_H
diff --git a/tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.cpp b/tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.cpp
new file mode 100644
index 0000000..f2724a4
--- /dev/null
+++ b/tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.cpp
@@ -0,0 +1,560 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestTessellation.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/backends/gl/Qt3DSOpenGLUtil.h"
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static const char *vertShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *vertPhongShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform mat4 mat_mvp;\n"
+ "in vec3 attr_pos; // Vertex pos\n"
+ "in vec3 attr_norm; // normal pos\n"
+ "out vec3 ctNorm; // output normal control patch\n"
+ "void main()\n"
+ "{\n"
+ " ctNorm = attr_norm;\n"
+ " gl_Position = vec4(attr_pos, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform vec3 color;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *fragPhongShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "uniform vec3 color;\n"
+ "in vec3 normWorld;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(color, 1.0);\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *tessControlShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_EXT_tessellation_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "// number of CPs in patch\n"
+ "layout (vertices = 3) out;\n"
+ "uniform float tessLevelInner; // controlled by keyboard buttons\n"
+ "uniform float tessLevelOuter; // controlled by keyboard buttons\n"
+ "void main () {\n"
+ "gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+ "// Calculate the tessellation levels\n"
+ "gl_TessLevelInner[0] = tessLevelInner; // number of nested primitives to generate\n"
+ "gl_TessLevelOuter[0] = tessLevelOuter; // times to subdivide first side\n"
+ "gl_TessLevelOuter[1] = tessLevelOuter; // times to subdivide second side\n"
+ "gl_TessLevelOuter[2] = tessLevelOuter; // times to subdivide third side\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *tessPhongControlShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_EXT_tessellation_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog +=
+ "// number of CPs in patch\n"
+ "layout (vertices = 3) out;\n"
+ "// phong tessellation per patch data\n"
+ "struct PhongTessPatch {\n"
+ " float projIJ;\n"
+ " float projJK;\n"
+ " float projIK;\n"
+ "};\n"
+ "in vec3 ctNorm[]; // control point normal\n"
+ "out vec3 normObj[]; // output normal pos\n"
+ "uniform float tessLevels;\n"
+ "uniform float tessBlend;\n"
+ "out PhongTessPatch tcTessPatch[3];\n"
+ "float PIi(int i, vec3 q)\n"
+ "{\n"
+ " vec3 q_minus_p = q - gl_in[i].gl_Position.xyz;\n"
+ " return q[gl_InvocationID] - dot(q_minus_p, ctNorm[i]) * ctNorm[i][gl_InvocationID];\n"
+ "}\n"
+ "void main () {\n"
+ " // path through data\n"
+ " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+ " normObj[gl_InvocationID] = ctNorm[gl_InvocationID];\n"
+ " // compute projections separate for each xyz component\n"
+ " tcTessPatch[gl_InvocationID].projIJ = PIi(0, gl_in[1].gl_Position.xyz) + PIi(1, "
+ "gl_in[0].gl_Position.xyz);\n"
+ " tcTessPatch[gl_InvocationID].projJK = PIi(1, gl_in[2].gl_Position.xyz) + PIi(2, "
+ "gl_in[1].gl_Position.xyz);\n"
+ " tcTessPatch[gl_InvocationID].projIK = PIi(2, gl_in[0].gl_Position.xyz) + PIi(0, "
+ "gl_in[2].gl_Position.xyz);\n"
+ " // set the tessellation levels\n"
+ " gl_TessLevelInner[0] = tessLevels; // number of nested primitives to generate\n"
+ " gl_TessLevelOuter[gl_InvocationID] = tessLevels; // times to subdivide first side\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *tessEvaluationShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_EXT_tessellation_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "// triangles, quads, or isolines\n"
+ "layout (triangles, equal_spacing, ccw) in;\n"
+ "uniform mat4 mat_mvp;\n"
+ "// gl_TessCoord is location within the patch\n"
+ "// (barycentric for triangles, UV for quads)\n"
+ "void main () {\n"
+ "vec4 p0 = gl_TessCoord.x * gl_in[0].gl_Position; // x is one corner\n"
+ "vec4 p1 = gl_TessCoord.y * gl_in[1].gl_Position; // y is the 2nd corner\n"
+ "vec4 p2 = gl_TessCoord.z * gl_in[2].gl_Position; // z is the 3rd corner (ignore when "
+ "using quads)\n"
+ "vec4 pos = p0 + p1 + p2;\n"
+ "gl_Position = mat_mvp * pos;\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+static const char *tessPhongEvaluationShader(std::string &prog, bool binESContext)
+{
+ if (binESContext) {
+ prog += "#version 310 es\n"
+ "#extension GL_EXT_tessellation_shader : enable\n"
+ "precision highp float;\n"
+ "precision highp int;\n";
+ } else {
+ prog += "#version 400\n";
+ }
+
+ prog += "// triangles, quads, or isolines\n"
+ "layout (triangles, fractional_odd_spacing, ccw) in;\n"
+ "struct PhongTessPatch {\n"
+ " float projIJ;\n"
+ " float projJK;\n"
+ " float projIK;\n"
+ "};\n"
+ "in vec3 normObj[]; // control point normal\n"
+ "out vec3 normWorld; // output normal pos\n"
+ "in PhongTessPatch tcTessPatch[];\n"
+ "uniform mat4 mat_mvp;\n"
+ "uniform float tessBlend;\n"
+ "// gl_TessCoord is location within the patch\n"
+ "// (barycentric for triangles, UV for quads)\n"
+ "void main () {\n"
+ " // output normal\n"
+ " // pre compute square tesselation coord\n"
+ " vec3 tessSquared = gl_TessCoord * gl_TessCoord;\n"
+ " vec3 norm = gl_TessCoord.x * normObj[0]\n"
+ " + gl_TessCoord.y * normObj[1]\n"
+ " + gl_TessCoord.z * normObj[2]; // z is the 3rd corner (ignore when "
+ "using quads)\n"
+ " // barycentric linear position\n"
+ " vec3 linearPos = gl_TessCoord.x * gl_in[0].gl_Position.xyz\n"
+ " + gl_TessCoord.y * gl_in[1].gl_Position.xyz\n"
+ " + gl_TessCoord.z * gl_in[2].gl_Position.xyz;\n"
+ " // projective terms\n"
+ " vec3 projJI = vec3(tcTessPatch[0].projIJ, tcTessPatch[1].projIJ, "
+ "tcTessPatch[2].projIJ);\n"
+ " vec3 projKJ = vec3(tcTessPatch[0].projJK, tcTessPatch[1].projJK, "
+ "tcTessPatch[2].projJK);\n"
+ " vec3 projIK = vec3(tcTessPatch[0].projIK, tcTessPatch[1].projIK, "
+ "tcTessPatch[2].projIK);\n"
+ " // phong interpolated position\n"
+ " vec3 phongPos = tessSquared.x * gl_in[0].gl_Position.xyz\n"
+ " + tessSquared.y * gl_in[1].gl_Position.xyz\n"
+ " + tessSquared.z * gl_in[2].gl_Position.xyz\n"
+ " + gl_TessCoord.x * gl_TessCoord.y * projJI\n"
+ " + gl_TessCoord.y * gl_TessCoord.z * projKJ\n"
+ " + gl_TessCoord.z * gl_TessCoord.x * projIK;\n"
+ " // final position\n"
+ " vec3 finalPos = (1.0-tessBlend)*linearPos + tessBlend*phongPos;\n"
+ " gl_Position = mat_mvp * vec4(finalPos, 1.0);\n"
+ " normWorld = norm;\n"
+ "}\n";
+
+ return prog.c_str();
+}
+
+struct Vertex
+{
+ QT3DSVec3 positions;
+ QT3DSVec3 normals;
+};
+
+NVRenderTestTessellation::NVRenderTestTessellation()
+{
+ _curTest = 0;
+ _maxColumn = 4;
+}
+
+NVRenderTestTessellation::~NVRenderTestTessellation()
+{
+}
+
+bool NVRenderTestTessellation::isSupported(NVRenderContext *context)
+{
+ NVRenderContextType ctxType = context->GetRenderContextType();
+ NVRenderContextType nonSupportedFlags(
+ NVRenderContextValues::GL2 | NVRenderContextValues::GLES2 | NVRenderContextValues::GL3
+ | NVRenderContextValues::GLES3 | NVRenderContextValues::GLES3PLUS);
+
+ // This is currently only supported on >= GL4 && >= GLES 3.1
+ if ((ctxType & nonSupportedFlags))
+ return false;
+
+ return true;
+}
+
+////////////////////////////////
+// test for functionality
+////////////////////////////////
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, (QT3DSU32)len);
+}
+
+bool NVRenderTestTessellation::run(NVRenderContext *context, userContextData *pUserData)
+{
+ bool success = true;
+
+ context->SetRenderTarget(NULL);
+ // conpute cell width
+ _cellSize = pUserData->winWidth / _maxColumn;
+
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 1.f));
+ context->Clear(NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+
+ success &= trianglePatches(context, pUserData);
+ _curTest++;
+ success &= phongPatches(context, pUserData);
+ _curTest++;
+
+ return success;
+}
+
+bool NVRenderTestTessellation::trianglePatches(NVRenderContext *context, userContextData *pUserData)
+{
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0) },
+ { QT3DSVec3(0.9, -0.9, 0) },
+ { QT3DSVec3(0.0, 0.9, 0) } };
+
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&mvp, -1, 1, -1, 1, -10, 10);
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ std::string tcProg;
+ std::string teProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestTessellation shader", toRef(vertShader(vtxProg, isGLESContext(context))),
+ toRef(fragShader(frgProg, isGLESContext(context))),
+ toRef(tessControlShader(tcProg, isGLESContext(context))),
+ toRef(tessEvaluationShader(teProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ };
+
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 6 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestFboMsaa: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 1));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Patches, 3);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestFboMsaa: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+ // set tessellation values
+ float tessLevelInner = 4.0;
+ compResult.mShader->SetPropertyValue("tessLevelInner", tessLevelInner);
+ float tessLevelOuter = 4.0;
+ compResult.mShader->SetPropertyValue("tessLevelOuter", tessLevelOuter);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+bool NVRenderTestTessellation::phongPatches(NVRenderContext *context, userContextData *pUserData)
+{
+ QT3DSVec3 n1(-1.0, 0.5, 1.0);
+ n1.normalize();
+ QT3DSVec3 n2(1.0, 0.5, 1.0);
+ n2.normalize();
+ QT3DSVec3 n3(0.0, 1.0, 1.0);
+ n3.normalize();
+ static const Vertex vertexPositions[] = { { QT3DSVec3(-0.9, -0.9, 0.0), n1 },
+ { QT3DSVec3(0.9, -0.9, 0.0), n2 },
+ { QT3DSVec3(0.0, 0.9, -0.0), n3 } };
+
+ qt3ds::QT3DSVec3 color(0.0, 1.0, 0.0);
+
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderAttribLayout> mAttribLayout;
+ NVScopedRefCounted<NVRenderInputAssembler> mInputAssembler;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ QT3DSMat44 p = QT3DSMat44::createIdentity();
+ QT3DSMat44 rotX = QT3DSMat44::createIdentity();
+ QT3DSMat44 rotY = QT3DSMat44::createIdentity();
+ QT3DSMat44 mv = QT3DSMat44::createIdentity();
+ QT3DSMat44 mvp = QT3DSMat44::createIdentity();
+ NvGl2DemoMatrixOrtho(&p, -1, 1, -1, 1, -10, 10);
+ // NvRenderTestMatrixRotY( &rotY, 45.0 );
+ // NvRenderTestMatrixRotX( &rotX, 90.0 );
+ mv = rotY * rotX;
+ mvp = mv * p;
+
+ // create shaders
+ std::string vtxProg;
+ std::string frgProg;
+ std::string tcProg;
+ std::string teProg;
+ NVRenderVertFragCompilationResult compResult = context->CompileSource(
+ "NVRenderTestTessellation shader", toRef(vertPhongShader(vtxProg, isGLESContext(context))),
+ toRef(fragPhongShader(frgProg, isGLESContext(context))),
+ toRef(tessPhongControlShader(tcProg, isGLESContext(context))),
+ toRef(tessPhongEvaluationShader(teProg, isGLESContext(context))));
+ if (!compResult.mShader) {
+ return false;
+ }
+
+ unsigned int curY = 0;
+ unsigned int curX = _curTest;
+ if (_curTest >= _maxColumn) {
+ curY = (_curTest / _maxColumn);
+ curX = (_curTest % _maxColumn);
+ }
+
+ // set viewport
+ context->SetViewport(NVRenderRect(curX * _cellSize, curY * _cellSize, _cellSize, _cellSize));
+
+ // this is the layout
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ NVRenderVertexBufferEntry("attr_norm", NVRenderComponentTypes::QT3DSF32, 3, 12),
+ };
+
+ QT3DSU32 bufSize = 3 * sizeof(Vertex);
+ NVDataRef<QT3DSU8> vertData((QT3DSU8 *)vertexPositions, bufSize);
+ mVertexBuffer = context->CreateVertexBuffer(NVRenderBufferUsageType::Static, bufSize,
+ 6 * sizeof(QT3DSF32), vertData);
+ if (!mVertexBuffer) {
+ qWarning() << "NVRenderTestFboMsaa: Failed to create vertex buffer";
+ return false;
+ }
+
+ // create our attribute layout
+ mAttribLayout = context->CreateAttributeLayout(toConstDataRef(entries, 2));
+ // create input Assembler
+ QT3DSU32 strides = mVertexBuffer->GetStride();
+ QT3DSU32 offsets = 0;
+ mInputAssembler = context->CreateInputAssembler(
+ mAttribLayout, toConstDataRef(&mVertexBuffer.mPtr, 1), mIndexBuffer.mPtr,
+ toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), NVRenderDrawMode::Patches, 3);
+ if (!mInputAssembler) {
+ qWarning() << "NVRenderTestFboMsaa: Failed to create input assembler";
+ return false;
+ }
+
+ // make input assembler active
+ context->SetInputAssembler(mInputAssembler);
+ // set program
+ context->SetActiveShader(compResult.mShader);
+ compResult.mShader->SetPropertyValue("mat_mvp", mvp);
+ // set color
+ compResult.mShader->SetPropertyValue("color", color);
+ // set tessellation values
+ float tessLevels = 8.0;
+ compResult.mShader->SetPropertyValue("tessLevels", tessLevels);
+ float tessBlend = 1.0;
+ compResult.mShader->SetPropertyValue("tessBlend", tessBlend);
+
+ context->SetDepthTestEnabled(true);
+ context->SetDepthWriteEnabled(true);
+
+ // draw
+ context->Draw(mInputAssembler->GetPrimitiveType(), 3, 0);
+
+ context->SetActiveShader(0);
+ compResult.mShader->release();
+
+ return true;
+}
+
+////////////////////////////////
+// performance test
+////////////////////////////////
+bool NVRenderTestTessellation::runPerformance(NVRenderContext *context, userContextData *pUserData)
+{
+ return true;
+}
+
+////////////////////////////////
+// test cleanup
+////////////////////////////////
+void NVRenderTestTessellation::cleanup(NVRenderContext *context, userContextData *pUserData)
+{
+ context->SetClearColor(QT3DSVec4(.0f, .0f, .0f, 0.f));
+ // dummy
+ context->SetViewport(NVRenderRect(0, 0, pUserData->winWidth, pUserData->winHeight));
+}
diff --git a/tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.h b/tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.h
new file mode 100644
index 0000000..7403696
--- /dev/null
+++ b/tests/auto/runtime/geometry/Qt3DSRenderTestTessellation.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_TESSELLATION_H
+#define QT3DS_RENDER_TEST_TESSELLATION_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ /// This class tests the creation of all kinds of primitives
+ class NVRenderTestTessellation : public NVRenderTestBase
+ {
+ public:
+ NVRenderTestTessellation();
+ ~NVRenderTestTessellation();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+ private:
+ bool trianglePatches(NVRenderContext *context, userContextData *pUserData);
+ bool phongPatches(NVRenderContext *context, userContextData *pUserData);
+
+ unsigned int _curTest;
+ unsigned int _cellSize;
+ unsigned int _maxColumn;
+ };
+}
+}
+
+#endif // QT3DS_RENDER_TEST_TESSELLATION_H
diff --git a/tests/auto/runtime/images/NVRenderTestAttribBuffers.png b/tests/auto/runtime/images/NVRenderTestAttribBuffers.png
new file mode 100644
index 0000000..e0fe946
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestAttribBuffers.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestBackendQuery.png b/tests/auto/runtime/images/NVRenderTestBackendQuery.png
new file mode 100644
index 0000000..7659236
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestBackendQuery.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestClear.png b/tests/auto/runtime/images/NVRenderTestClear.png
new file mode 100644
index 0000000..6e4c319
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestClear.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestComputeShader.png b/tests/auto/runtime/images/NVRenderTestComputeShader.png
new file mode 100644
index 0000000..6f08814
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestComputeShader.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestDrawIndirectBuffer.png b/tests/auto/runtime/images/NVRenderTestDrawIndirectBuffer.png
new file mode 100644
index 0000000..7659236
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestDrawIndirectBuffer.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestFboMsaa.png b/tests/auto/runtime/images/NVRenderTestFboMsaa.png
new file mode 100644
index 0000000..8eab95c
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestFboMsaa.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestGeometryShader.png b/tests/auto/runtime/images/NVRenderTestGeometryShader.png
new file mode 100644
index 0000000..820534e
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestGeometryShader.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestOcclusionQuery.png b/tests/auto/runtime/images/NVRenderTestOcclusionQuery.png
new file mode 100644
index 0000000..7659236
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestOcclusionQuery.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestProgramPipeline.png b/tests/auto/runtime/images/NVRenderTestProgramPipeline.png
new file mode 100644
index 0000000..f868b2d
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestProgramPipeline.png
Binary files differ
diff --git a/tests/auto/runtime/images/NVRenderTestTexture2D.png b/tests/auto/runtime/images/NVRenderTestTexture2D.png
new file mode 100644
index 0000000..afde59f
--- /dev/null
+++ b/tests/auto/runtime/images/NVRenderTestTexture2D.png
Binary files differ
diff --git a/tests/auto/runtime/runtime.pro b/tests/auto/runtime/runtime.pro
new file mode 100644
index 0000000..995c901
--- /dev/null
+++ b/tests/auto/runtime/runtime.pro
@@ -0,0 +1,82 @@
+TEMPLATE = app
+CONFIG += testcase
+include($$PWD/../../../commoninclude.pri)
+
+TARGET = tst_qt3dsruntime
+QT += testlib gui
+QT += quick-private
+
+RESOURCES += \
+ runtime.qrc
+
+INCLUDEPATH += \
+ $$PWD/../../../src/Qt3DSRuntimeRender/RendererImpl
+
+HEADERS += \
+ base/Qt3DSRenderTestAtomicCounterBuffer.h \
+ base/Qt3DSRenderTestAttribBuffers.h \
+ base/Qt3DSRenderTestBackendQuery.h \
+ base/Qt3DSRenderTestClear.h \
+ base/Qt3DSRenderTestConstantBuffer.h \
+ base/Qt3DSRenderTestDrawIndirectBuffer.h \
+ base/Qt3DSRenderTestPrimitives.h \
+ base/Qt3DSRenderTestProgramPipeline.h \
+ base/Qt3DSRenderTestTexture2D.h \
+ base/Qt3DSRenderTestTimerQuery.h \
+ compute/Qt3DSRenderTestComputeShader.h \
+ fbo/Qt3DSRenderTestFboMsaa.h \
+ geometry/Qt3DSRenderTestGeometryShader.h \
+ geometry/Qt3DSRenderTestOcclusionQuery.h \
+ geometry/Qt3DSRenderTestTessellation.h \
+ Qt3DSRenderTestBase.h \
+ Qt3DSRenderTestMathUtil.h \
+ tst_qt3dsruntime.h \
+ shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.h \
+ shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.h \
+ shadergenerator/Qt3DSRenderTestEffectGenerator.h
+
+SOURCES += \
+ base/Qt3DSRenderTestAtomicCounterBuffer.cpp \
+ base/Qt3DSRenderTestAttribBuffers.cpp \
+ base/Qt3DSRenderTestBackendQuery.cpp \
+ base/Qt3DSRenderTestClear.cpp \
+ base/Qt3DSRenderTestConstantBuffer.cpp \
+ base/Qt3DSRenderTestDrawIndirectBuffer.cpp \
+ base/Qt3DSRenderTestPrimitives.cpp \
+ base/Qt3DSRenderTestProgramPipeline.cpp \
+ base/Qt3DSRenderTestTexture2D.cpp \
+ base/Qt3DSRenderTestTimerQuery.cpp \
+ compute/Qt3DSRenderTestComputeShader.cpp \
+ fbo/Qt3DSRenderTestFboMsaa.cpp \
+ geometry/Qt3DSRenderTestGeometryShader.cpp \
+ geometry/Qt3DSRenderTestOcclusionQuery.cpp \
+ geometry/Qt3DSRenderTestTessellation.cpp \
+ Qt3DSRenderTestMathUtil.cpp \
+ tst_qt3dsruntime.cpp \
+ Qt3DSRenderTestBase.cpp \
+ shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.cpp \
+ shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp \
+ shadergenerator/Qt3DSRenderTestEffectGenerator.cpp
+
+linux {
+ BEGIN_ARCHIVE = -Wl,--whole-archive
+ END_ARCHIVE = -Wl,--no-whole-archive
+}
+
+LIBS += \
+ -lqt3dsopengl$$qtPlatformTargetSuffix() \
+ -lqt3dsqmlstreamer$$qtPlatformTargetSuffix()
+
+ANDROID_EXTRA_LIBS = \
+ libqt3dsqmlstreamer.so
+
+win32 {
+ LIBS += \
+ -lws2_32
+}
+
+linux {
+ LIBS += \
+ -ldl \
+ -lEGL
+}
diff --git a/tests/auto/runtime/runtime.qrc b/tests/auto/runtime/runtime.qrc
new file mode 100644
index 0000000..f4318f5
--- /dev/null
+++ b/tests/auto/runtime/runtime.qrc
@@ -0,0 +1,14 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/NVRenderTestTexture2D.png</file>
+ <file>images/NVRenderTestProgramPipeline.png</file>
+ <file>images/NVRenderTestAttribBuffers.png</file>
+ <file>images/NVRenderTestBackendQuery.png</file>
+ <file>images/NVRenderTestClear.png</file>
+ <file>images/NVRenderTestComputeShader.png</file>
+ <file>images/NVRenderTestDrawIndirectBuffer.png</file>
+ <file>images/NVRenderTestFboMsaa.png</file>
+ <file>images/NVRenderTestGeometryShader.png</file>
+ <file>images/NVRenderTestOcclusionQuery.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp
new file mode 100644
index 0000000..244065a
--- /dev/null
+++ b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp
@@ -0,0 +1,469 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestCustomMaterialGenerator.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderContext.h"
+#include "Qt3DSRenderCustomMaterialSystem.h"
+#include "Qt3DSRenderCustomMaterialRenderContext.h"
+#include "Qt3DSRenderCustomMaterialShaderGenerator.h"
+#include "Qt3DSRenderDynamicObjectSystem.h"
+#include "Qt3DSRenderDynamicObjectSystemCommands.h"
+#include "Qt3DSRenderContextCore.h"
+#include "Qt3DSTypes.h"
+#include "Qt3DSRenderRuntimeBinding.h"
+#include "Qt3DSApplication.h"
+#include "Qt3DSInputEngine.h"
+#include "foundation/FileTools.h"
+#include "Qt3DSWindowSystem.h"
+#include "Qt3DSRenderShaderCache.h"
+#include "rendererimpl/Qt3DSRendererImpl.h"
+#include "Qt3DSRenderLight.h"
+#include "Qt3DSRenderUIPLoader.h"
+#include "Qt3DSDMMetaDataTypes.h"
+
+#include <QTime>
+#include <QString>
+#include <QTextStream>
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+
+
+namespace qt3ds {
+namespace render {
+
+Qt3DSRenderTestCustomMaterialGenerator::Qt3DSRenderTestCustomMaterialGenerator()
+{
+
+}
+
+Qt3DSRenderTestCustomMaterialGenerator::~Qt3DSRenderTestCustomMaterialGenerator()
+{
+
+}
+
+
+bool Qt3DSRenderTestCustomMaterialGenerator::isSupported(NVRenderContext *context)
+{
+ Q_UNUSED(context);
+ return true;
+}
+
+bool Qt3DSRenderTestCustomMaterialGenerator::runPerformance(NVRenderContext *context,
+ userContextData *pContextData)
+{
+ Q_UNUSED(context);
+ Q_UNUSED(pContextData);
+ return false;
+}
+
+void Qt3DSRenderTestCustomMaterialGenerator::cleanup(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ Q_UNUSED(context);
+ Q_UNUSED(pUserData);
+}
+
+struct CustomTestParams
+{
+ SRenderableObjectFlags flags;
+ dynamic::SDynamicShaderProgramFlags dynamicFlags;
+ QT3DSF32 opacity;
+ SLayer layer;
+ SLayerRenderData layerData;
+ SRenderableImage *images;
+ SLight light[QT3DS_MAX_NUM_LIGHTS];
+ SModel model;
+ SRenderSubset subset;
+ SShaderDefaultMaterialKey shaderkey;
+ SCustomMaterial *material;
+ eastl::vector<SShaderPreprocessorFeature> features;
+ Option<qt3dsdm::SMetaDataCustomMaterial> metaMaterial;
+ SImage dummyImages[SShaderDefaultMaterialKeyProperties::ImageMapCount];
+ eastl::vector<SRenderableImage*> renderableImages;
+ qt3ds::render::Qt3DSRendererImpl *render;
+ SImage iblLightProbe;
+ NVRenderTexture2D *texture;
+
+ CustomTestParams(Qt3DSRendererImpl &impl)
+ : layerData(layer, impl)
+ , images(NULL)
+ , subset(impl.GetContext().GetAllocator())
+ , material(NULL)
+ , render(&impl)
+ , texture(NULL)
+ {
+ }
+ ~CustomTestParams()
+ {
+ if (texture)
+ texture->release();
+ }
+
+ void addRenderableImage(ImageMapTypes::Enum type,
+ SShaderDefaultMaterialKeyProperties::ImageMapNames name)
+ {
+ renderableImages.push_back(new SRenderableImage(type, dummyImages[name]));
+ render->DefaultMaterialShaderKeyProperties().m_ImageMaps[name].SetEnabled(shaderkey, true);
+ }
+ void prepare()
+ {
+ for (unsigned int i = 0; i < renderableImages.size(); i++) {
+ if (i == 0)
+ images = renderableImages[0];
+ else
+ renderableImages[i-1]->m_NextImage = renderableImages[i];
+ }
+ }
+};
+
+struct CustomTestKey
+{
+ unsigned int tessellation : 2;
+ unsigned int wireframe : 1;
+ unsigned int lighting: 1;
+ unsigned int indirectLightmap: 1;
+ unsigned int radiosityLightmap: 1;
+ unsigned int shadowLightmap: 1;
+ unsigned int transparency : 1;
+ unsigned int refraction : 1;
+ unsigned int iblprobe : 1;
+ unsigned int emissiveMap : 1;
+ unsigned int displacementMap : 1;
+ unsigned int diffuse = 1;
+ unsigned int specular = 1;
+ unsigned int glossy = 1;
+ unsigned int cutout = 1;
+ unsigned int transmissive : 1;
+ unsigned int ssao : 1;
+ unsigned int ssdo : 1;
+ unsigned int ssm : 1;
+
+ CustomTestKey(TessModeValues::Enum tess = TessModeValues::NoTess, bool wire = false,
+ bool lights = false, bool indirect = false, bool radiosity = false,
+ bool shadow = false, bool trans = false, bool refract = false, bool ibl = false,
+ bool emissive = false, bool disp = false, bool diff = false,
+ bool spec = false, bool glo = false, bool cut = false, bool transm = false,
+ bool ao = false, bool direct = false, bool shadowssm = false)
+ : tessellation(tess), wireframe(wire), lighting(lights), indirectLightmap(indirect)
+ , radiosityLightmap(radiosity), shadowLightmap(shadow), transparency(trans)
+ , refraction(refract), iblprobe(ibl), emissiveMap(emissive), displacementMap(disp)
+ , diffuse(diff), specular(spec), glossy(glo), cutout(cut), transmissive(transm)
+ , ssao(ao), ssdo(direct), ssm(shadowssm)
+ {
+
+ }
+
+ bool operator == (const CustomTestKey &other) const
+ {
+ uint64_t a = *(uint64_t *)this;
+ uint64_t b = *(uint64_t *)&other;
+ return a == b;
+ }
+
+ QString toString()
+ {
+ QString str;
+ QTextStream stream(&str);
+ stream << "Custom Key tessellation: " << int(tessellation);
+ stream << " wireframe: " << (wireframe ? "true" : "false");
+ stream << " lighting: " << (lighting ? "true" : "false");
+ stream << " indirectLightmap: " << (indirectLightmap ? "true" : "false");
+ stream << " radiosityLightmap: " << (radiosityLightmap ? "true" : "false");
+ stream << " shadowLightmap: " << (shadowLightmap ? "true" : "false");
+ stream << " transparency: " << (transparency ? "true" : "false");
+ stream << " refraction: " << (refraction ? "true" : "false");
+ stream << " iblprobe: " << (iblprobe ? "true" : "false");
+ stream << " emissiveMap: " << (emissiveMap ? "true" : "false");
+ stream << " displacementMap: " << (displacementMap ? "true" : "false");
+ stream << " diffuse: " << (diffuse ? "true" : "false");
+ stream << " specular: " << (specular ? "true" : "false");
+ stream << " glossy: " << (glossy ? "true" : "false");
+ stream << " cutout: " << (cutout ? "true" : "false");
+ stream << " transmissive: " << (transmissive ? "true" : "false");
+ stream << " ssao: " << (ssao ? "true" : "false");
+ stream << " ssdo: " << (ssdo ? "true" : "false");
+ stream << " ssm: " << (ssm ? "true" : "false");
+ return str;
+ }
+};
+
+#define MAX_TEST_KEY ((1llu<<20)-1)
+
+static CustomTestKey randomizeTestKey()
+{
+ uint64_t v = (uint64_t(qrand()))%MAX_TEST_KEY;
+ return *reinterpret_cast<CustomTestKey*>(&v);
+}
+
+CustomTestParams *generateTest(qt3ds::render::Qt3DSRendererImpl *renderImpl,
+ NVRenderContext *context, CustomTestKey key, SCustomMaterial *material)
+{
+ CustomTestParams *params = new CustomTestParams(*renderImpl);
+ params->material = material;
+ params->material->m_ShaderKeyValues = (SCustomMaterialShaderKeyFlags)0;
+ params->material->m_Lightmaps = SLightmaps();
+ params->material->m_DisplacementMap = NULL;
+ params->material->m_EmissiveMap2 = NULL;
+ params->material->m_hasTransparency = false;
+ params->material->m_IblProbe = NULL;
+ params->material->m_hasRefraction = false;
+ switch (key.tessellation) {
+ case 1:
+ params->model.m_TessellationMode = TessModeValues::TessLinear;
+ break;
+ case 2:
+ params->model.m_TessellationMode = TessModeValues::TessPhong;
+ break;
+ case 3:
+ params->model.m_TessellationMode = TessModeValues::TessNPatch;
+ break;
+ default:
+ params->model.m_TessellationMode = TessModeValues::NoTess;
+ break;
+ }
+
+ renderImpl->DefaultMaterialShaderKeyProperties()
+ .m_TessellationMode.SetValue(params->shaderkey, params->model.m_TessellationMode);
+
+ if (key.wireframe && key.tessellation > 0) {
+ params->subset.m_WireframeMode = true;
+ renderImpl->DefaultMaterialShaderKeyProperties().m_WireframeMode.SetValue(
+ params->shaderkey, true);
+ }
+
+ CRegisteredString lighting =
+ renderImpl->GetContext().GetStringTable().RegisterStr("QT3DS_ENABLE_CG_LIGHTING");
+ params->features.push_back(SShaderPreprocessorFeature(lighting, key.lighting));
+
+ if (key.indirectLightmap) {
+ params->material->m_Lightmaps.m_LightmapIndirect
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::LightmapIndirect];
+ params->addRenderableImage(ImageMapTypes::LightmapIndirect,
+ SShaderDefaultMaterialKeyProperties::LightmapIndirect);
+ }
+ if (key.radiosityLightmap) {
+ params->material->m_Lightmaps.m_LightmapRadiosity
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::LightmapRadiosity];
+ params->addRenderableImage(ImageMapTypes::LightmapRadiosity,
+ SShaderDefaultMaterialKeyProperties::LightmapRadiosity);
+ }
+ if (key.shadowLightmap) {
+ params->material->m_Lightmaps.m_LightmapShadow
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::LightmapShadow];
+ params->addRenderableImage(ImageMapTypes::LightmapRadiosity,
+ SShaderDefaultMaterialKeyProperties::LightmapShadow);
+ }
+
+ if (key.diffuse)
+ params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::diffuse;
+
+ // TODO: emissive mask doesn't work
+// if (key.emissiveMap >= 1) {
+// params->material->m_EmissiveMap2
+// = &params->dummyImages[SShaderDefaultMaterialKeyProperties::EmissiveMap];
+// params->addRenderableImage(ImageMapTypes::Emissive,
+// SShaderDefaultMaterialKeyProperties::EmissiveMap);
+// }
+
+ if (key.specular)
+ params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::specular;
+
+ if (key.displacementMap) {
+ params->material->m_DisplacementMap
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::DisplacementMap];
+ params->material->m_DisplacementMap->m_ImageShaderName
+ = renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("DisplacementMap");
+ params->material->m_DisplaceAmount = 1.0f;
+ params->addRenderableImage(ImageMapTypes::Displacement,
+ SShaderDefaultMaterialKeyProperties::DisplacementMap);
+
+ params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::displace;
+ }
+
+ if (key.iblprobe) {
+ renderImpl->DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(
+ params->shaderkey, true);
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_LIGHT_PROBE"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+
+ params->material->m_IblProbe = &params->iblLightProbe;
+ params->texture = context->CreateTexture2D();
+ NVRenderTextureFormats::Enum format = NVRenderTextureFormats::RGBA8;
+ unsigned int data = 0;
+ NVDataRef<QT3DSU8> buffer = toU8DataRef<unsigned int>(data);
+ params->texture->SetTextureData(buffer, 0, 1, 1, format);
+ params->iblLightProbe.m_TextureData.m_Texture = params->texture;
+ } else {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_LIGHT_PROBE"));
+ params->features.push_back(SShaderPreprocessorFeature(str, false));
+ }
+
+ // these requires calculateGlass function in material
+// if (key.transparency) {
+// params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::transparent;
+// params->material->m_hasTransparency = true;
+// }
+// if (key.refraction) {
+// params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::refraction;
+// params->material->m_hasRefraction = true;
+// }
+ if (key.glossy)
+ params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::glossy;
+
+ if (key.cutout)
+ params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::cutout;
+
+ if (key.transmissive)
+ params->material->m_ShaderKeyValues &= SCustomMaterialShaderKeyValues::transmissive;
+
+ if (key.ssm) {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_SSM"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ }
+ if (key.ssao) {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_SSAO"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ }
+ if (key.ssdo) {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_SSDO"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ }
+
+ params->prepare();
+ return params;
+}
+
+bool GenShader(IQt3DSRenderContext &qt3dsContext, CustomTestParams &params)
+{
+ bool success = true;
+ ICustomMaterialShaderGenerator &theMaterialGenerator(qt3dsContext.GetCustomMaterialShaderGenerator());
+
+ SCustomMaterialVertexPipeline thePipeline(&qt3dsContext,
+ params.model.m_TessellationMode);
+
+ for (int i = 0; i < params.metaMaterial->m_CustomMaterialCommands.size(); i++) {
+ dynamic::SCommand &command = *params.metaMaterial->m_CustomMaterialCommands[i];
+ if (command.m_Type == dynamic::CommandTypes::Enum::BindShader) {
+ dynamic::SBindShader *bindShader = static_cast<dynamic::SBindShader *>(&command);
+ NVRenderShaderProgram *theProgram = theMaterialGenerator.GenerateShader(
+ *params.material, params.shaderkey, thePipeline,
+ toConstDataRef(params.features.data(), (QT3DSU32)params.features.size()),
+ params.layerData.m_Lights, params.images,
+ (params.material->m_hasTransparency || params.material->m_hasRefraction),
+ "custom material pipeline-- ", bindShader->m_ShaderPath);
+ if (!theProgram) {
+ success = false;
+ break;
+ }
+ }
+ }
+
+ return success;
+}
+
+bool Qt3DSRenderTestCustomMaterialGenerator::run(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ Q_UNUSED(pUserData);
+ bool success = true;
+
+ QVector<CustomTestKey> testKeys;
+ testKeys.push_back(CustomTestKey());
+ testKeys.push_back(CustomTestKey(TessModeValues::TessLinear));
+ testKeys.push_back(CustomTestKey(TessModeValues::TessNPatch));
+ testKeys.push_back(CustomTestKey(TessModeValues::TessPhong));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true));
+ testKeys.push_back(CustomTestKey(TessModeValues::NoTess, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true));
+
+ while (testKeys.size() < 100) {
+ CustomTestKey key = randomizeTestKey();
+ if (!testKeys.contains(key))
+ testKeys.push_back(key);
+ }
+
+ if (success) {
+ CRegisteredString name = context->GetStringTable().RegisterStr("qrc:/copper.shader");
+
+ metadata()->LoadMaterialXMLFile("CustomMaterial", "", "copper", "qrc:/copper.shader");
+ Option<qt3dsdm::SMetaDataCustomMaterial> metaMaterial =
+ metadata()->GetMaterialMetaDataBySourcePath("qrc:/copper.shader");
+
+ if (metaMaterial.hasValue()) {
+ qt3ds::render::IUIPLoader::CreateMaterialClassFromMetaMaterial(
+ name, context->GetFoundation(),
+ qt3dsRenderer()->GetQt3DSContext().GetCustomMaterialSystem(), *metaMaterial,
+ context->GetStringTable());
+ SCustomMaterial *material = qt3dsRenderer()->GetQt3DSContext().GetCustomMaterialSystem()
+ .CreateCustomMaterial(name, qt3dsRenderer()->GetContext().GetAllocator());
+
+ for (CustomTestKey key : testKeys) {
+ CustomTestParams *params = generateTest(qt3dsRenderer(), context, key, material);
+ params->metaMaterial = metaMaterial;
+ success &= GenShader(qt3dsRenderer()->GetQt3DSContext(), *params);
+ if (!success)
+ qDebug () << "failing key: " << key.toString();
+ delete params;
+ }
+ delete material;
+ }
+ }
+
+ return success;
+}
+
+} // render
+} // qt3ds
diff --git a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.h b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.h
new file mode 100644
index 0000000..621d20f
--- /dev/null
+++ b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_CUSTOM_MATERIAL_GENERATOR_H
+#define QT3DS_RENDER_TEST_CUSTOM_MATERIAL_GENERATOR_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+class Qt3DSRenderTestCustomMaterialGenerator : public NVRenderTestBase
+{
+public:
+ Qt3DSRenderTestCustomMaterialGenerator();
+ ~Qt3DSRenderTestCustomMaterialGenerator();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+private:
+
+};
+
+} // render
+} // qt3ds
+
+#endif
diff --git a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.cpp b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.cpp
new file mode 100644
index 0000000..1e2c07e
--- /dev/null
+++ b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.cpp
@@ -0,0 +1,574 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestDefaultMaterialGenerator.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderContext.h"
+#include "Qt3DSTypes.h"
+#include "Qt3DSRenderRuntimeBinding.h"
+#include "Qt3DSApplication.h"
+#include "Qt3DSInputEngine.h"
+#include "foundation/FileTools.h"
+#include "Qt3DSWindowSystem.h"
+#include "Qt3DSRenderContextCore.h"
+#include "Qt3DSRenderShaderCache.h"
+#include "rendererimpl/Qt3DSRendererImpl.h"
+#include "Qt3DSRenderLight.h"
+
+#include <QTime>
+
+#include <string>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+
+
+namespace qt3ds {
+namespace render {
+
+Qt3DSRenderTestDefaultMaterialGenerator::Qt3DSRenderTestDefaultMaterialGenerator()
+{
+
+}
+
+Qt3DSRenderTestDefaultMaterialGenerator::~Qt3DSRenderTestDefaultMaterialGenerator()
+{
+
+}
+
+
+bool Qt3DSRenderTestDefaultMaterialGenerator::isSupported(NVRenderContext *context)
+{
+ Q_UNUSED(context);
+ return true;
+}
+
+bool Qt3DSRenderTestDefaultMaterialGenerator::runPerformance(NVRenderContext *context,
+ userContextData *pContextData)
+{
+ Q_UNUSED(context);
+ Q_UNUSED(pContextData);
+ return false;
+}
+
+void Qt3DSRenderTestDefaultMaterialGenerator::cleanup(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ Q_UNUSED(context);
+ Q_UNUSED(pUserData);
+}
+
+
+#define MAX_TEST_KEY ((1llu<<32)-1)
+
+struct TestKey
+{
+ unsigned int tessellation: 2;
+ unsigned int wireframe: 1;
+ unsigned int lighting: 2;
+ unsigned int lights: 4;
+ unsigned int indirectLightmap: 1;
+ unsigned int radiosityLightmap: 1;
+ unsigned int lightProbe: 2;
+ unsigned int iblLightProbe: 1;
+ unsigned int iblfow: 1;
+ unsigned int diffuseMap: 2;
+ unsigned int emissiveMap: 2;
+ unsigned int specularModel: 2;
+ unsigned int specularMap: 1;
+ unsigned int specularReflection: 1;
+ unsigned int fresnel: 1;
+ unsigned int bumpmapping: 2;
+ unsigned int displacementMap: 1;
+ unsigned int opacityMap: 1;
+ unsigned int translucencyMap: 1;
+ unsigned int ssm: 1;
+ unsigned int ssdo: 1;
+ unsigned int ssao: 1;
+
+ TestKey(TessModeValues::Enum tess = TessModeValues::NoTess, bool wire = false,
+ DefaultMaterialLighting::Enum lmode = DefaultMaterialLighting::NoLighting,
+ int lightCount = 0, bool indirect = false, bool radio = false, int lprobe = 0,
+ bool iblProbe = false, bool iblf = false, int diffuse = 0, int emissive = 0,
+ DefaultMaterialSpecularModel::Enum sModel = DefaultMaterialSpecularModel::Default,
+ bool sMap = false, bool sRef = false, bool fre = false, int bump = 0,
+ bool disp = false, bool opac = false, bool trans = false, bool shadow = false,
+ bool ao = false, bool directOcc = false)
+ : tessellation(tess), wireframe(wire), lighting(lmode), lights(lightCount)
+ , indirectLightmap(indirect), radiosityLightmap(radio), lightProbe(lprobe)
+ , iblLightProbe(iblProbe), iblfow(iblf), diffuseMap(diffuse), emissiveMap(emissive)
+ , specularModel(sModel), specularMap(sMap), specularReflection(sRef)
+ , fresnel(fre), bumpmapping(bump), displacementMap(disp), opacityMap(opac)
+ , translucencyMap(trans), ssm(shadow), ssao(ao), ssdo(directOcc)
+ {
+
+ }
+
+ bool operator == (const TestKey &other) const
+ {
+ return toInt() == other.toInt();
+ }
+
+ QString toString()
+ {
+ QString str;
+ QTextStream stream(&str);
+
+ stream << " tessellation: " << tessellation;
+ stream << " wireframe: " << (wireframe ? "true" : "false");
+ stream << " lighting: " << lighting;
+ stream << " lights: " << lights;
+ stream << " indirectLightmap: " << (indirectLightmap ? "true" : "false");
+ stream << " radiosityLightmap: " << (radiosityLightmap ? "true" : "false");
+ stream << " lightProbe: " << lightProbe;
+ stream << " iblLightProbe: " << (iblLightProbe ? "true" : "false");
+ stream << " iblfow: " << (iblfow ? "true" : "false");
+ stream << " diffuseMap: " << diffuseMap;
+ stream << " emissiveMap: " << emissiveMap;
+ stream << " specularModel: " << specularModel;
+ stream << " specularMap: " << (specularMap ? "true" : "false");
+ stream << " specularReflection: " << (specularReflection ? "true" : "false");
+ stream << " fresnel: " << (fresnel ? "true" : "false");
+ stream << " bumpmapping: " << bumpmapping;
+ stream << " displacementMap: " << (displacementMap ? "true" : "false");
+ stream << " opacityMap: " << (opacityMap ? "true" : "false");
+ stream << " translucencyMap: " << (translucencyMap ? "true" : "false");
+ stream << " ssm: " << (ssm ? "true" : "false");
+ stream << " ssdo: " << (ssdo ? "true" : "false");
+ stream << " ssao: " << (ssao ? "true" : "false");
+
+ return str;
+ }
+
+ void clampValues()
+ {
+ lighting = qMin(lighting, 2u);
+ if (lighting == 1)
+ lighting = 2;
+ emissiveMap = qMin(emissiveMap, 2u);
+ specularModel = qMin(specularModel, 2u);
+ bumpmapping = qMin(bumpmapping, 2u);
+ lightProbe = 0;
+ if (!iblLightProbe)
+ iblfow = 0;
+ if (!tessellation)
+ wireframe = 0;
+ }
+
+ uint64_t toInt() const
+ {
+ return (*(uint64_t *)this)&MAX_TEST_KEY;
+ }
+};
+
+struct TestParams
+{
+ SRenderableObjectFlags flags;
+ NVConstDataRef<QT3DSMat44> boneGlobals;
+ SRenderSubset subset;
+ SDefaultMaterial material;
+ SModel model;
+ QT3DSMat44 viewProjection;
+ SModelContext modelContext;
+ SRenderableImage *images;
+ SShaderDefaultMaterialKey shaderkey;
+ SSubsetRenderable renderable;
+ eastl::vector<SShaderPreprocessorFeature> features;
+ SLight light[QT3DS_MAX_NUM_LIGHTS];
+ SLayer layer;
+ SLayerRenderData layerData;
+ SImage dummyImages[SShaderDefaultMaterialKeyProperties::ImageMapCount];
+ NVRenderTexture2D *textures[4];
+ eastl::vector<SRenderableImage*> renderableImages;
+ qt3ds::render::Qt3DSRendererImpl *render;
+
+ TestParams(NVRenderContext *context, qt3ds::render::Qt3DSRendererImpl *renderImpl)
+ : subset(context->GetAllocator())
+ , modelContext(model, viewProjection)
+ , images(NULL)
+ , renderable(flags, QT3DSVec3(), *renderImpl, subset, material, modelContext, 1.0f, images,
+ shaderkey, boneGlobals)
+ , layerData(layer, *renderImpl)
+ , render(renderImpl)
+ {
+ for (int i = 0; i < 4; ++i) {
+ textures[i] = context->CreateTexture2D();
+ NVRenderTextureFormats::Enum format = NVRenderTextureFormats::RGBA8;
+ unsigned int data = 0;
+ NVDataRef<QT3DSU8> buffer = toU8DataRef<unsigned int>(data);
+ textures[i]->SetTextureData(buffer, 0, 1, 1, format);
+ }
+ for (int i = 0; i < SShaderDefaultMaterialKeyProperties::ImageMapCount; ++i)
+ dummyImages[i].m_TextureData.m_Texture = textures[i%4];
+ dummyImages[SShaderDefaultMaterialKeyProperties::DiffuseMap1].m_TextureData.
+ m_TextureFlags.SetPreMultiplied(true);
+ dummyImages[SShaderDefaultMaterialKeyProperties::EmissiveMap2].m_TextureData.
+ m_TextureFlags.SetInvertUVCoords(true);
+ }
+ ~TestParams()
+ {
+ for (NVRenderTexture2D *tex : textures)
+ tex->release();
+ for (SRenderableImage *img : renderableImages)
+ delete img;
+ }
+ void addRenderableImage(ImageMapTypes::Enum type,
+ SShaderDefaultMaterialKeyProperties::ImageMapNames name)
+ {
+ renderableImages.push_back(new SRenderableImage(type, dummyImages[name]));
+ render->DefaultMaterialShaderKeyProperties().m_ImageMaps[name].SetEnabled(shaderkey, true);
+ }
+ void prepare()
+ {
+ for (unsigned int i = 0; i < renderableImages.size(); i++) {
+ if (i == 0)
+ images = renderableImages[0];
+ else {
+ renderableImages[i-1]->m_NextImage = renderableImages[i];
+ }
+
+ }
+ renderable.m_ShaderDescription = shaderkey;
+ renderable.m_FirstImage = images;
+ }
+};
+
+TestKey randomizeTestKey()
+{
+ uint64_t v = (uint64_t(qrand()) << 32 | uint64_t(qrand()))&MAX_TEST_KEY;
+ TestKey key = *reinterpret_cast<TestKey*>(&v);
+ key.clampValues();
+ return key;
+}
+
+
+TestParams *generateTest(qt3ds::render::Qt3DSRendererImpl *renderImpl,
+ NVRenderContext *context, TestKey key)
+{
+ // TODO: light probes
+ TestParams *params = new TestParams(context, renderImpl);
+
+ switch (key.tessellation) {
+ case 1:
+ params->model.m_TessellationMode = TessModeValues::TessLinear;
+ break;
+ case 2:
+ params->model.m_TessellationMode = TessModeValues::TessPhong;
+ break;
+ case 3:
+ params->model.m_TessellationMode = TessModeValues::TessNPatch;
+ break;
+ default:
+ params->model.m_TessellationMode = TessModeValues::NoTess;
+ break;
+ }
+
+ renderImpl->DefaultMaterialShaderKeyProperties()
+ .m_TessellationMode.SetValue(params->shaderkey, params->model.m_TessellationMode);
+
+ switch (key.lighting) {
+ case 1:
+ params->material.m_Lighting = DefaultMaterialLighting::VertexLighting;
+ break;
+ case 2:
+ params->material.m_Lighting = DefaultMaterialLighting::FragmentLighting;
+ break;
+ default:
+ params->material.m_Lighting = DefaultMaterialLighting::NoLighting;
+ break;
+ }
+ if (key.lighting != 0) {
+ renderImpl->DefaultMaterialShaderKeyProperties()
+ .m_HasLighting.SetValue(params->shaderkey, true);
+ }
+
+ if (key.wireframe && key.tessellation > 0) {
+ params->subset.m_WireframeMode = true;
+ renderImpl->DefaultMaterialShaderKeyProperties().m_WireframeMode.SetValue(
+ params->shaderkey, true);
+ }
+ bool castShadow = false;
+ key.lights = qMin(int(key.lights), int(QT3DS_MAX_NUM_LIGHTS));
+ for (unsigned int i = 0; i < key.lights; ++i) {
+ params->light[i].m_LightType = static_cast<RenderLightTypes::Enum>((i%3)+1);
+ if (params->light[i].m_LightType != RenderLightTypes::Directional) {
+ renderImpl->DefaultMaterialShaderKeyProperties().m_LightFlags[i].SetValue(
+ params->shaderkey, true);
+ }
+ if (params->light[i].m_LightType == RenderLightTypes::Area) {
+ renderImpl->DefaultMaterialShaderKeyProperties()
+ .m_LightAreaFlags[i]
+ .SetValue(params->shaderkey, true);
+ }
+ if (params->light[i].m_LightType != RenderLightTypes::Point) {
+ renderImpl->DefaultMaterialShaderKeyProperties()
+ .m_LightShadowFlags[i]
+ .SetValue(params->shaderkey, castShadow);
+ castShadow = !castShadow;
+ }
+ params->layerData.m_Lights.push_back(&params->light[i]);
+ }
+
+ renderImpl->DefaultMaterialShaderKeyProperties().m_LightCount.SetValue(params->shaderkey,
+ key.lights);
+
+ // shadow lightmap is not used
+ if (key.indirectLightmap) {
+ params->material.m_Lightmaps.m_LightmapIndirect
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::LightmapIndirect];
+ params->addRenderableImage(ImageMapTypes::LightmapIndirect,
+ SShaderDefaultMaterialKeyProperties::LightmapIndirect);
+ }
+ if (key.radiosityLightmap) {
+ params->material.m_Lightmaps.m_LightmapRadiosity
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::LightmapRadiosity];
+ params->addRenderableImage(ImageMapTypes::LightmapRadiosity,
+ SShaderDefaultMaterialKeyProperties::LightmapRadiosity);
+ }
+
+ for (unsigned int i = 0; i < key.diffuseMap; ++i) {
+ params->material.m_DiffuseMaps[i]
+ = &params->dummyImages[static_cast<SShaderDefaultMaterialKeyProperties::ImageMapNames>
+ (SShaderDefaultMaterialKeyProperties::DiffuseMap0 + i)];
+ params->addRenderableImage(ImageMapTypes::Diffuse,
+ static_cast<SShaderDefaultMaterialKeyProperties::ImageMapNames>
+ (SShaderDefaultMaterialKeyProperties::DiffuseMap0 + i));
+ }
+
+ if (key.emissiveMap >= 1) {
+ params->material.m_EmissiveMap
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::EmissiveMap];
+ params->addRenderableImage(ImageMapTypes::Emissive,
+ SShaderDefaultMaterialKeyProperties::EmissiveMap);
+ }
+ if (key.emissiveMap == 2) {
+ params->material.m_EmissiveMap2
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::EmissiveMap2];
+ params->addRenderableImage(ImageMapTypes::Emissive,
+ SShaderDefaultMaterialKeyProperties::EmissiveMap2);
+ }
+
+ switch (key.specularModel) {
+ case 1:
+ params->material.m_SpecularModel = DefaultMaterialSpecularModel::KGGX;
+ break;
+ case 2:
+ params->material.m_SpecularModel = DefaultMaterialSpecularModel::KWard;
+ break;
+ default:
+ params->material.m_SpecularModel = DefaultMaterialSpecularModel::Default;
+ break;
+ }
+
+ if (key.specularMap) {
+ params->material.m_SpecularMap =
+ &params->dummyImages[SShaderDefaultMaterialKeyProperties::SpecularAmountMap];
+ params->material.m_SpecularAmount = 1.0f;
+ params->addRenderableImage(ImageMapTypes::SpecularAmountMap,
+ SShaderDefaultMaterialKeyProperties::SpecularAmountMap);
+ }
+ if (key.specularReflection) {
+ params->dummyImages[SShaderDefaultMaterialKeyProperties::SpecularMap].m_MappingMode
+ = ImageMappingModes::Environment;
+ params->material.m_SpecularAmount = 1.0f;
+ params->material.m_SpecularReflection
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::SpecularMap];
+ params->addRenderableImage(ImageMapTypes::Specular,
+ SShaderDefaultMaterialKeyProperties::SpecularMap);
+ }
+ if (key.fresnel)
+ params->material.m_FresnelPower = 1.0f;
+
+ if (key.bumpmapping == 1) {
+ params->material.m_BumpMap
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::BumpMap];
+ params->material.m_BumpAmount = 1.0f;
+ params->addRenderableImage(ImageMapTypes::Bump, SShaderDefaultMaterialKeyProperties::BumpMap);
+ }
+ if (key.bumpmapping == 2) {
+ params->material.m_NormalMap
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::NormalMap];
+ params->addRenderableImage(ImageMapTypes::Normal, SShaderDefaultMaterialKeyProperties::NormalMap);
+ }
+
+ if (key.displacementMap) {
+ params->material.m_DisplacementMap
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::DisplacementMap];
+ params->material.m_DisplaceAmount = 1.0f;
+ params->addRenderableImage(ImageMapTypes::Displacement,
+ SShaderDefaultMaterialKeyProperties::DisplacementMap);
+ }
+
+ if (key.opacityMap) {
+ params->material.m_OpacityMap
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::OpacityMap];
+ params->material.m_Opacity = 0.5f;
+ params->addRenderableImage(ImageMapTypes::Opacity,
+ SShaderDefaultMaterialKeyProperties::OpacityMap);
+ }
+
+ if (key.translucencyMap) {
+ params->material.m_TranslucencyMap
+ = &params->dummyImages[SShaderDefaultMaterialKeyProperties::TranslucencyMap];
+ params->material.m_TranslucentFalloff = 0.1f;
+ params->addRenderableImage(ImageMapTypes::Translucency,
+ SShaderDefaultMaterialKeyProperties::TranslucencyMap);
+ }
+
+ if (key.ssm) {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_SSM"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ }
+ if (key.ssao) {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_SSAO"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ }
+ if (key.ssdo) {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_SSDO"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ }
+
+ if (key.iblLightProbe) {
+ renderImpl->DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(
+ params->shaderkey, true);
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_LIGHT_PROBE"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ if (key.iblfow) {
+ CRegisteredString str(renderImpl->GetQt3DSContext().GetStringTable()
+ .RegisterStr("QT3DS_ENABLE_IBL_FOV"));
+ params->features.push_back(SShaderPreprocessorFeature(str, true));
+ }
+ }
+
+ if (params->material.IsSpecularEnabled()) {
+ renderImpl->DefaultMaterialShaderKeyProperties().m_SpecularEnabled.SetValue(
+ params->shaderkey, true);
+ renderImpl->DefaultMaterialShaderKeyProperties().m_SpecularModel.SetSpecularModel(
+ params->shaderkey, params->material.m_SpecularModel);
+ }
+ if (params->material.IsFresnelEnabled()) {
+ renderImpl->DefaultMaterialShaderKeyProperties().m_FresnelEnabled.SetValue(
+ params->shaderkey, true);
+ }
+
+ params->prepare();
+ return params;
+}
+
+
+
+bool Qt3DSRenderTestDefaultMaterialGenerator::run(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ Q_UNUSED(pUserData);
+ bool success = true;
+
+ qsrand(QTime::currentTime().msec());
+
+ QVector<TestKey> testKeys;
+
+ testKeys.push_back(TestKey());
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 1));
+ testKeys.push_back(TestKey(TessModeValues::TessLinear, false, DefaultMaterialLighting::FragmentLighting, 1));
+ testKeys.push_back(TestKey(TessModeValues::TessNPatch, false, DefaultMaterialLighting::FragmentLighting, 1));
+ testKeys.push_back(TestKey(TessModeValues::TessPhong, false, DefaultMaterialLighting::FragmentLighting, 1));
+ testKeys.push_back(TestKey(TessModeValues::TessLinear, true, DefaultMaterialLighting::FragmentLighting, 1));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 6));
+ // vertex lighting is not supported?
+ //testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::VertexLighting, 6));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 1, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 1, true, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 2));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 3, true, true, 0, false, false, 3));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 3, true, true, 0, false, false, 1, 1));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 4, true, true, 0, false, false, 1, 2));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 4, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::KGGX, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 5, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::KWard, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 5, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 6, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 6, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 1));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 2));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 0, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 0, true, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 0, true, true, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 0, true, true, true, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 0, true, true, true, false, true));
+ testKeys.push_back(TestKey(TessModeValues::NoTess, false, DefaultMaterialLighting::FragmentLighting, 2, true, true, 0, false, false, 1, 1, DefaultMaterialSpecularModel::Default, true, true, true, 0, true, true, true, true, false, true));
+
+ while (testKeys.size() < 100) {
+ TestKey key = randomizeTestKey();
+ if (!testKeys.contains(key))
+ testKeys.push_back(key);
+ }
+ // generated programs must be unique
+ QVector<NVRenderShaderProgram *> programs;
+ success = initializeQt3DSRenderer(context->format());
+ if (success) {
+ for (TestKey key : testKeys) {
+ qDebug () << "testing key: " << key.toInt();
+ TestParams *params = generateTest(qt3dsRenderer(), context, key);
+
+ qt3dsRenderer()->BeginLayerRender(params->layerData);
+ NVRenderShaderProgram *program
+ = qt3dsRenderer()->GenerateShader(params->renderable,
+ toConstDataRef(params->features.data(),
+ (QT3DSU32)params->features.size()));
+ if (!program) {
+ success = false;
+ } else {
+ if (programs.contains(program)) {
+ qDebug () << "Generated program is not unique vs " << testKeys[programs.indexOf(program)].toString();
+ success = false;
+ }
+ else {
+ programs.push_back(program);
+ }
+ }
+
+ if (!success)
+ qDebug () << "failing test key: " << key.toString();
+
+ qt3dsRenderer()->EndLayerRender();
+ delete params;
+ }
+ }
+
+ return success;
+}
+
+} // render
+} // qt3ds
diff --git a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.h b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.h
new file mode 100644
index 0000000..c1464a3
--- /dev/null
+++ b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_DEFAULT_MATERIAL_GENERATOR_H
+#define QT3DS_RENDER_TEST_DEFAULT_MATERIAL_GENERATOR_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+
+namespace qt3ds {
+namespace render {
+
+class Qt3DSRenderTestDefaultMaterialGenerator : public NVRenderTestBase
+{
+public:
+ Qt3DSRenderTestDefaultMaterialGenerator();
+ ~Qt3DSRenderTestDefaultMaterialGenerator();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+private:
+
+};
+
+} // render
+} // qt3ds
+
+#endif
diff --git a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.cpp b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.cpp
new file mode 100644
index 0000000..48346e6
--- /dev/null
+++ b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSRenderTestEffectGenerator.h"
+#include "../Qt3DSRenderTestMathUtil.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderContext.h"
+#include "Qt3DSRenderCustomMaterialSystem.h"
+#include "Qt3DSRenderCustomMaterialRenderContext.h"
+#include "Qt3DSRenderCustomMaterialShaderGenerator.h"
+#include "Qt3DSRenderDynamicObjectSystem.h"
+#include "Qt3DSRenderDynamicObjectSystemCommands.h"
+#include "Qt3DSRenderContextCore.h"
+#include "Qt3DSTypes.h"
+#include "Qt3DSRenderRuntimeBinding.h"
+#include "Qt3DSApplication.h"
+#include "Qt3DSInputEngine.h"
+#include "foundation/FileTools.h"
+#include "Qt3DSWindowSystem.h"
+#include "Qt3DSRenderShaderCache.h"
+#include "rendererimpl/Qt3DSRendererImpl.h"
+#include "Qt3DSRenderLight.h"
+#include "Qt3DSRenderUIPLoader.h"
+#include "Qt3DSDMMetaDataTypes.h"
+
+#include <QTime>
+#include <QString>
+#include <QStringList>
+
+#include <string>
+
+using namespace qt3ds::render;
+
+namespace qt3ds {
+namespace render {
+
+Qt3DSRenderTestEffectGenerator::Qt3DSRenderTestEffectGenerator()
+{
+
+}
+
+Qt3DSRenderTestEffectGenerator::~Qt3DSRenderTestEffectGenerator()
+{
+
+}
+
+bool Qt3DSRenderTestEffectGenerator::isSupported(NVRenderContext *context)
+{
+ Q_UNUSED(context);
+ return true;
+}
+
+bool Qt3DSRenderTestEffectGenerator::runPerformance(NVRenderContext *context,
+ userContextData *pContextData)
+{
+ Q_UNUSED(context);
+ Q_UNUSED(pContextData);
+ return false;
+}
+
+void Qt3DSRenderTestEffectGenerator::cleanup(NVRenderContext *context,
+ userContextData *pUserData)
+{
+ Q_UNUSED(context);
+ Q_UNUSED(pUserData);
+}
+
+bool GenShader(IQt3DSRenderContext &qt3dsContext, SEffect &effect, qt3dsdm::SMetaDataEffect *metaEffect)
+{
+ bool success = true;
+ for (int i = 0; i < metaEffect->m_EffectCommands.size(); i++) {
+ dynamic::SCommand &command = *metaEffect->m_EffectCommands[i];
+ if (command.m_Type == dynamic::CommandTypes::Enum::BindShader) {
+ dynamic::SBindShader *bindShader = static_cast<dynamic::SBindShader *>(&command);
+ NVRenderShaderProgram *theProgram =
+ qt3dsContext.GetDynamicObjectSystem()
+ .GetShaderProgram(bindShader->m_ShaderPath, bindShader->m_ShaderDefine,
+ TShaderFeatureSet(), dynamic::SDynamicShaderProgramFlags())
+ .first;
+ if (!theProgram)
+ success = false;
+ }
+ }
+ return success;
+}
+
+bool Qt3DSRenderTestEffectGenerator::run(NVRenderContext *context, userContextData *pUserData)
+{
+ Q_UNUSED(pUserData);
+ bool success = true;
+
+ QStringList effectFiles;
+ effectFiles.append("Desaturate.effect");
+ effectFiles.append("Gaussian Blur.effect");
+ effectFiles.append("Sepia.effect");
+ effectFiles.append("Bloom.effect");
+
+ for (QString effectName : effectFiles) {
+ QString qfile = "qrc:/";
+ qfile.append(effectName);
+ QByteArray data = qfile.toLatin1();
+ const char *cname = data.data();
+ CRegisteredString name = context->GetStringTable().RegisterStr(cname);
+
+ metadata()->LoadEffectXMLFile("Effect", "", effectName.toLatin1().data(), cname);
+ Option<qt3dsdm::SMetaDataEffect> metaEffect =
+ metadata()->GetEffectMetaDataBySourcePath(cname);
+
+ if (metaEffect.hasValue()) {
+ qt3ds::render::IUIPLoader::CreateEffectClassFromMetaEffect(
+ name, context->GetFoundation(),
+ qt3dsRenderer()->GetQt3DSContext().GetEffectSystem(), *metaEffect,
+ context->GetStringTable());
+
+ SEffect *effect = qt3dsRenderer()->GetQt3DSContext().GetEffectSystem()
+ .CreateEffectInstance(name, qt3dsRenderer()->GetContext().GetAllocator());
+
+ success &= GenShader(qt3dsRenderer()->GetQt3DSContext(), *effect, &metaEffect.getValue());
+ if (!success)
+ qDebug () << "failed effect: " << effectName;
+ delete effect;
+ }
+ }
+
+ return success;
+}
+
+} // render
+} // qt3ds
diff --git a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.h b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.h
new file mode 100644
index 0000000..4e26cf3
--- /dev/null
+++ b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestEffectGenerator.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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_TEST_EFFECT_GENERATOR_H
+#define QT3DS_RENDER_TEST_EFFECT_GENERATOR_H
+
+#include "../Qt3DSRenderTestBase.h"
+
+namespace qt3ds {
+namespace render {
+
+class Qt3DSRenderTestEffectGenerator : public NVRenderTestBase
+{
+public:
+ Qt3DSRenderTestEffectGenerator();
+ ~Qt3DSRenderTestEffectGenerator();
+
+ bool isSupported(NVRenderContext *context);
+ bool run(NVRenderContext *context, userContextData *pUserData);
+ bool runPerformance(NVRenderContext *context, userContextData *pContextData);
+ void cleanup(NVRenderContext *context, userContextData *pUserData);
+
+private:
+
+};
+
+} // render
+} // qt3ds
+
+#endif
diff --git a/tests/auto/runtime/tst_qt3dsruntime.cpp b/tests/auto/runtime/tst_qt3dsruntime.cpp
new file mode 100644
index 0000000..763529c
--- /dev/null
+++ b/tests/auto/runtime/tst_qt3dsruntime.cpp
@@ -0,0 +1,727 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "tst_qt3dsruntime.h"
+
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/TrackingAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/StringTable.h"
+#include "foundation/Qt3DSMat44.h"
+
+#include "base/Qt3DSRenderTestClear.h"
+#include "base/Qt3DSRenderTestPrimitives.h"
+#include "base/Qt3DSRenderTestConstantBuffer.h"
+#include "base/Qt3DSRenderTestBackendQuery.h"
+#include "base/Qt3DSRenderTestTimerQuery.h"
+#include "base/Qt3DSRenderTestTexture2D.h"
+#include "base/Qt3DSRenderTestAtomicCounterBuffer.h"
+#include "base/Qt3DSRenderTestDrawIndirectBuffer.h"
+#include "base/Qt3DSRenderTestAttribBuffers.h"
+#include "base/Qt3DSRenderTestProgramPipeline.h"
+#include "fbo/Qt3DSRenderTestFboMsaa.h"
+#include "geometry/Qt3DSRenderTestTessellation.h"
+#include "geometry/Qt3DSRenderTestGeometryShader.h"
+#include "geometry/Qt3DSRenderTestOcclusionQuery.h"
+#include "compute/Qt3DSRenderTestComputeShader.h"
+#include "shadergenerator/Qt3DSRenderTestDefaultMaterialGenerator.h"
+#include "shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.h"
+#include "shadergenerator/Qt3DSRenderTestEffectGenerator.h"
+
+#include <QImage>
+#include <QOpenGLContext>
+#include <QOffscreenSurface>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLFramebufferObjectFormat>
+
+using namespace std;
+using namespace qt3ds;
+using namespace qt3ds::render;
+using namespace qt3ds::foundation;
+
+extern "C" {
+bool InitializeGL();
+}
+
+// Enable this to dump the test output into a log.txt file
+//#define DUMP_LOGFILE
+
+#ifndef EA_PLATFORM_WINDOWS
+
+#ifndef EASTL_DEBUG_BREAK
+void EASTL_DEBUG_BREAK()
+{
+ return;
+}
+#endif
+
+namespace qt3ds {
+void NVAssert(const char *exp, const char *file, int line, bool *ignore)
+{
+ *ignore = true;
+ QString message = QString("failed: %1, file %2, line %3\n")
+ .arg(exp).arg(file).arg(line);
+ QFAIL(message.toLatin1().constData());
+}
+}
+#endif
+
+void messageOutput(QtMsgType type, const QMessageLogContext &context,
+ const QString &msg)
+{
+ Q_UNUSED(context);
+ switch (type) {
+ case QtDebugMsg:
+ case QtInfoMsg:
+ case QtWarningMsg:
+ case QtCriticalMsg: {
+#ifdef DUMP_LOGFILE
+ QFile file("log.txt");
+ if (file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
+ QTextStream stream(&file);
+ stream << msg;
+ }
+ file.close();
+#endif
+ } break; // swallow
+ case QtFatalMsg:
+ QFAIL(msg.toLocal8Bit().constData());
+ }
+}
+
+void tst_qt3dsruntime::initTestCase()
+{
+ qInstallMessageHandler(messageOutput);
+#ifdef DUMP_LOGFILE
+ QFile file("log.txt");
+ if (file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
+ QTextStream stream(&file);
+ stream << "Log file: " << QTime::currentTime().toString() << "\n";
+ }
+ file.close();
+#endif
+}
+
+QSurfaceFormat makeFormat(int major, int minor, bool gles = false, bool coreProfile = true)
+{
+ QSurfaceFormat format;
+ format.setDepthBufferSize(32);
+ format.setVersion(major, minor);
+ if (coreProfile)
+ format.setProfile(QSurfaceFormat::CoreProfile);
+ else
+ format.setProfile(QSurfaceFormat::CompatibilityProfile);
+ if (gles)
+ format.setRenderableType(QSurfaceFormat::OpenGLES);
+ return format;
+}
+
+bool tst_qt3dsruntime::init(QSurfaceFormat format)
+{
+ m_glContext = new QT_PREPEND_NAMESPACE(QOpenGLContext)(this);
+ m_glContext->setFormat(format);
+ bool success = m_glContext->create();
+ if (!success)
+ return false;
+
+ m_glSurface = new QOffscreenSurface;
+ m_glSurface->setFormat(format);
+ m_glSurface->create();
+ m_glContext->makeCurrent(m_glSurface);
+
+ m_allocator = new CAllocator;
+ m_foundation = NVCreateFoundation(QT3DS_FOUNDATION_VERSION, *m_allocator);
+ m_stringTable = &IStringTable::CreateStringTable(*m_allocator);
+ m_renderContext = &NVRenderContext::CreateGL(*m_foundation, *m_stringTable, format);
+ return true;
+}
+
+bool tst_qt3dsruntime::init()
+{
+#if defined(QT_OPENGL_ES_2)
+ return init(makeFormat(2, 0, true, false));
+#elif defined(Q_OS_ANDROID) || defined(QT_OPENGL_ES_3)
+ return init(makeFormat(3, 2, true, false));
+#else
+ return init(makeFormat(4, 3));
+#endif
+}
+
+bool tst_qt3dsruntime::executeTest(NVRenderTestBase *curTest,
+ const QString &testName,
+ bool performPixelTest)
+{
+ bool success = true;
+ int width = 640;
+ int height = 480;
+ userContextData userData = { (unsigned int)width, (unsigned int)height };
+
+ QOpenGLFramebufferObjectFormat fboFormat;
+ fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(QSize(width, height), fboFormat);
+
+ m_renderContext->SetDefaultRenderTarget(fbo->handle());
+ m_renderContext->SetDefaultDepthBufferBitCount(m_glContext->format().depthBufferSize());
+ m_renderContext->SetViewport(NVRenderRect(0, 0, userData.winWidth, userData.winHeight));
+
+ success = curTest->run(m_renderContext, &userData);
+
+ if (performPixelTest) {
+ QImage image = fbo->toImage();
+ QImage refImage(QString(":/images/%1.png").arg(testName));
+ refImage = refImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ if (!refImage.isNull()) {
+ bool pixelTest = image == refImage;
+ success &= pixelTest;
+ if (!pixelTest)
+ image.save(QString("%1_failed.png").arg(testName));
+ }
+ }
+
+ curTest->cleanup(m_renderContext, &userData);
+
+ return success;
+}
+
+void tst_qt3dsruntime::testNVRenderTestClear()
+{
+ init();
+ NVRenderTestClear *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestClear);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ bool success = executeTest(test, "NVRenderTestClear");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestPrimitives()
+{
+ init();
+ NVRenderTestPrimitives *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestPrimitives);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ bool success = executeTest(test, "NVRenderTestPrimitives");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestConstantBuffer()
+{
+ init();
+ NVRenderTestConstantBuffer *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestConstantBuffer);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ bool success = executeTest(test, "NVRenderTestConstantBuffer");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestBackendQuery()
+{
+ init();
+ NVRenderTestBackendQuery *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestBackendQuery);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestBackendQuery", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestTimerQuery()
+{
+ init();
+ NVRenderTestTimerQuery *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestTimerQuery);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ bool success = executeTest(test, "NVRenderTestTimerQuery");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestFboMsaa()
+{
+ init();
+ NVRenderTestFboMsaa *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestFboMsaa);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestFboMsaa", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestTessellation()
+{
+ init();
+ NVRenderTestTessellation *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestTessellation);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ bool success = executeTest(test, "NVRenderTestTessellation");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestGeometryShader()
+{
+ init();
+ NVRenderTestGeometryShader *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestGeometryShader);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ bool success = executeTest(test, "NVRenderTestGeometryShader");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestComputeShader()
+{
+ init();
+ NVRenderTestComputeShader *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestComputeShader);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestComputeShader", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestOcclusionQuery()
+{
+ init();
+ NVRenderTestOcclusionQuery *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestOcclusionQuery);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestOcclusionQuery", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestTexture2D()
+{
+ init();
+ NVRenderTestTexture2D *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestTexture2D);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestTexture2D", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestAtomicCounterBuffer()
+{
+ init();
+ NVRenderTestAtomicCounterBuffer *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestAtomicCounterBuffer);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ bool success = executeTest(test, "NVRenderTestAtomicCounterBuffer");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestDrawIndirectBuffer()
+{
+ init();
+ NVRenderTestDrawIndirectBuffer *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestDrawIndirectBuffer);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestDrawIndirectBuffer", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestAttribBuffers()
+{
+ init();
+ NVRenderTestAttribBuffers *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestAttribBuffers);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestAttribBuffers", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testNVRenderTestProgramPipeline()
+{
+ init();
+ NVRenderTestProgramPipeline *test =
+ QT3DS_NEW(m_foundation->getAllocator(), NVRenderTestProgramPipeline);
+ if (!test->isSupported(m_renderContext)) {
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ QSKIP("not supported");
+ }
+ // TODO: Fix BOUL-332 to re-enable this pixel test
+ bool success = executeTest(test, "NVRenderTestProgramPipeline", false);
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+#if defined(QT_OPENGL_ES_2)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_200es()
+{
+ if (init(makeFormat(2, 0, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_200es()
+{
+ runCustomShaderGeneratorTest(makeFormat(2, 0, true, false));
+ cleanup();
+}
+#endif
+
+#if defined(QT_OPENGL_ES_3)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_300es()
+{
+ if (init(makeFormat(3, 0, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_300es()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 0, true, false));
+ cleanup();
+}
+
+#if defined(QT_FEATURE_opengles31)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_310es()
+{
+ if (init(makeFormat(3, 1, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_310es()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 1, true, false));
+ cleanup();
+}
+#endif
+#if defined(QT_FEATURE_opengles32)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_320es()
+{
+ if (init(makeFormat(3, 1, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_320es()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 1, true, false));
+ cleanup();
+}
+
+#endif
+#endif
+
+#if defined(QT_OPENGL_DYNAMIC)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_300()
+{
+ QSKIP("OpenGL 3.0 is not supported");
+ if (init(makeFormat(3, 0))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_310()
+{
+ if (init(makeFormat(3, 1))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_320()
+{
+ if (init(makeFormat(3, 2))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_330()
+{
+ if (init(makeFormat(3, 3))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_400()
+{
+ if (init(makeFormat(4, 0))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_410()
+{
+ if (init(makeFormat(4, 1))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_420()
+{
+ if (init(makeFormat(4, 2))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_430()
+{
+ if (init(makeFormat(4, 3))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_300()
+{
+ QSKIP("OpenGL 3.0 is not supported");
+ runCustomShaderGeneratorTest(makeFormat(3, 0));
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_310()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 1));
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_320()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 2));
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_330()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 3));
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_400()
+{
+ runCustomShaderGeneratorTest(makeFormat(4, 0));
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_410()
+{
+ runCustomShaderGeneratorTest(makeFormat(4, 1));
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_420()
+{
+ runCustomShaderGeneratorTest(makeFormat(4, 2));
+}
+
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_430()
+{
+ runCustomShaderGeneratorTest(makeFormat(4, 3));
+}
+
+#endif
+
+void tst_qt3dsruntime::runDefaultShaderGeneratorTest()
+{
+ Qt3DSRenderTestDefaultMaterialGenerator *test =
+ QT3DS_NEW(m_foundation->getAllocator(), Qt3DSRenderTestDefaultMaterialGenerator);
+ if (!test->isSupported(m_renderContext))
+ QSKIP("not supported");
+ bool success = executeTest(test, "Qt3DSRenderTestDefaultMaterialGenerator");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+}
+
+void tst_qt3dsruntime::runCustomShaderGeneratorTest(QSurfaceFormat format)
+{
+ m_glContext = new QT_PREPEND_NAMESPACE(QOpenGLContext)(this);
+ m_glContext->setFormat(format);
+ bool success = m_glContext->create();
+ if (!success)
+ return;
+
+ m_glSurface = new QOffscreenSurface;
+ m_glSurface->setFormat(format);
+ m_glSurface->create();
+ m_glContext->makeCurrent(m_glSurface);
+
+ m_allocator = new CAllocator;
+ m_foundation = NVCreateFoundation(QT3DS_FOUNDATION_VERSION, *m_allocator);
+
+ Qt3DSRenderTestCustomMaterialGenerator *test =
+ QT3DS_NEW(m_foundation->getAllocator(), Qt3DSRenderTestCustomMaterialGenerator);
+
+ test->initializeQt3DSRenderer(format);
+ m_renderContext = &NVRenderContext::CreateGL(*m_foundation, test->qt3dsRenderer()->GetContext()
+ .GetStringTable(), format);
+
+ if (!test->isSupported(m_renderContext))
+ QSKIP("not supported");
+ success = executeTest(test, "Qt3DSRenderTestCusromMaterialGenerator");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::testRenderEffectGenerator()
+{
+ QSurfaceFormat format = makeFormat(4, 3);
+ m_glContext = new QT_PREPEND_NAMESPACE(QOpenGLContext)(this);
+ m_glContext->setFormat(format);
+ bool success = m_glContext->create();
+ if (!success)
+ return;
+
+ m_glSurface = new QOffscreenSurface;
+ m_glSurface->setFormat(format);
+ m_glSurface->create();
+ m_glContext->makeCurrent(m_glSurface);
+
+ m_allocator = new CAllocator;
+ m_foundation = NVCreateFoundation(QT3DS_FOUNDATION_VERSION, *m_allocator);
+
+ Qt3DSRenderTestEffectGenerator *test =
+ QT3DS_NEW(m_foundation->getAllocator(), Qt3DSRenderTestEffectGenerator);
+
+ test->initializeQt3DSRenderer(format);
+ m_renderContext = &NVRenderContext::CreateGL(*m_foundation, test->qt3dsRenderer()->GetContext()
+ .GetStringTable(), format);
+
+ if (!test->isSupported(m_renderContext))
+ QSKIP("not supported");
+ success = executeTest(test, "Qt3DSRenderTestEffectGenerator");
+ QT3DS_FREE(m_foundation->getAllocator(), test);
+ test = 0;
+ QVERIFY(success);
+ cleanup();
+}
+
+void tst_qt3dsruntime::cleanup()
+{
+ if (m_renderContext)
+ m_renderContext->release();
+ if (m_foundation)
+ m_foundation->release();
+
+ m_renderContext = 0;
+ m_stringTable = 0;
+ m_foundation = 0;
+
+ delete m_allocator;
+ m_allocator = 0;
+
+ m_glSurface->destroy();
+ delete m_glSurface;
+ m_glSurface = 0;
+
+ delete m_glContext;
+ m_glContext = 0;
+}
+
+QTEST_MAIN(tst_qt3dsruntime)
diff --git a/tests/auto/runtime/tst_qt3dsruntime.h b/tests/auto/runtime/tst_qt3dsruntime.h
new file mode 100644
index 0000000..1f5b943
--- /dev/null
+++ b/tests/auto/runtime/tst_qt3dsruntime.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 TST_QT3DSRUNTIME
+#define TST_QT3DSRUNTIME
+
+#include <QtTest/QtTest>
+#include <QtTest/QSignalSpy>
+
+namespace qt3ds {
+class NVFoundation;
+namespace foundation {
+class CAllocator;
+class IStringTable;
+}
+namespace render {
+class NVRenderContext;
+class NVRenderTestBase;
+}
+}
+
+QT_BEGIN_NAMESPACE
+class QOpenGLContext;
+class QOffscreenSurface;
+QT_END_NAMESPACE
+
+class tst_qt3dsruntime : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qt3dsruntime()
+ : m_allocator(0)
+ , m_foundation(0)
+ , m_stringTable(0)
+ , m_renderContext(0)
+ , m_glContext(0)
+ , m_glSurface(0)
+ {
+ }
+
+private Q_SLOTS:
+ void initTestCase();
+
+ void testNVRenderTestClear();
+ void testNVRenderTestPrimitives();
+ void testNVRenderTestConstantBuffer();
+ void testNVRenderTestBackendQuery();
+ void testNVRenderTestTimerQuery();
+ void testNVRenderTestFboMsaa();
+ void testNVRenderTestTessellation();
+ void testNVRenderTestGeometryShader();
+ void testNVRenderTestComputeShader();
+ void testNVRenderTestOcclusionQuery();
+ void testNVRenderTestTexture2D();
+ void testNVRenderTestAtomicCounterBuffer();
+ void testNVRenderTestDrawIndirectBuffer();
+ void testNVRenderTestAttribBuffers();
+ void testNVRenderTestProgramPipeline();
+
+ void testRenderEffectGenerator();
+
+#if defined(QT_OPENGL_ES_2)
+ void testRenderDefaultShaderGenerator_200es();
+ void testRenderCustomShaderGenerator_200es();
+#endif
+#if defined(QT_OPENGL_ES_3)
+ void testRenderDefaultShaderGenerator_300es();
+ void testRenderCustomShaderGenerator_300es();
+#if defined(QT_FEATURE_opengles31)
+ void testRenderDefaultShaderGenerator_310es();
+ void testRenderCustomShaderGenerator_310es();
+#endif
+#if defined(QT_FEATURE_opengles32)
+ void testRenderDefaultShaderGenerator_320es();
+ void testRenderCustomShaderGenerator_320es();
+#endif
+#endif
+
+#if defined(QT_OPENGL_DYNAMIC)
+ void testRenderDefaultShaderGenerator_300();
+ void testRenderDefaultShaderGenerator_310();
+ void testRenderDefaultShaderGenerator_320();
+ void testRenderDefaultShaderGenerator_330();
+ void testRenderDefaultShaderGenerator_400();
+ void testRenderDefaultShaderGenerator_410();
+ void testRenderDefaultShaderGenerator_420();
+ void testRenderDefaultShaderGenerator_430();
+
+ void testRenderCustomShaderGenerator_300();
+ void testRenderCustomShaderGenerator_310();
+ void testRenderCustomShaderGenerator_320();
+ void testRenderCustomShaderGenerator_330();
+ void testRenderCustomShaderGenerator_400();
+ void testRenderCustomShaderGenerator_410();
+ void testRenderCustomShaderGenerator_420();
+ void testRenderCustomShaderGenerator_430();
+#endif
+
+
+
+private:
+ bool executeTest(qt3ds::render::NVRenderTestBase *curTest,
+ const QString &testName, bool peformPixelTest = true);
+ bool init(QSurfaceFormat format);
+ bool init();
+ void runDefaultShaderGeneratorTest();
+ void runCustomShaderGeneratorTest(QSurfaceFormat format);
+ void cleanup();
+
+ qt3ds::foundation::CAllocator *m_allocator;
+ qt3ds::NVFoundation *m_foundation;
+ qt3ds::foundation::IStringTable *m_stringTable;
+ qt3ds::render::NVRenderContext *m_renderContext;
+ QOpenGLContext *m_glContext;
+ QOffscreenSurface *m_glSurface;
+};
+
+#endif // TST_QT3DSRUNTIME