diff options
Diffstat (limited to 'src/Runtime/Source/render')
102 files changed, 29099 insertions, 0 deletions
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp new file mode 100644 index 00000000..f67cf717 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "foundation/Qt3DSVec4.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +namespace { +class ClearColor : public NVRenderExample +{ + NVRenderContext &m_Context; + +public: + ClearColor(NVRenderContext &ctx) + : m_Context(ctx) + { + } + virtual void drawFrame(double currentSeconds) + { + // Apply this value immediately but track it so that a later pop will in fact + // restore this value. + if (currentSeconds < 1) + m_Context.SetClearColor(QT3DSVec4(.8f, .0f, .0f, 1.f)); + else if (currentSeconds < 2) + m_Context.SetClearColor(QT3DSVec4(0.f, .0f, 1.f, 1.f)); + else + m_Context.SetClearColor(QT3DSVec4(0.f, 1.0f, 1.f, 1.f)); + m_Context.Clear(NVRenderClearFlags(NVRenderClearValues::Color)); + } + virtual QT3DSU32 getRuntimeInSeconds() { return 2; } + virtual void release() { NVDelete(m_Context.GetFoundation(), this); } +}; +} + +// QT3DS_RENDER_REGISTER_EXAMPLE( ClearColor );
\ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp new file mode 100644 index 00000000..d866cda0 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp @@ -0,0 +1,491 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "render/NvRenderBaseTypes.h" +#include "render_util/NVRenderAllocator.h" +#include "render_util/NVRenderErrorStream.h" +#include "render_util/NVRenderUtils.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSTime.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSMath.h" + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +using namespace qt3ds; +using namespace qt3ds::render; + +static TExampleCreateFunc gCreateFuncs[128]; + +TExampleCreateFunc *NVRenderExampleFactory::mExampleCreators = gCreateFuncs; +QT3DSU32 NVRenderExampleFactory::mMaxCreators = 128; +QT3DSU32 NVRenderExampleFactory::mNumCreators = 0; +namespace { +NVRenderErrorStream g_errorStream; +NVRenderAllocator g_allocator(g_errorStream); +NVFoundation *g_foundation(NULL); +NVRenderContext *g_renderContext(NULL); +NVRenderExample *g_example(NULL); +QT3DSI32 g_exampleIdx(0); +Time::Second g_runTime; +Time g_timer; +} + +bool NVRenderExampleFactory::nextExample() +{ + if (g_example) + g_example->release(); + g_example = 0; + if (g_exampleIdx < (int)mNumCreators) { + g_example = mExampleCreators[g_exampleIdx](*g_renderContext); + ++g_exampleIdx; + g_runTime = g_example->getRuntimeInSeconds(); + g_timer = Time(); + return true; + } + return false; +} + +void NVRenderExampleFactory::beginExamples() +{ + g_foundation = NVCreateFoundation(QT3DS_FOUNDATION_VERSION, g_allocator, g_errorStream); + g_renderContext = + &NVRenderContext::CreateGL(*g_foundation, NVRenderContextType(NVRenderContextValues::GL2)); + nextExample(); +} +bool NVRenderExampleFactory::update() +{ + Time::Second currentTime = g_timer.peekElapsedSeconds(); + if (currentTime > g_runTime) + nextExample(); + if (g_example) + g_example->drawFrame(currentTime); + + return g_example != NULL; +} + +void NVRenderExampleFactory::endExamples() +{ + g_exampleIdx = mNumCreators; + nextExample(); + if (g_renderContext) + g_renderContext->release(); + if (g_foundation) + g_foundation->release(); + + g_renderContext = NULL; + g_foundation = NULL; +} + +namespace qt3ds { +namespace render { + /////////////////////////////////////////////////////////////////////////////// + + // Math stuff + + int eq(float a, float b) + { + float diff = a - b; + if (diff < 0) { + diff = -diff; + } + return diff <= eps; + } + + // + // Matrix functions, since GLES 2.x doesn't provide them + // + + void NvGl2DemoMatrixIdentity(float m[16]) + { + memset(m, 0, sizeof(float) * 16); + m[4 * 0 + 0] = m[4 * 1 + 1] = m[4 * 2 + 2] = m[4 * 3 + 3] = 1.0; + } + + int NvGl2DemoMatrixEquals(float a[16], float b[16]) + { + int i; + for (i = 0; i < 16; ++i) + if (!eq(a[i], b[i])) + return 0; + + return 1; + } + + void NvGl2DemoMatrixTranspose(float m[16]) + { + int i, j; + float t; + for (i = 1; i < 4; ++i) + for (j = 0; j < i; ++j) { + t = m[4 * i + j]; + m[4 * i + j] = m[4 * j + i]; + m[4 * j + i] = t; + } + } + + void NvGl2DemoMatrixMultiply(float m0[16], float m1[16]) + { + int r, c, i; + for (r = 0; r < 4; r++) { + float m[4] = { 0.0, 0.0, 0.0, 0.0 }; + for (c = 0; c < 4; c++) { + for (i = 0; i < 4; i++) { + m[c] += m0[4 * i + r] * m1[4 * c + i]; + } + } + for (c = 0; c < 4; c++) { + m0[4 * c + r] = m[c]; + } + } + } + + void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9]) + { + int r, c, i; + for (r = 0; r < 4; r++) { + float m[3] = { 0.0, 0.0, 0.0 }; + for (c = 0; c < 3; c++) { + for (i = 0; i < 3; i++) { + m[c] += m0[4 * i + r] * m1[3 * c + i]; + } + } + for (c = 0; c < 3; c++) { + m0[4 * c + r] = m[c]; + } + } + } + + void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9]) + { + int r, c, i; + for (r = 0; r < 3; r++) { + float m[3] = { 0.0, 0.0, 0.0 }; + for (c = 0; c < 3; c++) { + for (i = 0; i < 3; i++) { + m[c] += m0[3 * i + r] * m1[3 * c + i]; + } + } + for (c = 0; c < 3; c++) { + m0[3 * c + r] = m[c]; + } + } + } + + void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f) + { + float m1[16]; + float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv, twoNear; + + rightMinusLeftInv = 1.0f / (r - l); + topMinusBottomInv = 1.0f / (t - b); + farMinusNearInv = 1.0f / (f - n); + twoNear = 2.0f * n; + + m1[0] = twoNear * rightMinusLeftInv; + m1[1] = 0.0f; + m1[2] = 0.0f; + m1[3] = 0.0f; + + m1[4] = 0.0f; + m1[5] = twoNear * topMinusBottomInv; + m1[6] = 0.0f; + m1[7] = 0.0f; + + m1[8] = (r + l) * rightMinusLeftInv; + m1[9] = (t + b) * topMinusBottomInv; + m1[10] = -(f + n) * farMinusNearInv; + m1[11] = -1.0f; + + m1[12] = 0.0f; + m1[13] = 0.0f; + m1[14] = -(twoNear * f) * farMinusNearInv; + m1[15] = 0.0f; + + NvGl2DemoMatrixMultiply(m, m1); + } + + void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f) + { + float m1[16]; + float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv; + + rightMinusLeftInv = 1.0f / (r - l); + topMinusBottomInv = 1.0f / (t - b); + farMinusNearInv = 1.0f / (f - n); + + m1[0] = 2.0f * rightMinusLeftInv; + m1[1] = 0.0f; + m1[2] = 0.0f; + m1[3] = 0.0f; + + m1[4] = 0.0f; + m1[5] = 2.0f * topMinusBottomInv; + m1[6] = 0.0f; + m1[7] = 0.0f; + + m1[8] = 0.0f; + m1[9] = 0.0f; + m1[10] = -2.0f * farMinusNearInv; + m1[11] = 0.0f; + + m1[12] = -(r + l) * rightMinusLeftInv; + m1[13] = -(t + b) * topMinusBottomInv; + m1[14] = -(f + n) * farMinusNearInv; + m1[15] = 1.0f; + + NvGl2DemoMatrixMultiply(m, m1); + } + + void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z) + { + float m1[16]; + NvGl2DemoMatrixIdentity(m1); + + m1[4 * 3 + 0] = x; + m1[4 * 3 + 1] = y; + m1[4 * 3 + 2] = z; + + NvGl2DemoMatrixMultiply(m, m1); + } + + void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z) + { + float len = (float)sqrtf(x * x + y * y + z * z); + float u0 = x / len; + float u1 = y / len; + float u2 = z / len; + float rad = (float)(theta / 180 * NVPi); + float c = (float)cosf(rad); + float s = (float)sinf(rad); + m[3 * 0 + 0] = u0 * u0 + c * (1 - u0 * u0) + s * 0; + m[3 * 0 + 1] = u0 * u1 + c * (0 - u0 * u1) + s * u2; + m[3 * 0 + 2] = u0 * u2 + c * (0 - u0 * u2) - s * u1; + + m[3 * 1 + 0] = u1 * u0 + c * (0 - u1 * u0) - s * u2; + m[3 * 1 + 1] = u1 * u1 + c * (1 - u1 * u1) + s * 0; + m[3 * 1 + 2] = u1 * u2 + c * (0 - u1 * u2) + s * u0; + + m[3 * 2 + 0] = u2 * u0 + c * (0 - u2 * u0) + s * u1; + m[3 * 2 + 1] = u2 * u1 + c * (0 - u2 * u1) - s * u0; + m[3 * 2 + 2] = u2 * u2 + c * (1 - u2 * u2) + s * 0; + } + + void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z) + { + float r[9]; + NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z); + NvGl2DemoMatrixMultiply_4x4_3x3(m, r); + } + + void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z) + { + float r[9]; + NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z); + NvGl2DemoMatrixMultiply_3x3(m, r); + } + + float NvGl2DemoMatrixDeterminant(float m[16]) + { + return m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] + + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] + + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] + + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] + + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2] + + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] + + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3] + - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] + - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3] + + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; + } + + void NvGl2DemoMatrixInverse(float m[16]) + { + float a[16]; + float det; + int i; + float b[16], e[16]; + + a[4 * 0 + 0] = m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] + - m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] + + m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] + - m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] + + m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 0 + 1] = m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1] + - m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2] + + m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2] + + m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3] + - m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 0 + 2] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 1] + - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 1] + + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 2] + - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 3] + + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 3]; + a[4 * 0 + 3] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1] + - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1] + - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2] + + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2] + + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3] + - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3]; + a[4 * 1 + 0] = m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] + - m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] + + m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] + + m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] + - m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 1 + 1] = m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0] + + m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2] + - m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3]; + a[4 * 1 + 2] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 2] + + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 2] + + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 3] + - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 3]; + a[4 * 1 + 3] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0] + + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2] + - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2] + - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3] + + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3]; + a[4 * 2 + 0] = m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] + + m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] + - m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] + - m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] + + m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3]; + a[4 * 2 + 1] = m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1] + + m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3] + - m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3]; + a[4 * 2 + 2] = m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 0] + + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 1] + - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 1] + - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 3] + + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 3]; + a[4 * 2 + 3] = m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0] + - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0] + - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1] + + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1] + + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3] + - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3]; + a[4 * 3 + 0] = m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] + - m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] + - m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] + + m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] + + m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] + - m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2]; + a[4 * 3 + 1] = m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0] + + m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1] + - m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1] + - m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2] + + m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2]; + a[4 * 3 + 2] = m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 0] + - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 1] + + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 1] + + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 2] + - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 2]; + a[4 * 3 + 3] = m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0] + - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0] + + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1] + - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1] + - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2] + + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2]; + + det = NvGl2DemoMatrixDeterminant(m); + + for (i = 0; i < 16; ++i) + a[i] /= det; + + NvGl2DemoMatrixIdentity(e); + + NvGl2DemoMatrixCopy(b, m); + NvGl2DemoMatrixMultiply(b, a); + + NvGl2DemoMatrixCopy(m, a); + } + + void NvGl2DemoMatrixCopy(float dest[16], float src[16]) + { + memcpy(dest, src, 16 * sizeof(float)); + } + + void NvGl2DemoMatrixPrint(float a[16]) + { + int i, j; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 4; ++j) + printf("%f%c", a[4 * i + j], j == 3 ? '\n' : ' '); + } + + void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4]) + { + float res[4]; + int i, j; + + for (i = 0; i < 4; ++i) { + res[i] = 0; + for (j = 0; j < 4; ++j) + res[i] += m[i * 4 + j] * v[j]; + } + + memcpy(v, res, sizeof(res)); + } +} +}
\ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h new file mode 100644 index 00000000..79bfd911 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_EXAMPLE_H +#define QT3DS_RENDER_EXAMPLE_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/NvRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + class NVRenderContext; + + class NVRenderExample + { + protected: + virtual ~NVRenderExample() {} + public: + virtual void drawFrame(double currentSeconds) = 0; + virtual QT3DSU32 getRuntimeInSeconds() { return 5; } + virtual void handleKeypress(int /*keypress*/) {} + virtual void release() = 0; + }; + + typedef NVRenderExample *(*TExampleCreateFunc)(NVRenderContext &context); + + struct NVRenderExampleFactory + { + static TExampleCreateFunc *mExampleCreators; + static QT3DSU32 mMaxCreators; + static QT3DSU32 mNumCreators; + + static void addCreator(TExampleCreateFunc creator) + { + if (mNumCreators < mMaxCreators) { + mExampleCreators[mNumCreators] = creator; + ++mNumCreators; + } else + QT3DS_ASSERT(false); + } + + // Assuming that the render context is egl + // Relies on the global structures defined in demo common + // to figure out window state. + static bool nextExample(); + static void beginExamples(); + static bool update(); + static void endExamples(); + }; + + template <typename TExample> + struct NVRenderExampleCreator + { + + static NVRenderExample *createExample(NVRenderContext &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), TExample)(context); + } + NVRenderExampleCreator() { NVRenderExampleFactory::addCreator(createExample); } + }; + +#define QT3DS_RENDER_REGISTER_EXAMPLE(dtype) static NVRenderExampleCreator<dtype> dtype##Creator + +#define eps 1e-4 + + int eq(float a, float b); + + // Matrix functions + void NvGl2DemoMatrixIdentity(float m[16]); + int NvGl2DemoMatrixEquals(float a[16], float b[16]); + void NvGl2DemoMatrixTranspose(float m[16]); + void NvGl2DemoMatrixMultiply(float m0[16], float m1[16]); + void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9]); + void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9]); + void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f); + void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f); + void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z); + void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z); + void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z); + void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z); + + float NvGl2DemoMatrixDeterminant(float m[16]); + void NvGl2DemoMatrixInverse(float m[16]); + void NvGl2DemoMatrixCopy(float dest[16], float src[16]); + + void NvGl2DemoMatrixPrint(float a[16]); + + void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4]); +} +} + +#endif
\ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp new file mode 100644 index 00000000..efae6f5e --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExampleTools.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render_util/NVRenderUtils.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSVec4.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +struct BoxFace +{ + QT3DSVec3 positions[4]; + QT3DSVec3 normal; +}; + +static const BoxFace g_BoxFaces[] = { + { // Z+ + QT3DSVec3(-1, -1, 1), QT3DSVec3(-1, 1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(0, 0, 1) }, + { // X+ + QT3DSVec3(1, -1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, -1, -1), QT3DSVec3(1, 0, 0) }, + { // Z- + QT3DSVec3(1, -1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, -1, -1), + QT3DSVec3(0, 0, -1) }, + { // X- + QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, -1, 1), + QT3DSVec3(-1, 0, 0) }, + { // Y+ + QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, 1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, 1, 1), QT3DSVec3(0, 1, 0) }, + { // Y- + QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, -1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(1, -1, -1), QT3DSVec3(0, -1, 0) } +}; + +static const QT3DSVec3 g_BoxUVs[] = { + QT3DSVec3(0, 1, 0), QT3DSVec3(0, 0, 0), QT3DSVec3(1, 0, 0), QT3DSVec3(1, 1, 0), +}; + +void NVRenderExampleTools::createBox(NVRenderContext &context, + NVRenderVertexBuffer *&outVertexBuffer, + NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory) +{ + const QT3DSU32 numVerts = 24; + const QT3DSU32 numIndices = 36; + QT3DSVec3 extents = QT3DSVec3(1, 1, 1); + + NVRenderVertexBufferEntry entries[] = { + NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0), + NVRenderVertexBufferEntry("attr_norm", NVRenderComponentTypes::QT3DSF32, 3, 3 * sizeof(QT3DSF32)), + NVRenderVertexBufferEntry("attr_uv", NVRenderComponentTypes::QT3DSF32, 2, 6 * sizeof(QT3DSF32)), + }; + + QT3DSU32 bufStride = 8 * sizeof(QT3DSF32); + QT3DSU32 bufSize = bufStride * numVerts; + outVertexBuffer = context.CreateVertexBuffer( + NVRenderBufferUsageType::Static, NVConstDataRef<NVRenderVertexBufferEntry>(entries, 3), 0, + releaseMemory ? 0 : bufSize); + QT3DS_ASSERT(bufStride == outVertexBuffer->GetStride()); + NVDataRef<QT3DSU8> vertData; + if (releaseMemory) + vertData = NVDataRef<QT3DSU8>( + (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "VertexBufferData"), + bufSize); + else + vertData = outVertexBuffer->LockBuffer(bufSize); + QT3DSU8 *positions = (QT3DSU8 *)vertData.begin(); + QT3DSU8 *normals = positions + 3 * sizeof(QT3DSF32); + QT3DSU8 *uvs = normals + 3 * sizeof(QT3DSF32); + + for (QT3DSU32 i = 0; i < 6; i++) { + const BoxFace &bf = g_BoxFaces[i]; + for (QT3DSU32 j = 0; j < 4; j++) { + QT3DSVec3 &p = *(QT3DSVec3 *)positions; + positions = ((QT3DSU8 *)positions) + bufStride; + QT3DSVec3 &n = *(QT3DSVec3 *)normals; + normals = ((QT3DSU8 *)normals) + bufStride; + QT3DSF32 *uv = (QT3DSF32 *)uvs; + uvs = ((QT3DSU8 *)uvs) + bufStride; + n = bf.normal; + p = bf.positions[j].multiply(extents); + uv[0] = g_BoxUVs[j].x; + uv[1] = g_BoxUVs[j].y; + } + } + + if (releaseMemory) { + outVertexBuffer->SetBuffer(vertData, false); + context.GetFoundation().getAllocator().deallocate(vertData.begin()); + } else + outVertexBuffer->UnlockBuffer(); + + bufSize = numIndices * sizeof(QT3DSU16); + outIndexBuffer = + context.CreateIndexBuffer(NVRenderBufferUsageType::Static, NVRenderComponentTypes::QT3DSU16, + releaseMemory ? 0 : bufSize); + NVDataRef<QT3DSU8> indexData; + if (releaseMemory) + indexData = NVDataRef<QT3DSU8>( + (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "IndexData"), + bufSize); + else + indexData = outIndexBuffer->LockBuffer(bufSize); + QT3DSU16 *indices = reinterpret_cast<QT3DSU16 *>(indexData.begin()); + for (QT3DSU8 i = 0; i < 6; i++) { + const QT3DSU16 base = i * 4; + *(indices++) = base + 0; + *(indices++) = base + 1; + *(indices++) = base + 2; + *(indices++) = base + 0; + *(indices++) = base + 2; + *(indices++) = base + 3; + } + if (releaseMemory) { + outIndexBuffer->SetBuffer(indexData, false); + context.GetFoundation().getAllocator().deallocate(indexData.begin()); + } else + outIndexBuffer->UnlockBuffer(); +} + +namespace { + +inline NVConstDataRef<QT3DSI8> toRef(const char *data) +{ + size_t len = strlen(data) + 1; + return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, len); +} + +static void dumpShaderOutput(NVRenderContext &ctx, + const NVRenderVertFragCompilationResult &compResult) +{ + if (!isTrivial(compResult.mFragCompilationOutput)) { + ctx.GetFoundation().error(QT3DS_WARN, "Frag output:\n%s", compResult.mFragCompilationOutput); + } + if (!isTrivial(compResult.mVertCompilationOutput)) { + ctx.GetFoundation().error(QT3DS_WARN, "Vert output:\n%s", compResult.mVertCompilationOutput); + } + if (!isTrivial(compResult.mLinkOutput)) { + ctx.GetFoundation().error(QT3DS_WARN, "Link output:\n%s", compResult.mLinkOutput); + } +} + +NVRenderVertFragShader *compileAndDump(NVRenderContext &ctx, const char *name, + const char *vertShader, const char *fragShader) +{ + NVRenderVertFragCompilationResult compResult = + ctx.CompileSource(name, toRef(vertShader), toRef(fragShader)); + dumpShaderOutput(ctx, compResult); + return compResult.mShader; +} +} + +NVRenderVertFragShader *NVRenderExampleTools::createSimpleShader(NVRenderContext &ctx) +{ + return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShader()); +} + +NVRenderVertFragShader *NVRenderExampleTools::createSimpleShaderTex(NVRenderContext &ctx) +{ + return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShaderTex()); +}
\ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h new file mode 100644 index 00000000..5b402868 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_EXAMPLE_TOOLS_H +#define QT3DS_RENDER_EXAMPLE_TOOLS_H +#include "Qt3DSRenderExample.h" + +namespace qt3ds { +namespace render { + + class NVRenderExampleTools + { + public: + static const char *getSimpleVertShader() + { + return "uniform mat4 mat_mvp;\n" + "attribute vec3 attr_pos; // Vertex pos\n" + "attribute vec3 attr_norm; // Vertex pos\n" + "attribute vec2 attr_uv; // UV coords\n" + "varying vec4 color_to_add;\n" + "varying vec2 uv_coords;\n" + "void main()\n" + "{\n" + "gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n" + "color_to_add.xyz = attr_norm * attr_norm;\n" + "color_to_add.a = 1.0;\n" + "uv_coords = attr_uv;\n" + "}\n"; + } + + static const char *getSimpleFragShader() + { + return "precision mediump sampler2D;\n" + "precision mediump float;\n" + "varying vec4 color_to_add;\n" + "void main()\n" + "{\n" + "gl_FragColor=color_to_add;\n" + "}\n"; + } + + static const char *getSimpleFragShaderTex() + { + return "precision mediump sampler2D;\n" + "precision mediump float;\n" + "uniform sampler2D image0;\n" + "varying vec2 uv_coords;\n" + "void main()\n" + "{\n" + "gl_FragColor=vec4(texture2D( image0, uv_coords ).xyz, 1.0 );\n" + "}\n"; + } + + static void createBox(NVRenderContext &context, NVRenderVertexBuffer *&outVertexBuffer, + NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory = true); + static NVRenderVertFragShader *createSimpleShader(NVRenderContext &context); + static NVRenderVertFragShader *createSimpleShaderTex(NVRenderContext &context); + }; +} +} + +#endif
\ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp new file mode 100644 index 00000000..e2cb4149 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "Qt3DSRenderExampleTools.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "foundation/Qt3DSVec4.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +namespace { +struct ShaderArgs +{ + float mvp[16]; + NVRenderTexture2DPtr texture; + NVRenderVertFragShaderPtr shader; + ShaderArgs() {} +}; +class RenderToTexture : public NVRenderExample +{ + NVRenderContext &m_Context; + NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer; + NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer; + // Simple shader + NVScopedRefCounted<NVRenderVertFragShader> mSimpleShader; + // Simple shader with texture lookup. + NVScopedRefCounted<NVRenderVertFragShader> mSimpleShaderTex; + + NVScopedRefCounted<NVRenderFrameBuffer> mFrameBuffer; + NVScopedRefCounted<NVRenderTexture2D> mColorBuffer; + NVScopedRefCounted<NVRenderTexture2D> mDepthBuffer; + + NVRenderHandle mGroupId; + QT3DSU32 mFBWidth; + QT3DSU32 mFBHeight; + + ShaderArgs mShaderArgs; + float frus[16]; + float model[16]; + float rot[9]; + +public: + RenderToTexture(NVRenderContext &context) + : m_Context(context) + , mFBWidth(400) + , mFBHeight(400) + { + NVRenderExampleTools::createBox(m_Context, mVertexBuffer.mPtr, mIndexBuffer.mPtr); + mVertexBuffer->addRef(); + mIndexBuffer->addRef(); + mSimpleShader = NVRenderExampleTools::createSimpleShader(m_Context); + mSimpleShaderTex = NVRenderExampleTools::createSimpleShaderTex(m_Context); + // If you don't want the depth buffer information back out of the system, then you can + // do this. + // mDepthBuffer = m_Context.CreateRenderBuffer( NVRenderRenderBufferFormats::Depth16, + // mFBWidth, mFBHeight ); + + mDepthBuffer = m_Context.CreateTexture2D(); + mDepthBuffer->SetTextureData(NVDataRef<QT3DSU8>(), 0, mFBWidth, mFBHeight, + NVRenderTextureFormats::Depth16); + mColorBuffer = m_Context.CreateTexture2D(); + mColorBuffer->SetTextureData(NVDataRef<QT3DSU8>(), 0, mFBWidth, mFBHeight, + NVRenderTextureFormats::RGBA8); + if (mDepthBuffer.mPtr && mColorBuffer.mPtr) { + // Creating objects tends to Bind them to their active state hooks. + // So to protect the rest of the system against what they are doing (if we care), we + // need + // to push the current state + // Auto-binds the framebuffer. + mFrameBuffer = m_Context.CreateFrameBuffer(); + mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *mColorBuffer.mPtr); + mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Depth, *mDepthBuffer.mPtr); + QT3DS_ASSERT(mFrameBuffer->IsComplete()); + + m_Context.SetRenderTarget(NULL); + } + mColorBuffer->SetMinFilter(NVRenderTextureMinifyingOp::Linear); + mColorBuffer->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); + m_Context.SetVertexBuffer(mVertexBuffer); + m_Context.SetIndexBuffer(mIndexBuffer); + m_Context.SetDepthTestEnabled(true); + m_Context.SetDepthWriteEnabled(true); + m_Context.SetClearColor(QT3DSVec4(.3f)); + // Setup various matrici + NvGl2DemoMatrixIdentity(model); + NvGl2DemoMatrixIdentity(frus); + NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10); + NvGl2DemoMatrixTranslate(model, 0, 0, -4); + mShaderArgs.texture = mColorBuffer.mPtr; + } + void setupMVP(QT3DSVec3 translation) + { + float *mvp(mShaderArgs.mvp); + memCopy(mvp, frus, 16 * sizeof(float)); + NvGl2DemoMatrixMultiply(mvp, model); + NvGl2DemoMatrixTranslate(mvp, translation.x, translation.y, translation.z); + NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot); + } + void DrawIndexedArrays(QT3DSVec3 translation) + { + setupMVP(translation); + m_Context.SetActiveShader(mShaderArgs.shader); + mShaderArgs.shader->Bind(); + mShaderArgs.shader->SetPropertyValue("mat_mvp", + *reinterpret_cast<QT3DSMat44 *>(mShaderArgs.mvp)); + mShaderArgs.shader->SetPropertyValue("image0", mShaderArgs.texture); + m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0); + } + + virtual void drawFrame(double currentSeconds) + { + NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0); + NVRenderClearFlags clearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth); + // render to frame buffer + { + NVRenderContextScopedProperty<NVRenderFrameBufferPtr> __framebuffer( + m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget, + mFrameBuffer); + NVRenderContextScopedProperty<NVRenderRect> __viewport( + m_Context, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, + NVRenderRect(0, 0, mFBWidth, mFBHeight)); + NVRenderContextScopedProperty<QT3DSVec4> __clearColor( + m_Context, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, + QT3DSVec4(.6f)); + m_Context.Clear(clearFlags); + mShaderArgs.shader = mSimpleShader; + DrawIndexedArrays(QT3DSVec3(0.f)); + } + m_Context.Clear(clearFlags); + mShaderArgs.texture = mColorBuffer; + mShaderArgs.shader = mSimpleShaderTex; + + DrawIndexedArrays(QT3DSVec3(-2.f, 0.f, 0.f)); + + mShaderArgs.texture = mDepthBuffer; + DrawIndexedArrays(QT3DSVec3(2.f, 0.f, 0.f)); + } + virtual QT3DSU32 getRuntimeInSeconds() + { + return mSimpleShader.mPtr && mSimpleShaderTex.mPtr ? 5 : 0; + } + virtual void release() { NVDelete(m_Context.GetFoundation(), this); } +}; +} + +QT3DS_RENDER_REGISTER_EXAMPLE(RenderToTexture);
\ No newline at end of file diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp new file mode 100644 index 00000000..807f0821 --- /dev/null +++ b/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "Qt3DSRenderExample.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/NVRenderVertFragShader.h" +#include "render_util/NVRenderUtils.h" +#include "Qt3DSRenderExampleTools.h" +#include "foundation/Qt3DSMat44.h" + +using namespace qt3ds; +using namespace qt3ds::render; + +#pragma warning(disable : 4189) +#pragma warning(disable : 4100) + +namespace { + +struct ShaderArguments +{ + QT3DSMat44 mMatrix; +}; + +class SpinningCube : public NVRenderExample +{ + NVRenderContext &m_Context; + NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer; + NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer; + NVScopedRefCounted<NVRenderVertFragShader> mShader; + NVRenderHandle mShaderArgGroupId; + float frus[16]; + float model[16]; + float rot[9]; + +public: + SpinningCube(NVRenderContext &ctx) + : m_Context(ctx) + { + NVRenderExampleTools::createBox(ctx, mVertexBuffer.mPtr, mIndexBuffer.mPtr, false); + mVertexBuffer->addRef(); + mIndexBuffer->addRef(); + mShader = NVRenderExampleTools::createSimpleShader(ctx); + ctx.SetViewport(NVRenderRect(0, 0, 400, 400)); + // These properties will get applied just before render no matter what + // so we can just use the default settings here. + ctx.SetVertexBuffer(mVertexBuffer); + ctx.SetIndexBuffer(mIndexBuffer); + if (mShader) { + ctx.SetActiveShader(mShader); + } + ctx.SetDepthTestEnabled(true); + ctx.SetDepthWriteEnabled(true); + NvGl2DemoMatrixIdentity(model); + NvGl2DemoMatrixIdentity(frus); + NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10); + NvGl2DemoMatrixTranslate(model, 0, 0, -4); + } + virtual void drawFrame(double currentSeconds) + { + NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0); + float mvp[16]; + NvGl2DemoMatrixIdentity(mvp); + NvGl2DemoMatrixMultiply(mvp, frus); + NvGl2DemoMatrixMultiply(mvp, model); + NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot); + + NVConstDataRef<QT3DSU8> instance((QT3DSU8 *)mvp, 16 * sizeof(float)); + m_Context.Clear( + NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth)); + mShader->SetPropertyValue("mat_mvp", *reinterpret_cast<QT3DSMat44 *>(mvp)); + m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0); + } + virtual QT3DSU32 getRuntimeInSeconds() { return mShader.mPtr ? 5 : 0; } + virtual void release() { NVDelete(m_Context.GetFoundation(), this); } +}; +} +QT3DS_RENDER_REGISTER_EXAMPLE(SpinningCube);
\ No newline at end of file diff --git a/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp new file mode 100644 index 00000000..272c3e8c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderAtomicCounterBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + ///< struct handling a constant buffer entry + class AtomicCounterBufferEntry + { + public: + CRegisteredString m_Name; ///< parameter Name + QT3DSI32 m_Offset; ///< offset into the memory buffer + + AtomicCounterBufferEntry(CRegisteredString name, QT3DSI32 offset) + : m_Name(name) + , m_Offset(offset) + { + } + }; + + NVRenderAtomicCounterBuffer::NVRenderAtomicCounterBuffer( + NVRenderContextImpl &context, CRegisteredString bufferName, size_t size, + NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Storage, usageType, data) + , m_Name(bufferName) + , m_AtomicCounterBufferEntryMap( + m_Foundation.getAllocator(), + "NVRenderAtomicCounterBuffer::m_AtomicCounterBufferEntryMap") + , m_Dirty(true) + { + QT3DS_ASSERT(context.IsStorageBufferSupported()); + } + + NVRenderAtomicCounterBuffer::~NVRenderAtomicCounterBuffer() + { + for (TRenderAtomiCounterBufferEntryMap::iterator + iter = m_AtomicCounterBufferEntryMap.begin(), + end = m_AtomicCounterBufferEntryMap.end(); + iter != end; ++iter) { + NVDelete(m_Foundation.getAllocator(), iter->second); + } + + m_AtomicCounterBufferEntryMap.clear(); + + m_Context.BufferDestroyed(*this); + } + + void NVRenderAtomicCounterBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderAtomicCounterBuffer::BindToShaderProgram(QT3DSU32 index) + { + m_Backend->ProgramSetAtomicCounterBuffer(index, m_BufferHandle); + } + + void NVRenderAtomicCounterBuffer::Update() + { + // we only update the buffer if it is dirty and we actually have some data + if (m_Dirty && m_BufferData.size()) { + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, + m_BufferData.begin()); + m_Dirty = false; + } + } + + void NVRenderAtomicCounterBuffer::UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data) + { + // we only update the buffer if we something + if (data.size()) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, + data.begin() + offset); + } + + void NVRenderAtomicCounterBuffer::AddParam(CRegisteredString name, QT3DSU32 offset) + { + if (m_AtomicCounterBufferEntryMap.find(name) == m_AtomicCounterBufferEntryMap.end()) { + AtomicCounterBufferEntry *newEntry = + QT3DS_NEW(m_Foundation.getAllocator(), AtomicCounterBufferEntry)(name, offset); + + if (newEntry) + m_AtomicCounterBufferEntryMap.insert(eastl::make_pair(name, newEntry)); + } else { + // no duplicated entries + return; + } + } + + bool NVRenderAtomicCounterBuffer::ContainsParam(CRegisteredString name) + { + if (m_AtomicCounterBufferEntryMap.find(name) != m_AtomicCounterBufferEntryMap.end()) + return true; + else + return false; + } + + NVRenderAtomicCounterBuffer * + NVRenderAtomicCounterBuffer::Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderAtomicCounterBuffer *retval = NULL; + + if (context.IsAtomicCounterBufferSupported()) { + CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); + QT3DSU32 bufSize = sizeof(NVRenderAtomicCounterBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "AtomicCounterBuffer"); + retval = new (newMem) NVRenderAtomicCounterBuffer( + context, theBufferName, size, usageType, + toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size())); + } else { + QT3DS_ASSERT(false); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h new file mode 100644 index 00000000..5ff449ea --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + class AtomicCounterBufferEntry; + + typedef nvhash_map<CRegisteredString, AtomicCounterBufferEntry *> + TRenderAtomiCounterBufferEntryMap; + + ///< Constant (uniform) buffer representation + class QT3DS_AUTOTEST_EXPORT NVRenderAtomicCounterBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] bufferName Name of the buffer. Must match the name used in programs + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, + size_t size, NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data); + + ///< destructor + virtual ~NVRenderAtomicCounterBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief bind the buffer to a shader program + * + * @param[in] index Index of the constant buffer within the program + * + * @return no return. + */ + virtual void BindToShaderProgram(QT3DSU32 index); + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief update a piece of memory directly within the storage buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 (430) layout which guarantees a specific layout behavior across + *all HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into storage buffer + * @param[in] data pointer to data + * + * @return no return + */ + void UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data); + + /** + * @brief add a parameter to the atomic counter buffer + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] offset Offset in bytes into the buffer + * + * @return no return + */ + void AddParam(CRegisteredString name, QT3DSU32 offset); + + /** + * @brief Check if the buffer contains this param + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * + * @return no return + */ + bool ContainsParam(CRegisteredString name); + + /** + * @brief get the buffer name + * + * @return the buffer name + */ + CRegisteredString GetBufferName() const { return m_Name; } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_BufferHandle); + } + + /** + * @brief create a NVRenderAtomicCounterBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the buffer object or NULL + */ + static NVRenderAtomicCounterBuffer *Create(NVRenderContextImpl &context, + const char *bufferName, + NVRenderBufferUsageType::Enum usageType, + size_t size, NVConstDataRef<QT3DSU8> bufferData); + + private: + CRegisteredString m_Name; ///< buffer name + TRenderAtomiCounterBufferEntryMap + m_AtomicCounterBufferEntryMap; ///< holds the entries of a atomic counter buffer + bool m_Dirty; ///< true if buffer is dirty + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp new file mode 100644 index 00000000..42641a04 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderAttribLayout.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + ///< constructor + NVRenderAttribLayout::NVRenderAttribLayout(NVRenderContextImpl &context, + NVConstDataRef<NVRenderVertexBufferEntry> attribs) + : m_Context(context) + , m_Foundation(context.GetFoundation()) + , mRefCount(0) + , m_Backend(context.GetBackend()) + { + m_AttribLayoutHandle = m_Backend->CreateAttribLayout(attribs); + QT3DS_ASSERT(m_AttribLayoutHandle); + } + + ///< destructor + NVRenderAttribLayout::~NVRenderAttribLayout() + { + if (m_AttribLayoutHandle) { + m_Backend->ReleaseAttribLayout(m_AttribLayoutHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h new file mode 100644 index 00000000..da801c8e --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_ATTRIB_LAYOUT_H +#define QT3DS_RENDER_ATTRIB_LAYOUT_H + +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + // forward declarations + class NVRenderContextImpl; + class NVRenderBackend; + + ///< this class handles the vertex attribute layout setup + class NVRenderAttribLayout : public NVRefCounted + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] attribs Pointer to attribute list + * + * @return No return. + */ + NVRenderAttribLayout(NVRenderContextImpl &context, + NVConstDataRef<NVRenderVertexBufferEntry> attribs); + ///< destructor + ~NVRenderAttribLayout(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendAttribLayoutObject GetAttribLayoutHandle() const + { + return m_AttribLayoutHandle; + } + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + + NVRenderBackend::NVRenderBackendAttribLayoutObject + m_AttribLayoutHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h b/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h new file mode 100644 index 00000000..c988b2f1 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h @@ -0,0 +1,2100 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TYPES_H +#define QT3DS_RENDER_QT3DS_RENDER_TYPES_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSFlags.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/Qt3DSMath.h" +#include "foundation/Qt3DSVec2.h" + +namespace qt3ds { + +namespace render { +using namespace foundation; + +#define QT3DS_RENDER_ITERATE_COMPONENT_TYPES \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU8) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI8) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU16) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI16) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU32) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI32) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU64) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI64) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF16) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF32) \ + QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF64) + +struct NVRenderComponentTypes +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) x, + QT3DS_RENDER_ITERATE_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_COMPONENT_TYPES + #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + default: + break; + } + return "Unknown"; + } + + static qt3ds::QT3DSU32 getSizeofType(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ + case x: \ + return sizeof(qt3ds::x); + QT3DS_RENDER_ITERATE_COMPONENT_TYPES + #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } +}; + +/** + Define a set of compile-time trait classes that map the enumerations + to actual compile time types and sizeof so we can deal with the enumeration + in generic ways. + */ +template <NVRenderComponentTypes::Enum TraitType> +struct NVRenderComponentTraits +{ + bool force_compile_error; +}; + +/** + Define a compile time mapping from datatype to enumeration. Not that if you + use this with a type that isn't a component type you will get a compilation + error. + */ +template <typename TDataType> +struct NVRenderComponentTypeToTypeMap +{ + bool force_compile_error; +}; + +#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \ + template <> \ + struct NVRenderComponentTraits<NVRenderComponentTypes::x> \ +{ \ + typedef x TComponentType; \ + QT3DSU8 mComponentSize; \ + NVRenderComponentTraits<NVRenderComponentTypes::x>() \ + : mComponentSize(sizeof(x)) \ +{ \ +} \ +}; \ + template <> \ + struct NVRenderComponentTypeToTypeMap<x> \ +{ \ + NVRenderComponentTypes::Enum m_ComponentType; \ + NVRenderComponentTypeToTypeMap<x>() \ + : m_ComponentType(NVRenderComponentTypes::x) \ +{ \ +} \ +}; + +QT3DS_RENDER_ITERATE_COMPONENT_TYPES; + +#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE + +// Map at compile time from component type to datatype; +template <typename TDataType> +inline NVRenderComponentTypes::Enum getComponentTypeForType() +{ + return NVRenderComponentTypeToTypeMap<TDataType>().m_ComponentType; +} + +struct NVRenderContextValues +{ + enum Enum { + GLES2 = 1 << 0, + GL2 = 1 << 1, + GLES3 = 1 << 2, + GL3 = 1 << 3, + GLES3PLUS = 1 << 4, + GL4 = 1 << 5, + NullContext = 1 << 6, + }; +}; + +typedef NVFlags<NVRenderContextValues::Enum, QT3DSU32> NVRenderContextType; + +struct NVRenderClearValues +{ + enum Enum { + Color = 1 << 0, + Depth = 1 << 1, + Stencil = 1 << 3, + Coverage = 1 << 4, + }; +}; + +typedef NVFlags<NVRenderClearValues::Enum, QT3DSU32> NVRenderClearFlags; + +struct NVRenderQueryType +{ + enum Enum { + Unknown = 0, + Samples, ///< samples query object + Timer, ///< timer query object + }; +}; + +struct NVRenderQueryResultType +{ + enum Enum { + Unknown = 0, + ResultAvailable, ///< Check if query result is available + Result, ///< Get actual result + }; +}; + +struct NVRenderSyncType +{ + enum Enum { + Unknown = 0, + GpuCommandsComplete, ///< sync to Gpu commands finished + }; +}; + +struct NVRenderSyncValues +{ + enum Enum { + Unknown = 0, ///< for future usage + }; +}; + +typedef NVFlags<NVRenderSyncValues::Enum, QT3DSU32> NVRenderSyncFlags; + +struct NVRenderCommandFlushValues +{ + enum Enum { + SyncFlushCommands = 0, ///< sync for flushing command + }; +}; + +typedef NVFlags<NVRenderCommandFlushValues::Enum, QT3DSU32> NVRenderCommandFlushFlags; + +struct NVRenderBufferBindValues +{ + enum Enum { + Unknown = 0, + Vertex = 1 << 0, ///< Bind as vertex buffer + Index = 1 << 1, ///< Bind as index buffer + Constant = 1 << 2, ///< Bind as constant buffer + Storage = 1 << 3, ///< Bind as shader storage buffer + Atomic_Counter = 1 << 4, ///< Bind as atomic counter buffer + Draw_Indirect = 1 << 5, ///< Bind as draw indirect buffer + }; +}; + +typedef NVFlags<NVRenderBufferBindValues::Enum, QT3DSU32> NVRenderBufferBindFlags; + +struct NVRenderBufferUsageType +{ + enum Enum { + Unknown = 0, + Static, ///< Rarely updated + Dynamic, ///< Most likely updated every frame + }; +}; + +struct NVRenderImageAccessType +{ + enum Enum { + Unknown = 0, + Read, ///< Read only access + Write, ///< Write only access + ReadWrite, ///< Read and write access + }; +}; + +struct NVRenderBufferAccessTypeValues +{ + enum Enum { + Unknown = 0, + Read = 1 << 0, ///< Read access + Write = 1 << 1, ///< Write access + Invalid = 1 << 2, ///< No sync + InvalidRange = 1 << 3, ///< No sync + + }; +}; + +typedef NVFlags<NVRenderBufferAccessTypeValues::Enum, QT3DSU32> NVRenderBufferAccessFlags; + +///< defines a barrier of ordering the memory transactions to a command relative to those issued +///before the barrier +struct NVRenderBufferBarrierValues +{ + enum Enum { + Unknown = 0, + VertexAttribArray = 1 << 0, ///< Barrier for vertex attributes sourced from a buffer + ElementArray = 1 << 1, ///< Barrier for indices sourced from a buffer + UniformBuffer = 1 << 2, ///< Barrier for shader uniforms sourced from a buffer + TextureFetch = 1 << 3, ///< Barrier for texture fetches within shaders + ShaderImageAccess = 1 << 4, ///< Barrier for image access using load / store + CommandBuffer = 1 << 5, ///< Barrier for indirect drawing + PixelBuffer = 1 << 6, ///< Barrier for pixel buffer access + TextureUpdate = 1 << 7, ///< Barrier for texture writes + BufferUpdate = 1 << 8, ///< Barrier for buffer writes + Framebuffer = 1 << 9, ///< Barrier for framebuffer writes + TransformFeedback = 1 << 10, ///< Barrier for transform feedback writes + AtomicCounter = 1 << 11, ///< Barrier for atomic counter writes + ShaderStorage = 1 << 12, ///< Barrier for shader storage blocks writes + All = 0xFFFF, ///< Barrier for all of the above + }; +}; + +typedef NVFlags<NVRenderBufferBarrierValues::Enum, QT3DSU32> NVRenderBufferBarrierFlags; + +#define QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA4) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGB565) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA5551) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth16) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth24) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth32) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(StencilIndex8) \ + QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(CoverageNV) + +struct NVRenderRenderBufferFormats +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) x, + QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS +#undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS + #undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_TEXTURE_FORMATS \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32I) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32UI) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8A8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB565) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA5551) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Alpha8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance16) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(LuminanceAlpha8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R11G11B10) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB9E5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_DXT1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT3) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_PunchThrough_Alpha1_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_PunchThrough_Alpha1_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA8_ETC2_EAC) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ETC2_EAC) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNSIGNED_FLOAT) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_SIGNED_FLOAT) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_4x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x12) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_4x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x12) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth16) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth32) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24Stencil8) + +struct NVRenderTextureFormats +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) x, +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) x, +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) x, + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS +#undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT +#undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT +#undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + }; + + static bool isUncompressedTextureFormat(NVRenderTextureFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \ + case NVRenderTextureFormats::x: \ + return true; +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT + default: + break; + } + return false; + } + + static bool isCompressedTextureFormat(NVRenderTextureFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \ + case NVRenderTextureFormats::x: \ + return true; +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT + default: + break; + } + return false; + } + + static bool isDepthTextureFormat(NVRenderTextureFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \ + case NVRenderTextureFormats::x: \ + return true; + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT + default: + break; + } + return false; + } + + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_TEXTURE_FORMATS + #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT + #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT + default: + break; + } + return "Unknown"; + } + + static QT3DSU32 getSizeofFormat(Enum value) + { + switch (value) { + case R8: + return 1; + case R16F: + return 2; + case R16: + return 2; + case R32I: + return 4; + case R32F: + return 4; + case RGBA8: + return 4; + case RGB8: + return 3; + case RGB565: + return 2; + case RGBA5551: + return 2; + case Alpha8: + return 1; + case Luminance8: + return 1; + case LuminanceAlpha8: + return 1; + case Depth16: + return 2; + case Depth24: + return 3; + case Depth32: + return 4; + case Depth24Stencil8: + return 4; + case RGB9E5: + return 4; + case SRGB8: + return 3; + case SRGB8A8: + return 4; + case RGBA16F: + return 8; + case RG16F: + return 4; + case RG32F: + return 8; + case RGBA32F: + return 16; + case RGB32F: + return 12; + case R11G11B10: + return 4; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static QT3DSU32 getNumberOfComponent(Enum value) + { + switch (value) { + case R8: + return 1; + case R16F: + return 1; + case R16: + return 1; + case R32I: + return 1; + case R32F: + return 1; + case RGBA8: + return 4; + case RGB8: + return 3; + case RGB565: + return 3; + case RGBA5551: + return 4; + case Alpha8: + return 1; + case Luminance8: + return 1; + case LuminanceAlpha8: + return 2; + case Depth16: + return 1; + case Depth24: + return 1; + case Depth32: + return 1; + case Depth24Stencil8: + return 2; + case RGB9E5: + return 3; + case SRGB8: + return 3; + case SRGB8A8: + return 4; + case RGBA16F: + return 4; + case RG16F: + return 2; + case RG32F: + return 2; + case RGBA32F: + return 4; + case RGB32F: + return 3; + case R11G11B10: + return 3; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static void decodeToFloat(void *inPtr, QT3DSU32 byteOfs, float *outPtr, + NVRenderTextureFormats::Enum inFmt) + { + outPtr[0] = 0.0f; + outPtr[1] = 0.0f; + outPtr[2] = 0.0f; + outPtr[3] = 0.0f; + QT3DSU8 *src = reinterpret_cast<QT3DSU8 *>(inPtr); + // float divisor; // If we want to support RGBD? + switch (inFmt) { + case Alpha8: + outPtr[0] = ((float)src[byteOfs]) / 255.0f; + break; + + case Luminance8: + case LuminanceAlpha8: + case R8: + case RG8: + case RGB8: + case RGBA8: + case SRGB8: + case SRGB8A8: + // NOTE : RGBD Hack here for reference. Not meant for installation. + // divisor = (NVRenderTextureFormats::getSizeofFormat(inFmt) == 4) ? + // ((float)src[byteOfs+3]) / 255.0f : 1.0f; + for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) { + float val = ((float)src[byteOfs + i]) / 255.0f; + outPtr[i] = (i < 3) ? powf(val, 0.4545454545f) : val; + // Assuming RGBA8 actually means RGBD (which is stupid, I know) + // if ( NVRenderTextureFormats::getSizeofFormat(inFmt) == 4 ) { outPtr[i] /= + // divisor; } + } + // outPtr[3] = divisor; + break; + + case R32F: + outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0]; + break; + case RG32F: + outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0]; + outPtr[1] = reinterpret_cast<float *>(src + byteOfs)[1]; + break; + case RGBA32F: + outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0]; + outPtr[1] = reinterpret_cast<float *>(src + byteOfs)[1]; + outPtr[2] = reinterpret_cast<float *>(src + byteOfs)[2]; + outPtr[3] = reinterpret_cast<float *>(src + byteOfs)[3]; + break; + case RGB32F: + outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0]; + outPtr[1] = reinterpret_cast<float *>(src + byteOfs)[1]; + outPtr[2] = reinterpret_cast<float *>(src + byteOfs)[2]; + break; + + case R16F: + case RG16F: + case RGBA16F: + for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) { + // NOTE : This only works on the assumption that we don't have any denormals, + // Infs or NaNs. + // Every pixel in our source image should be "regular" + QT3DSU16 h = reinterpret_cast<QT3DSU16 *>(src + byteOfs)[i]; + QT3DSU32 sign = (h & 0x8000) << 16; + QT3DSU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23); + QT3DSU32 mantissa = ((h & 0x3ff) << 13); + QT3DSU32 result = sign | exponent | mantissa; + + if (h == 0 || h == 0x8000) { + result = 0; + } // Special case for zero and negative zero + qt3ds::intrinsics::memCopy(reinterpret_cast<QT3DSU32 *>(outPtr) + i, &result, 4); + } + break; + + case R11G11B10: + // place holder + QT3DS_ASSERT(false); + break; + + default: + outPtr[0] = 0.0f; + outPtr[1] = 0.0f; + outPtr[2] = 0.0f; + outPtr[3] = 0.0f; + break; + } + } + + static void encodeToPixel(float *inPtr, void *outPtr, QT3DSU32 byteOfs, + NVRenderTextureFormats::Enum inFmt) + { + QT3DSU8 *dest = reinterpret_cast<QT3DSU8 *>(outPtr); + switch (inFmt) { + case NVRenderTextureFormats::Alpha8: + dest[byteOfs] = QT3DSU8(inPtr[0] * 255.0f); + break; + + case Luminance8: + case LuminanceAlpha8: + case R8: + case RG8: + case RGB8: + case RGBA8: + case SRGB8: + case SRGB8A8: + for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) { + inPtr[i] = (inPtr[i] > 1.0f) ? 1.0f : inPtr[i]; + if (i < 3) + dest[byteOfs + i] = QT3DSU8(powf(inPtr[i], 2.2f) * 255.0f); + else + dest[byteOfs + i] = QT3DSU8(inPtr[i] * 255.0f); + } + break; + + case R32F: + reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0]; + break; + case RG32F: + reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0]; + reinterpret_cast<float *>(dest + byteOfs)[1] = inPtr[1]; + break; + case RGBA32F: + reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0]; + reinterpret_cast<float *>(dest + byteOfs)[1] = inPtr[1]; + reinterpret_cast<float *>(dest + byteOfs)[2] = inPtr[2]; + reinterpret_cast<float *>(dest + byteOfs)[3] = inPtr[3]; + break; + case RGB32F: + reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0]; + reinterpret_cast<float *>(dest + byteOfs)[1] = inPtr[1]; + reinterpret_cast<float *>(dest + byteOfs)[2] = inPtr[2]; + break; + + case R16F: + case RG16F: + case RGBA16F: + for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) { + // NOTE : This also has the limitation of not handling infs, NaNs and + // denormals, but it should be + // sufficient for our purposes. + if (inPtr[i] > 65519.0f) { + inPtr[i] = 65519.0f; + } + if (fabs(inPtr[i]) < 6.10352E-5f) { + inPtr[i] = 0.0f; + } + QT3DSU32 f = reinterpret_cast<QT3DSU32 *>(inPtr)[i]; + QT3DSU32 sign = (f & 0x80000000) >> 16; + QT3DSI32 exponent = (f & 0x7f800000) >> 23; + QT3DSU32 mantissa = (f >> 13) & 0x3ff; + exponent = exponent - 112; + if (exponent > 31) { + exponent = 31; + } + if (exponent < 0) { + exponent = 0; + } + exponent = exponent << 10; + reinterpret_cast<QT3DSU16 *>(dest + byteOfs)[i] = + QT3DSU16(sign | exponent | mantissa); + } + break; + + case R11G11B10: + // place holder + QT3DS_ASSERT(false); + break; + + default: + dest[byteOfs] = 0; + dest[byteOfs + 1] = 0; + dest[byteOfs + 2] = 0; + dest[byteOfs + 3] = 0; + break; + } + } +}; + +struct NVRenderTextureTargetType +{ + enum Enum { + Unknown = 0, + Texture2D, + Texture2D_MS, + Texture2D_Array, + TextureCube, + TextureCubePosX, + TextureCubeNegX, + TextureCubePosY, + TextureCubeNegY, + TextureCubePosZ, + TextureCubeNegZ, + }; +}; + +struct NVRenderTextureUnit +{ + enum Enum { + TextureUnit_0 = 0, + TextureUnit_1, + TextureUnit_2, + TextureUnit_3, + TextureUnit_4, + TextureUnit_5, + TextureUnit_6, + TextureUnit_7, + TextureUnit_8, + TextureUnit_9, + TextureUnit_10, + TextureUnit_11, + TextureUnit_12, + TextureUnit_13, + TextureUnit_14, + TextureUnit_15, + TextureUnit_16, + TextureUnit_17, + TextureUnit_18, + TextureUnit_19, + TextureUnit_20, + TextureUnit_21, + TextureUnit_22, + TextureUnit_23, + TextureUnit_24, + TextureUnit_25, + TextureUnit_26, + TextureUnit_27, + TextureUnit_28, + TextureUnit_29, + TextureUnit_30, + TextureUnit_31 + }; +}; + +struct NVRenderTextureCompareMode +{ + enum Enum { Unknown = 0, NoCompare, CompareToRef }; +}; + +struct NVRenderTextureSwizzleMode +{ + enum Enum { NoSwizzle = 0, L8toR8, A8toR8, L8A8toRG8, L16toR16 }; +}; + +#define QT3DS_RENDER_ITERATE_BOOL_OP \ + QT3DS_RENDER_HANDLE_BOOL_OP(Never) \ + QT3DS_RENDER_HANDLE_BOOL_OP(Less) \ + QT3DS_RENDER_HANDLE_BOOL_OP(LessThanOrEqual) \ + QT3DS_RENDER_HANDLE_BOOL_OP(Equal) \ + QT3DS_RENDER_HANDLE_BOOL_OP(NotEqual) \ + QT3DS_RENDER_HANDLE_BOOL_OP(Greater) \ + QT3DS_RENDER_HANDLE_BOOL_OP(GreaterThanOrEqual) \ + QT3DS_RENDER_HANDLE_BOOL_OP(AlwaysTrue) + +struct NVRenderTextureCompareOp +{ + enum Enum { +#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x, + QT3DS_RENDER_ITERATE_BOOL_OP +#undef QT3DS_RENDER_HANDLE_BOOL_OP + }; +}; + +#define QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP \ + QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Nearest) \ + QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Linear) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapNearest) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapNearest) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapLinear) \ + QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapLinear) + +struct NVRenderTextureMinifyingOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x, +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) x, + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + }; + const char *toString(NVRenderTextureMinifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderTextureMagnifyingOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x, +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + }; + const char *toString(NVRenderTextureMinifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) + QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP \ + QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(ClampToEdge) \ + QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(MirroredRepeat) \ + QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(Repeat) + +struct NVRenderTextureCoordOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) x, + QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP + }; + const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP + #undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_HINT \ + QT3DS_RENDER_HANDLE_HINT(Fastest) \ + QT3DS_RENDER_HANDLE_HINT(Nicest) \ + QT3DS_RENDER_HANDLE_HINT(Unspecified) + +struct NVRenderHint +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_HINT(x) x, + QT3DS_RENDER_ITERATE_HINT +#undef QT3DS_RENDER_HANDLE_HINT + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_HINT(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_HINT + #undef QT3DS_RENDER_HANDLE_HINT + default: + break; + } + return "Unknown"; + } +}; + +class NVRenderImplemented +{ +protected: + virtual ~NVRenderImplemented() {} +public: + // Get the handle that binds us to the implementation. + // For instance, return the GLuint that came back from + // glGenTextures. + virtual const void *GetImplementationHandle() const = 0; +}; + +struct NVRenderVertexBufferEntry +{ + const char *m_Name; + /** Datatype of the this entry points to in the buffer */ + NVRenderComponentTypes::Enum m_ComponentType; + /** Number of components of each data member. 1,2,3, or 4. Don't be stupid.*/ + QT3DSU32 m_NumComponents; + /** Offset from the beginning of the buffer of the first item */ + QT3DSU32 m_FirstItemOffset; + /** Attribute input slot used for this entry*/ + QT3DSU32 m_InputSlot; + + NVRenderVertexBufferEntry(const char *nm, NVRenderComponentTypes::Enum type, + QT3DSU32 numComponents, QT3DSU32 firstItemOffset = 0, + QT3DSU32 inputSlot = 0) + : m_Name(nm) + , m_ComponentType(type) + , m_NumComponents(numComponents) + , m_FirstItemOffset(firstItemOffset) + , m_InputSlot(inputSlot) + { + } + + NVRenderVertexBufferEntry() + : m_Name(NULL) + , m_ComponentType(NVRenderComponentTypes::Unknown) + , m_NumComponents(0) + , m_FirstItemOffset(0) + , m_InputSlot(0) + { + } + + NVRenderVertexBufferEntry(const NVRenderVertexBufferEntry &inOther) + : m_Name(inOther.m_Name) + , m_ComponentType(inOther.m_ComponentType) + , m_NumComponents(inOther.m_NumComponents) + , m_FirstItemOffset(inOther.m_FirstItemOffset) + , m_InputSlot(inOther.m_InputSlot) + { + } + + NVRenderVertexBufferEntry &operator=(const NVRenderVertexBufferEntry &inOther) + { + if (this != &inOther) { + m_Name = inOther.m_Name; + m_ComponentType = inOther.m_ComponentType; + m_NumComponents = inOther.m_NumComponents; + m_FirstItemOffset = inOther.m_FirstItemOffset; + m_InputSlot = inOther.m_InputSlot; + } + return *this; + } +}; + +class NVRenderShaderProgram; + +typedef NVConstDataRef<QT3DSI8> TConstI8Ref; + +struct NVRenderVertFragCompilationResult +{ + const char *mShaderName; + + NVRenderShaderProgram *mShader; ///< contains the program + + NVRenderVertFragCompilationResult() + : mShaderName("") + , mShader(NULL) + { + } +}; + +#define QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color0) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color1) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color2) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color3) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color4) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color5) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color6) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color7) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Depth) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Stencil) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(DepthStencil) \ + QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(CoverageNV) + +struct NVRenderFrameBufferAttachments +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(x) x, + QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT + LastAttachment, + }; +}; + +struct NVRenderDrawMode +{ + enum Enum { + Unknown = 0, + Points, + LineStrip, + LineLoop, + Lines, + TriangleStrip, + TriangleFan, + Triangles, + Patches, + }; +}; + +struct NVRenderTextureCubeFaces +{ + enum Enum { + InvalidFace = 0, + CubePosX = 1, + CubeNegX, + CubePosY, + CubeNegY, + CubePosZ, + CubeNegZ, + }; +}; + +// enums match the NV path extensions +struct NVRenderPathCommands +{ + enum Enum { + Close = 0, + MoveTo = 2, + CubicCurveTo = 12, + }; +}; + +struct NVRenderPathFontTarget +{ + enum Enum { + StandardFont = 0, + SystemFont = 1, + FileFont = 2, + }; +}; + +struct NVRenderPathMissingGlyphs +{ + enum Enum { + SkipMissing = 0, + UseMissing = 1, + }; +}; + +struct NVRenderPathFontStyleValues +{ + enum Enum { + Bold = 1 << 0, + Italic = 1 << 1, + }; +}; + +typedef NVFlags<NVRenderPathFontStyleValues::Enum, QT3DSU32> NVRenderPathFontStyleFlags; + +struct NVRenderPathReturnValues +{ + enum Enum { + FontGlypsAvailable = 0, + FontTargetUnavailable = 1, + FontUnavailable = 2, + FontUnintelligible = 3, + InvalidEnum = 4, + OutOfMemory = 5, + }; +}; + +struct NVRenderPathFormatType +{ + enum Enum { + Byte = 1, + UByte, + Short, + UShort, + Int, + Uint, + Float, + Utf8, + Utf16, + Bytes2, + Bytes3, + Bytes4, + }; +}; + +struct NVRenderPathGlyphFontMetricValues +{ + enum Enum { + GlyphWidth = 1 << 0, + GlyphHeight = 1 << 1, + GlyphHorizontalBearingX = 1 << 2, + GlyphHorizontalBearingY = 1 << 3, + GlyphHorizontalBearingAdvance = 1 << 4, + GlyphVerticalBearingX = 1 << 5, + GlyphVerticalBearingY = 1 << 6, + GlyphVerticalBearingAdvance = 1 << 7, + GlyphHasKerning = 1 << 8, + + FontXMinBounds = 1 << 9, + FontYMinBounds = 1 << 10, + FontXMaxBounds = 1 << 11, + FontYMaxBounds = 1 << 12, + FontUnitsPerEm = 1 << 13, + FontAscender = 1 << 14, + FontDescender = 1 << 15, + FontHeight = 1 << 16, + FontMaxAdvanceWidth = 1 << 17, + FontMaxAdvanceHeight = 1 << 18, + FontUnderlinePosition = 1 << 19, + FontUnderlineThickness = 1 << 20, + FontHasKerning = 1 << 21, + FontNumGlyphIndices = 1 << 22, + }; +}; + +typedef NVFlags<NVRenderPathGlyphFontMetricValues::Enum, QT3DSU32> +NVRenderPathGlyphFontMetricFlags; + +struct NVRenderPathListMode +{ + enum Enum { + AccumAdjacentPairs = 1, + AdjacentPairs, + FirstToRest, + }; +}; + +struct NVRenderPathFillMode +{ + enum Enum { + Fill = 1, + CountUp, + CountDown, + Invert, + }; +}; + +struct NVRenderPathCoverMode +{ + enum Enum { + ConvexHull = 1, + BoundingBox, + BoundingBoxOfBoundingBox, + PathFillCover, + PathStrokeCover, + }; +}; + +struct NVRenderPathTransformType +{ + enum Enum { + NoTransform = 0, + TranslateX, + TranslateY, + Translate2D, + Translate3D, + Affine2D, + Affine3D, + TransposeAffine2D, + TransposeAffine3D, + }; +}; + +#define QT3DS_RENDER_ITERATE_WINDING \ + QT3DS_RENDER_HANDLE_WINDING(Clockwise) \ + QT3DS_RENDER_HANDLE_WINDING(CounterClockwise) + +struct NVRenderWinding +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_WINDING(x) x, + QT3DS_RENDER_ITERATE_WINDING +#undef QT3DS_RENDER_HANDLE_WINDING + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_WINDING(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_WINDING + #undef QT3DS_RENDER_HANDLE_WINDING + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_RENDER_STATE \ + QT3DS_RENDER_HANDLE_RENDER_STATE(Blend) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(CullFace) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(DepthTest) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(StencilTest) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(ScissorTest) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(DepthWrite) \ + QT3DS_RENDER_HANDLE_RENDER_STATE(Multisample) + +struct NVRenderState +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) x, + QT3DS_RENDER_ITERATE_RENDER_STATE +#undef QT3DS_RENDER_HANDLE_RENDER_STATE + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_RENDER_STATE + #undef QT3DS_RENDER_HANDLE_RENDER_STATE + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_BLEND_FUNC \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(Zero) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(One) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(DstColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(DstAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantColor) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantAlpha) \ + QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantAlpha) \ + QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(SrcAlphaSaturate) + +struct NVRenderSrcBlendFunc +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x, +#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) x, + QT3DS_RENDER_ITERATE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC + }; + + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) \ + case x: \ + return #x; +#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_BLEND_FUNC + #undef QT3DS_RENDER_HANDLE_BLEND_FUNC + #undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderDstBlendFunc +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x, +#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) + QT3DS_RENDER_ITERATE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_BLEND_FUNC +#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC + }; + + static const char *toString(Enum value) + { + return NVRenderSrcBlendFunc::toString((NVRenderSrcBlendFunc::Enum)value); + } +}; + +#define QT3DS_RENDER_ITERATE_BLEND_EQUATION \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(Add) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(Subtract) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(ReverseSubtract) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(Overlay) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorBurn) \ + QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorDodge) + +struct NVRenderBlendEquation +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) x, + QT3DS_RENDER_ITERATE_BLEND_EQUATION +#undef QT3DS_RENDER_HANDLE_BLEND_EQUATION + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_BLEND_EQUATION + #undef QT3DS_RENDER_HANDLE_BLEND_EQUATION + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_FACES \ + QT3DS_RENDER_HANDLE_FACES(Front) \ + QT3DS_RENDER_HANDLE_FACES(Back) \ + QT3DS_RENDER_HANDLE_FACES(FrontAndBack) + +struct NVRenderFaces +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_FACES(x) x, + QT3DS_RENDER_ITERATE_FACES +#undef QT3DS_RENDER_HANDLE_FACES + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_FACES(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_FACES + #undef QT3DS_RENDER_HANDLE_FACES + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_READ_FACES \ + QT3DS_RENDER_HANDLE_READ_FACES(Front) \ + QT3DS_RENDER_HANDLE_READ_FACES(Back) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color0) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color1) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color2) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color3) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color4) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color5) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color6) \ + QT3DS_RENDER_HANDLE_READ_FACES(Color7) + +struct NVReadFaces +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_READ_FACES(x) x, + QT3DS_RENDER_ITERATE_READ_FACES +#undef QT3DS_RENDER_HANDLE_READ_FACES + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_READ_FACES(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_READ_FACES + #undef QT3DS_RENDER_HANDLE_READ_FACES + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderBoolOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x, + QT3DS_RENDER_ITERATE_BOOL_OP +#undef QT3DS_RENDER_HANDLE_BOOL_OP + }; + + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_BOOL_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_BOOL_OP + #undef QT3DS_RENDER_HANDLE_BOOL_OP + default: + break; + } + return "Unknown"; + } +}; + +#define QT3DS_RENDER_ITERATE_STENCIL_OP \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Keep) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Zero) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Replace) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Increment) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(IncrementWrap) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Decrement) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(DecrementWrap) \ + QT3DS_RENDER_HANDLE_STENCIL_OP(Invert) + +struct NVRenderStencilOp +{ + enum Enum { + Unknown = 0, +#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) x, + QT3DS_RENDER_ITERATE_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_STENCIL_OP + }; + static const char *toString(Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) \ + case x: \ + return #x; + QT3DS_RENDER_ITERATE_STENCIL_OP + #undef QT3DS_RENDER_HANDLE_STENCIL_OP + default: + break; + } + return "Unknown"; + } +}; + +struct NVRenderBlendFunctionArgument +{ + NVRenderSrcBlendFunc::Enum m_SrcRGB; + NVRenderDstBlendFunc::Enum m_DstRGB; + NVRenderSrcBlendFunc::Enum m_SrcAlpha; + NVRenderDstBlendFunc::Enum m_DstAlpha; + + NVRenderBlendFunctionArgument(NVRenderSrcBlendFunc::Enum srcRGB, + NVRenderDstBlendFunc::Enum dstRGB, + NVRenderSrcBlendFunc::Enum srcAlpha, + NVRenderDstBlendFunc::Enum dstAlpha) + : m_SrcRGB(srcRGB) + , m_DstRGB(dstRGB) + , m_SrcAlpha(srcAlpha) + , m_DstAlpha(dstAlpha) + { + } + + // Default blend system premultiplies values. + NVRenderBlendFunctionArgument() + : m_SrcRGB(NVRenderSrcBlendFunc::SrcAlpha) + , m_DstRGB(NVRenderDstBlendFunc::OneMinusSrcAlpha) + , m_SrcAlpha(NVRenderSrcBlendFunc::One) + , m_DstAlpha(NVRenderDstBlendFunc::OneMinusSrcAlpha) + { + } +}; + +struct NVRenderBlendEquationArgument +{ + NVRenderBlendEquation::Enum m_RGBEquation; + NVRenderBlendEquation::Enum m_AlphaEquation; + + NVRenderBlendEquationArgument(NVRenderBlendEquation::Enum rgb, + NVRenderBlendEquation::Enum alpha) + : m_RGBEquation(rgb) + , m_AlphaEquation(alpha) + { + } + NVRenderBlendEquationArgument() + : m_RGBEquation(NVRenderBlendEquation::Add) + , m_AlphaEquation(NVRenderBlendEquation::Add) + { + } +}; + +struct NVRenderStencilOperationArgument +{ + NVRenderStencilOp::Enum m_StencilFail; // What happens when stencil test fails. + // These values assume the stencil passed + NVRenderStencilOp::Enum + m_DepthFail; // What happens when the stencil passes but depth test fail. + NVRenderStencilOp::Enum m_DepthPass; // What happens when the stencil and depth tests pass. + + NVRenderStencilOperationArgument(NVRenderStencilOp::Enum fail, + NVRenderStencilOp::Enum depthFail, + NVRenderStencilOp::Enum depthPass) + : m_StencilFail(fail) + , m_DepthFail(depthFail) + , m_DepthPass(depthPass) + { + } + NVRenderStencilOperationArgument() + : m_StencilFail(NVRenderStencilOp::Keep) + , m_DepthFail(NVRenderStencilOp::Keep) + , m_DepthPass(NVRenderStencilOp::Keep) + { + } + NVRenderStencilOperationArgument(const NVRenderStencilOperationArgument &StencilOp) + : m_StencilFail(StencilOp.m_StencilFail) + , m_DepthFail(StencilOp.m_DepthFail) + , m_DepthPass(StencilOp.m_DepthPass) + { + } + + NVRenderStencilOperationArgument &operator=(const NVRenderStencilOperationArgument &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_StencilFail = rhs.m_StencilFail; + m_DepthFail = rhs.m_DepthFail; + m_DepthPass = rhs.m_DepthPass; + + return *this; + } + + bool operator==(const NVRenderStencilOperationArgument &other) const + { + return (m_StencilFail == other.m_StencilFail && m_DepthFail == other.m_DepthFail + && m_DepthPass == other.m_DepthPass); + } +}; + +// see glStencilFuncSeparate +struct NVRenderStencilFunctionArgument +{ + NVRenderBoolOp::Enum m_Function; + QT3DSU32 m_ReferenceValue; + QT3DSU32 m_Mask; + + NVRenderStencilFunctionArgument(NVRenderBoolOp::Enum function, QT3DSU32 referenceValue, + QT3DSU32 mask) + : m_Function(function) + , m_ReferenceValue(referenceValue) + , m_Mask(mask) + { + } + NVRenderStencilFunctionArgument() + : m_Function(NVRenderBoolOp::AlwaysTrue) + , m_ReferenceValue(0) + , m_Mask((QT3DSU32)-1) + { + } + NVRenderStencilFunctionArgument(const NVRenderStencilFunctionArgument &StencilFunc) + : m_Function(StencilFunc.m_Function) + , m_ReferenceValue(StencilFunc.m_ReferenceValue) + , m_Mask(StencilFunc.m_Mask) + { + } + + NVRenderStencilFunctionArgument &operator=(const NVRenderStencilFunctionArgument &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_Function = rhs.m_Function; + m_ReferenceValue = rhs.m_ReferenceValue; + m_Mask = rhs.m_Mask; + + return *this; + } + + bool operator==(const NVRenderStencilFunctionArgument &other) const + { + return (m_Function == other.m_Function && m_ReferenceValue == other.m_ReferenceValue + && m_Mask == other.m_Mask); + } +}; + +class NVRenderFrameBuffer; +class NVRenderVertexBuffer; +class NVRenderIndexBuffer; +class NVRenderShaderProgram; +class NVRenderProgramPipeline; +class NVRenderTextureBase; +class NVRenderTexture2D; +class NVRenderTexture2DArray; +class NVRenderTextureCube; +class NVRenderImage2D; +class NVRenderDataBuffer; +class NVRenderAttribLayout; +class NVRenderInputAssembler; + +typedef NVRenderFrameBuffer *NVRenderFrameBufferPtr; +typedef NVRenderVertexBuffer *NVRenderVertexBufferPtr; +typedef NVRenderIndexBuffer *NVRenderIndexBufferPtr; +typedef NVRenderTexture2D *NVRenderTexture2DPtr; +typedef NVRenderTexture2DPtr *NVRenderTexture2DHandle; +typedef NVRenderTexture2DArray *NVRenderTexture2DArrayPtr; +typedef NVRenderTextureCube *NVRenderTextureCubePtr; +typedef NVRenderTextureCubePtr *NVRenderTextureCubeHandle; +typedef NVRenderImage2D *NVRenderImage2DPtr; +typedef NVRenderDataBuffer *NVRenderDataBufferPtr; +typedef const char *NVRenderConstCharPtr; +typedef bool QT3DSRenderBool; +typedef NVRenderShaderProgram *NVRenderShaderProgramPtr; +typedef NVDataRef<QT3DSU32> NVU32List; +typedef NVDataRef<const char *> NVConstCharPtrList; + +template <typename TDataType> +struct NVRenderRectT +{ + typedef TDataType TRectType; + TDataType m_X; + TDataType m_Y; + TDataType m_Width; + TDataType m_Height; + NVRenderRectT(TDataType x, TDataType y, TDataType w, TDataType h) + : m_X(x) + , m_Y(y) + , m_Width(w) + , m_Height(h) + { + } + NVRenderRectT() + : m_X(0) + , m_Y(0) + , m_Width(0) + , m_Height(0) + { + } + bool operator==(const NVRenderRectT<TDataType> &inOther) const + { + return m_X == inOther.m_X && m_Y == inOther.m_Y && m_Width == inOther.m_Width + && m_Height == inOther.m_Height; + } + bool operator!=(const NVRenderRectT<TDataType> &inOther) const + { + return !(*this == inOther); + } + TDataType GetRightExtent() const { return m_X + m_Width; } + TDataType GetBottomExtent() const { return m_Y + m_Height; } + // Ensure this rect is inside the bounds of the other rect + void EnsureInBounds(const NVRenderRectT<TDataType> &inOther) + { + TDataType rightExtent = qt3ds::NVMin(GetRightExtent(), inOther.GetRightExtent()); + TDataType bottomExtent = qt3ds::NVMin(GetBottomExtent(), inOther.GetBottomExtent()); + m_X = qt3ds::NVMax(m_X, inOther.m_X); + m_Y = qt3ds::NVMax(m_Y, inOther.m_Y); + m_Width = NVMax(static_cast<TDataType>(0), rightExtent - m_X); + m_Height = NVMax(static_cast<TDataType>(0), bottomExtent - m_Y); + } +}; + +// Render rects are setup to be in the coordinate space of the gl viewport, +// so x, y are left, bottom with increasing units going to the right and +// up respectively. +struct NVRenderRect : public NVRenderRectT<QT3DSI32> +{ + typedef NVRenderRectT<QT3DSI32> TBase; + NVRenderRect(QT3DSI32 x, QT3DSI32 y, QT3DSI32 w, QT3DSI32 h) + : TBase(x, y, w, h) + { + } + NVRenderRect() + : TBase() + { + } +}; + +struct NVRenderRectF : public NVRenderRectT<QT3DSF32> +{ + typedef NVRenderRectT<QT3DSF32> TBase; + NVRenderRectF(QT3DSF32 x, QT3DSF32 y, QT3DSF32 w, QT3DSF32 h) + : TBase(x, y, w, h) + { + } + NVRenderRectF() + : TBase() + { + } + NVRenderRectF(const NVRenderRect &inRect) + : TBase((QT3DSF32)inRect.m_X, (QT3DSF32)inRect.m_Y, (QT3DSF32)inRect.m_Width, + (QT3DSF32)inRect.m_Height) + { + } + NVRenderRect ToIntegerRect() const + { + return NVRenderRect((QT3DSI32)m_X, (QT3DSI32)m_Y, (QT3DSU32)(m_Width + .5f), + (QT3DSU32)(m_Height + .5f)); + } + QT3DSVec2 BottomLeft() const { return QT3DSVec2(m_X, m_Y); } + QT3DSVec2 Center() const + { + QT3DSVec2 halfDims = HalfDims(); + return QT3DSVec2(m_X + halfDims.x, m_Y + halfDims.y); + } + QT3DSVec2 HalfDims() const { return QT3DSVec2(m_Width / 2.0f, m_Height / 2.0f); } + // Normalized coordinates are in the range of -1,1 where -1 is the left, bottom edges + // and 1 is the top,right edges. + QT3DSVec2 AbsoluteToNormalizedCoordinates(QT3DSVec2 absoluteCoordinates) const + { + QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates)); + return RelativeToNormalizedCoordinates(relativeCoords); + }; + + QT3DSVec2 RelativeToNormalizedCoordinates(QT3DSVec2 rectRelativeCoords) const + { + QT3DSVec2 halfDims(HalfDims()); + QT3DSVec2 retval((rectRelativeCoords.x / halfDims.x) - 1.0f, + (rectRelativeCoords.y / halfDims.y) - 1.0f); + return retval; + } + + // Take coordinates in global space and move local space where 0,0 is the center + // of the rect but return value in pixels, not in normalized -1,1 range + QT3DSVec2 ToNormalizedRectRelative(QT3DSVec2 absoluteCoordinates) const + { + // normalize them + QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates)); + QT3DSVec2 halfDims(HalfDims()); + QT3DSVec2 normalized((relativeCoords.x / halfDims.x) - 1.0f, + (relativeCoords.y / halfDims.y) - 1.0f); + return QT3DSVec2(normalized.x * halfDims.x, normalized.y * halfDims.y); + } + + // Return coordinates in pixels but relative to this rect. + QT3DSVec2 ToRectRelative(QT3DSVec2 absoluteCoordinates) const + { + return QT3DSVec2(absoluteCoordinates.x - m_X, absoluteCoordinates.y - m_Y); + } + + QT3DSVec2 ToAbsoluteCoords(QT3DSVec2 inRelativeCoords) const + { + return QT3DSVec2(inRelativeCoords.x + m_X, inRelativeCoords.y + m_Y); + } +}; + +template <typename TDataType> +struct NVRenderGenericVec2 +{ + TDataType x; + TDataType y; + NVRenderGenericVec2(TDataType _x, TDataType _y) + : x(_x) + , y(_y) + { + } + NVRenderGenericVec2() {} + bool operator==(const NVRenderGenericVec2 &inOther) const + { + return x == inOther.x && y == inOther.y; + } +}; + +template <typename TDataType> +struct NVRenderGenericVec3 +{ + TDataType x; + TDataType y; + TDataType z; + NVRenderGenericVec3(TDataType _x, TDataType _y, TDataType _z) + : x(_x) + , y(_y) + , z(_z) + { + } + NVRenderGenericVec3() {} + bool operator==(const NVRenderGenericVec3 &inOther) const + { + return x == inOther.x && y == inOther.y && z == inOther.z; + } +}; + +template <typename TDataType> +struct NVRenderGenericVec4 +{ + TDataType x; + TDataType y; + TDataType z; + TDataType w; + NVRenderGenericVec4(TDataType _x, TDataType _y, TDataType _z, TDataType _w) + : x(_x) + , y(_y) + , z(_z) + , w(_w) + { + } + NVRenderGenericVec4() {} + bool operator==(const NVRenderGenericVec4 &inOther) const + { + return x == inOther.x && y == inOther.y && z == inOther.z && w == inOther.w; + } +}; + +#define DECLARE_GENERIC_VECTOR_TYPE(type, numElems) \ + typedef NVRenderGenericVec##numElems<type> type##_##numElems +DECLARE_GENERIC_VECTOR_TYPE(bool, 2); +DECLARE_GENERIC_VECTOR_TYPE(bool, 3); +DECLARE_GENERIC_VECTOR_TYPE(bool, 4); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 2); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 3); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 4); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 2); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 3); +DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 4); + +#define ITERATE_QT3DS_SHADER_DATA_TYPES \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSRenderBool) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(bool_2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(bool_3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(bool_4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSF32) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_2) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_3) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_4) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat33) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat44) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DPtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DHandle) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DArrayPtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubePtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubeHandle) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderImage2DPtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderDataBufferPtr) + +struct NVRenderShaderDataTypes +{ + enum Enum { + Unknown = 0, +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) type, + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + }; +}; + +template <typename TDataType> +struct NVDataTypeToShaderDataTypeMap +{ +}; + +#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \ + template <> \ + struct NVDataTypeToShaderDataTypeMap<type> \ +{ \ + static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::type; } \ +}; +ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + +template <> +struct NVDataTypeToShaderDataTypeMap<NVConstDataRef<QT3DSMat44>> +{ + static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::QT3DSMat44; } +}; + +struct NVRenderShaderTypeValue +{ + enum Enum { + Unknown = 1 << 0, + Vertex = 1 << 1, + Fragment = 1 << 2, + TessControl = 1 << 3, + TessEvaluation = 1 << 4, + Geometry = 1 << 5 + }; +}; + +typedef NVFlags<NVRenderShaderTypeValue::Enum, QT3DSU32> NVRenderShaderTypeFlags; + +struct NVRenderTextureTypeValue +{ + enum Enum { + Unknown = 0, + Diffuse, + Specular, + Environment, + Bump, + Normal, + Displace, + Emissive, + Emissive2, + Anisotropy, + Translucent, + LightmapIndirect, + LightmapRadiosity, + LightmapShadow + }; + + static const char *toString(NVRenderTextureTypeValue::Enum value) + { + switch (value) { + case Unknown: + return "Unknown"; + case Diffuse: + return "Diffuse"; + case Specular: + return "Specular"; + case Environment: + return "Environment"; + case Bump: + return "Bump"; + case Normal: + return "Normal"; + case Displace: + return "Displace"; + case Emissive: + return "Emissive"; + case Emissive2: + return "Emissive2"; + case Anisotropy: + return "Anisotropy"; + case Translucent: + return "Translucent"; + case LightmapIndirect: + return "LightmapIndirect"; + case LightmapRadiosity: + return "LightmapRadiosity"; + case LightmapShadow: + return "LightmapShadow"; + default: + return "Unknown"; + } + } +}; + +#define ITERATE_QT3DS_READ_PIXEL_FORMATS \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(Alpha8) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB565) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB8) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA4444) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA5551) \ + HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA8) + +struct NVRenderReadPixelFormats +{ + enum Enum { + Unknown = 0, +#define HANDLE_QT3DS_READ_PIXEL_FORMAT(format) format, + ITERATE_QT3DS_READ_PIXEL_FORMATS +#undef HANDLE_QT3DS_READ_PIXEL_FORMAT + }; +}; + +// Now for scoped property access. +template <typename TBaseType, typename TDataType> +struct NVRenderGenericScopedProperty +{ + typedef void (TBaseType::*TSetter)(TDataType inType); + typedef TDataType (TBaseType::*TGetter)() const; + + TBaseType &m_Context; + TSetter m_Setter; + TDataType m_InitialValue; + NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter) + : m_Context(ctx) + , m_Setter(setter) + , m_InitialValue(((ctx).*getter)()) + { + } + NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter, + const TDataType &inNewValue) + : m_Context(ctx) + , m_Setter(setter) + , m_InitialValue(((ctx).*getter)()) + { + ((m_Context).*m_Setter)(inNewValue); + } + ~NVRenderGenericScopedProperty() { ((m_Context).*m_Setter)(m_InitialValue); } +}; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp b/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp new file mode 100644 index 00000000..01aef473 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderComputeShader.h" + +namespace qt3ds { +namespace render { + + NVRenderComputeShader::NVRenderComputeShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, NVConstDataRef<QT3DSI8> source, + bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateComputeShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderComputeShader::~NVRenderComputeShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseComputeShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderComputeShader.h b/src/Runtime/Source/render/Qt3DSRenderComputeShader.h new file mode 100644 index 00000000..1ab36bc0 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderComputeShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_COMPUTE_SHADER_H +#define QT3DS_RENDER_COMPUTE_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a compute shader + class NVRenderComputeShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderComputeShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram); + + /// @brief destructor + ~NVRenderComputeShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendComputeShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendComputeShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp new file mode 100644 index 00000000..1b3c43a9 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderConstantBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + ///< struct handling a constant buffer entry + class ConstantBufferParamEntry + { + public: + CRegisteredString m_Name; ///< parameter Name + NVRenderShaderDataTypes::Enum m_Type; ///< parameter type + QT3DSI32 m_Count; ///< one or array size + QT3DSI32 m_Offset; ///< offset into the memory buffer + + ConstantBufferParamEntry(CRegisteredString name, NVRenderShaderDataTypes::Enum type, + QT3DSI32 count, QT3DSI32 offset) + : m_Name(name) + , m_Type(type) + , m_Count(count) + , m_Offset(offset) + { + } + }; + + NVRenderConstantBuffer::NVRenderConstantBuffer(NVRenderContextImpl &context, + CRegisteredString bufferName, size_t size, + NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Constant, usageType, NVDataRef<QT3DSU8>()) + , m_Name(bufferName) + , m_ConstantBufferEntryMap(m_Foundation.getAllocator(), + "NVRenderConstantBuffer::m_ConstantBufferEntryMap") + , m_CurrentOffset(0) + , m_CurrentSize(0) + , m_HWBufferInitialized(false) + , m_Dirty(true) + , m_RangeStart(0) + , m_RangeEnd(0) + , m_MaxBlockSize(0) + { + QT3DS_ASSERT(context.GetConstantBufferSupport()); + + m_Backend->GetRenderBackendValue( + NVRenderBackend::NVRenderBackendQuery::MaxConstantBufferBlockSize, &m_MaxBlockSize); + + if (size && data.size() && size == data.size()) { + QT3DS_ASSERT(size < (QT3DSU32)m_MaxBlockSize); + if (allocateShadowBuffer(data.size())) { + memcpy(m_ShadowCopy.begin(), data.begin(), data.size()); + } + } + } + + NVRenderConstantBuffer::~NVRenderConstantBuffer() + { + // check if we should release memory + if (m_ShadowCopy.size()) { + m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin()); + } + + m_ShadowCopy = NVDataRef<QT3DSU8>(); + + for (TRenderConstantBufferEntryMap::iterator iter = m_ConstantBufferEntryMap.begin(), + end = m_ConstantBufferEntryMap.end(); + iter != end; ++iter) { + NVDelete(m_Foundation.getAllocator(), iter->second); + } + + m_ConstantBufferEntryMap.clear(); + + m_Context.BufferDestroyed(*this); + } + + void NVRenderConstantBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderConstantBuffer::BindToShaderProgram(NVRenderShaderProgram *inShader, + QT3DSU32 blockIndex, QT3DSU32 binding) + { + if ((QT3DSI32)binding == -1) { + binding = m_Context.GetNextConstantBufferUnit(); + m_Backend->ProgramSetConstantBlock(inShader->GetShaderProgramHandle(), blockIndex, + binding); + } + + m_Backend->ProgramSetConstantBuffer(binding, m_BufferHandle); + } + + bool NVRenderConstantBuffer::SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index, + QT3DSI32 bufSize, QT3DSI32 paramCount) + { + bool bSuccess = false; + + if (!m_HWBufferInitialized) { + // allocate shadow buffer + QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate( + bufSize, "NVRenderConstantBuffer", __FILE__, __LINE__); + if (!newMem) + return false; + + // allocate temp buffers to hold constant buffer information + QT3DSI32 *theIndices = NULL, *theTypes = NULL, *theSizes = NULL, *theOffsets = NULL; + theIndices = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theIndices) + goto fail; + theTypes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theTypes) + goto fail; + theSizes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theSizes) + goto fail; + theOffsets = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32), + "NVRenderConstantBuffer"); + if (!theOffsets) + goto fail; + + bSuccess = true; + + // get indices for the individal constant buffer entries + m_Backend->GetConstantBufferParamIndices(pProgram->GetShaderProgramHandle(), index, + theIndices); + + // get constant buffer uniform information + m_Backend->GetConstantBufferParamInfoByIndices(pProgram->GetShaderProgramHandle(), + paramCount, (QT3DSU32 *)theIndices, + theTypes, theSizes, theOffsets); + + // get the names of the uniforms + char nameBuf[512]; + QT3DSI32 elementCount, binding; + NVRenderShaderDataTypes::Enum type; + + QT3DS_FOREACH(idx, paramCount) + { + m_Backend->GetConstantInfoByID(pProgram->GetShaderProgramHandle(), theIndices[idx], + 512, &elementCount, &type, &binding, nameBuf); + // check if we already have this entry + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + TRenderConstantBufferEntryMap::iterator entry = + m_ConstantBufferEntryMap.find(theName); + if (entry != m_ConstantBufferEntryMap.end()) { + ConstantBufferParamEntry *pParam = entry->second; + // copy content + if (m_ShadowCopy.size()) + memcpy(newMem + theOffsets[idx], + m_ShadowCopy.begin() + entry->second->m_Offset, + entry->second->m_Count * getUniformTypeSize(pParam->m_Type)); + + pParam->m_Offset = theOffsets[idx]; + QT3DS_ASSERT(type == pParam->m_Type); + QT3DS_ASSERT(elementCount == pParam->m_Count); + } else { + // create one + m_ConstantBufferEntryMap.insert(eastl::make_pair( + theName, + createParamEntry(theName, (NVRenderShaderDataTypes::Enum)theTypes[idx], + theSizes[idx], theOffsets[idx]))); + } + } + + // release previous one + if (m_ShadowCopy.size()) { + m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin()); + } + // set new one + m_ShadowCopy = NVDataRef<QT3DSU8>(newMem, bufSize); + + m_HWBufferInitialized = true; + + fail: + if (theIndices) + QT3DS_FREE(m_Foundation.getAllocator(), theIndices); + if (theTypes) + QT3DS_FREE(m_Foundation.getAllocator(), theTypes); + if (theSizes) + QT3DS_FREE(m_Foundation.getAllocator(), theSizes); + if (theOffsets) + QT3DS_FREE(m_Foundation.getAllocator(), theOffsets); + + } else { + // some sanity checks + bSuccess = true; + bSuccess &= (m_ShadowCopy.size() <= (QT3DSU32)bufSize); + } + + return bSuccess; + } + + void NVRenderConstantBuffer::Update() + { + // we only update the buffer if the buffer is already on hardware + // and if it is dirty + if (m_Dirty && m_HWBufferInitialized) { + if (m_RangeEnd == 0) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_ShadowCopy.size(), + m_UsageType, m_ShadowCopy.begin()); + else + UpdateRange(); + + m_Dirty = false; + m_RangeStart = m_RangeEnd = 0; + } + } + + void NVRenderConstantBuffer::UpdateRange() + { + if ((m_RangeStart + m_RangeEnd) > m_ShadowCopy.size()) { + QT3DS_ASSERT(false); + return; + } + + m_Backend->UpdateBufferRange(m_BufferHandle, m_BindFlags, m_RangeStart, + m_RangeEnd - m_RangeStart, + m_ShadowCopy.begin() + m_RangeStart); + } + + void NVRenderConstantBuffer::AddParam(CRegisteredString name, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count) + { + if (m_ConstantBufferEntryMap.find(name) == m_ConstantBufferEntryMap.end()) { + ConstantBufferParamEntry *newEntry = + QT3DS_NEW(m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count, + m_CurrentOffset); + + if (newEntry) + m_ConstantBufferEntryMap.insert(eastl::make_pair(name, newEntry)); + } else { + // no duplicated entries + return; + } + + // compute new current buffer size and offset + QT3DSI32 constantSize = getUniformTypeSize(type) * count; + m_CurrentSize += constantSize; + m_CurrentOffset += constantSize; + } + + void NVRenderConstantBuffer::UpdateParam(const char *inName, NVDataRef<QT3DSU8> value) + { + // allocate space if not done yet + // NOTE this gets reallocated once we get the real constant buffer size from a program + if (!m_ShadowCopy.size()) { + // allocate shadow buffer + if (!allocateShadowBuffer(m_CurrentSize)) + return; + } + + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(inName)); + TRenderConstantBufferEntryMap::iterator entry = m_ConstantBufferEntryMap.find(theName); + if (entry != m_ConstantBufferEntryMap.end()) { + if (!memcmp(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(), + entry->second->m_Count * getUniformTypeSize(entry->second->m_Type))) { + return; + } + memcpy(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(), + entry->second->m_Count * getUniformTypeSize(entry->second->m_Type)); + m_Dirty = true; + } + } + + void NVRenderConstantBuffer::UpdateRaw(QT3DSI32 offset, NVDataRef<QT3DSU8> data) + { + // allocate space if yet done + if (!m_ShadowCopy.size()) { + // allocate shadow buffer + if (!allocateShadowBuffer(data.size())) + return; + } + + QT3DS_ASSERT((offset + data.size()) < (QT3DSU32)m_MaxBlockSize); + + // we do not initialize anything when this is used + m_HWBufferInitialized = true; + + // we do not allow resize once allocated + if ((offset + data.size()) > m_ShadowCopy.size()) + return; + + // copy data + if (!memcmp(m_ShadowCopy.begin() + offset, data.begin(), data.size())) { + return; + } + memcpy(m_ShadowCopy.begin() + offset, data.begin(), data.size()); + + // update start + m_RangeStart = (m_Dirty) ? (m_RangeStart > (QT3DSU32)offset) ? offset : m_RangeStart : offset; + m_RangeEnd = (offset + data.size() > m_RangeEnd) ? offset + data.size() : m_RangeEnd; + + m_Dirty = true; + } + + ConstantBufferParamEntry *NVRenderConstantBuffer::createParamEntry( + CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count, QT3DSI32 offset) + { + ConstantBufferParamEntry *newEntry = QT3DS_NEW( + m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count, offset); + + return newEntry; + } + + QT3DSI32 + NVRenderConstantBuffer::getUniformTypeSize(NVRenderShaderDataTypes::Enum type) + { + switch (type) { + case NVRenderShaderDataTypes::QT3DSF32: + return sizeof(QT3DSF32); + case NVRenderShaderDataTypes::QT3DSI32: + return sizeof(QT3DSI32); + case NVRenderShaderDataTypes::QT3DSI32_2: + return sizeof(QT3DSI32) * 2; + case NVRenderShaderDataTypes::QT3DSI32_3: + return sizeof(QT3DSI32) * 3; + case NVRenderShaderDataTypes::QT3DSI32_4: + return sizeof(QT3DSI32) * 4; + case NVRenderShaderDataTypes::QT3DSU32: + return sizeof(QT3DSU32); + case NVRenderShaderDataTypes::QT3DSU32_2: + return sizeof(QT3DSU32) * 2; + case NVRenderShaderDataTypes::QT3DSU32_3: + return sizeof(QT3DSU32) * 3; + case NVRenderShaderDataTypes::QT3DSU32_4: + return sizeof(QT3DSU32) * 4; + case NVRenderShaderDataTypes::QT3DSVec2: + return sizeof(QT3DSF32) * 2; + case NVRenderShaderDataTypes::QT3DSVec3: + return sizeof(QT3DSF32) * 3; + case NVRenderShaderDataTypes::QT3DSVec4: + return sizeof(QT3DSF32) * 4; + case NVRenderShaderDataTypes::QT3DSMat33: + return sizeof(QT3DSF32) * 9; + case NVRenderShaderDataTypes::QT3DSMat44: + return sizeof(QT3DSF32) * 16; + default: + QT3DS_ASSERT(!"Unhandled type in NVRenderConstantBuffer::getUniformTypeSize"); + break; + } + + return 0; + } + + bool NVRenderConstantBuffer::allocateShadowBuffer(QT3DSU32 size) + { + // allocate shadow buffer + QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate(size, "NVRenderConstantBuffer", + __FILE__, __LINE__); + if (!newMem) + return false; + + m_ShadowCopy = NVDataRef<QT3DSU8>(newMem, size); + + m_BufferCapacity = size; + + return true; + } + + NVRenderConstantBuffer *NVRenderConstantBuffer::Create(NVRenderContextImpl &context, + const char *bufferName, + NVRenderBufferUsageType::Enum usageType, + size_t size, + NVConstDataRef<QT3DSU8> bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderConstantBuffer *retval = NULL; + + if (context.GetConstantBufferSupport()) { + CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); + QT3DSU32 cbufSize = sizeof(NVRenderConstantBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "ConstantBuffer"); + retval = new (newMem) NVRenderConstantBuffer( + context, theBufferName, size, usageType, + toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size())); + } else { + QT3DS_ASSERT(false); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h new file mode 100644 index 00000000..5ede23b9 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h @@ -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$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + class ConstantBufferParamEntry; + class NVRenderShaderProgram; + + typedef nvhash_map<CRegisteredString, ConstantBufferParamEntry *> TRenderConstantBufferEntryMap; + + ///< Constant (uniform) buffer representation + class QT3DS_AUTOTEST_EXPORT NVRenderConstantBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] bufferName Name of the buffer. Must match the name used in programs + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderConstantBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, + size_t size, NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data); + + ///< destructor + virtual ~NVRenderConstantBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief bind the buffer to a shader program + * + * @param[in] inShader Pointer to active program + * @param[in] blockIndex Index of the constant block within the program + * @param[in] binding Binding point of constant buffer + * + * @return no return. + */ + virtual void BindToShaderProgram(NVRenderShaderProgram *inShader, QT3DSU32 blockIndex, + QT3DSU32 binding); + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief setup constant buffer + * + * @param[in] pProgram Pointer to the shader program + * @param[in] index Index of the constant buffer within the program + * @param[in] bufSize Size of the constant buffer + * @param[in] paramCount Parameter entry count of the constant buffer + * + * @return return if successful + */ + bool SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index, QT3DSI32 bufSize, + QT3DSI32 paramCount); + + /** + * @brief add a parameter to the constant buffer + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] type Type of the parameter like Mat44 + * @param[in] count One or size of array + * + * @return no return + */ + void AddParam(CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count); + + /** + * @brief update a parameter in the constant buffer + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] value New value + * + * @return no return + */ + void UpdateParam(const char *name, NVDataRef<QT3DSU8> value); + + /** + * @brief update a piece of memory directly within the constant buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 layout which guarantees a specific layout behavior across all + *HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into constant buffer + * @param[in] data pointer to new data + * + * @return no return + */ + void UpdateRaw(QT3DSI32 offset, NVDataRef<QT3DSU8> data); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_BufferHandle); + } + + /** + * @brief create a NVRenderConstantBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the backend object handle. + */ + static NVRenderConstantBuffer *Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData); + + /** + * @brief get the buffer name + * + * @return the buffer name + */ + CRegisteredString GetBufferName() const { return m_Name; } + + private: + /** + * @brief Create a parameter entry + * + * @param[in] name Name of the parameter (must match the name in the shader + * program) + * @param[in] type Type of the parameter like Mat44 + * @param[in] count One or size of array + * @param[in] offset Offset of the parameter in the memory buffer + * + * @return return new Entry + */ + ConstantBufferParamEntry *createParamEntry(CRegisteredString name, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + QT3DSI32 offset); + + /** + * @brief get size of a uniform type + * + * @param[in] type type of uniform + * + * @return return uniform size + */ + QT3DSI32 + getUniformTypeSize(NVRenderShaderDataTypes::Enum type); + + /** + * @brief allocate the shadow buffer + * + * @param[in] size size of buffer + * + * @return return true on success + */ + bool allocateShadowBuffer(QT3DSU32 size); + + /** + * @brief update a certain range of the buffer to hardware + * + * @return no return. + */ + virtual void UpdateRange(); + + private: + CRegisteredString m_Name; ///< buffer name + TRenderConstantBufferEntryMap + m_ConstantBufferEntryMap; ///< holds the entries of a constant buffer + QT3DSU32 m_CurrentOffset; ///< holds the current offset + QT3DSU32 m_CurrentSize; ///< holds the current size + bool m_HWBufferInitialized; ///< true if the hardware version of the buffer is initialized + bool m_Dirty; ///< true if buffer is dirty + QT3DSU32 m_RangeStart; ///< start offset of the range to update + QT3DSU32 m_RangeEnd; ///< size of the range to update + QT3DSI32 m_MaxBlockSize; ///< maximum size for a single constant buffer + NVDataRef<QT3DSU8> m_ShadowCopy; ///< host copy of the data in the GPU + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderContext.cpp b/src/Runtime/Source/render/Qt3DSRenderContext.cpp new file mode 100644 index 00000000..aa2cb30f --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderContext.cpp @@ -0,0 +1,1107 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSMat44.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Utils.h" +#include "EASTL/set.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace eastl; + +namespace qt3ds { +namespace render { + + NVRenderContextImpl::NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend, + IStringTable &inStrTable) + : m_backend(inBackend) + , m_DirtyFlags(0) + , m_DefaultOffscreenRenderTarget((NVRenderBackend::NVRenderBackendRenderTargetObject)NULL) + , m_DephBits(16) + , m_StencilBits(8) + , mRefCount(0) + , m_Foundation(fnd) + , m_StringTable(inStrTable) + , m_VertToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_VertToImpMap") + , m_IndexToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_IndexToImpMap") + , m_ConstantToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ConstantToImpMap") + , m_StorageToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_StorageToImpMap") + , m_AtomicCounterToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_AtomicCounterToImpMap") + , m_DrawIndirectToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_DrawIndirectToImpMap") + , m_DepthStencilStateToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_DepthStencilStateToImpMap") + , m_RasterizerStateToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RasterizerStateToImpMap") + , m_PathFontSpecToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RasterizerStateToImpMap") + , m_Tex2DToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Tex2DToImpMap") + , m_Tex2DArrayToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_Tex2DArrayToImpMap") + , m_TexCubeToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_TexCubeToImpMap") + , m_Image2DtoImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Image2DtoImpMap") + , m_ShaderToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ShaderToImpMap") + , m_RenderBufferToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RenderBufferToImpMap") + , m_FrameBufferToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_FrameBufferToImpMap") + , m_NextTextureUnit(1) + , m_NextConstantBufferUnit(1) + , m_PropertyStack(m_Foundation.getAllocator(), "NVRenderContextImpl::m_PropertyStack") + { + + m_StringTable.addRef(); + + m_MaxTextureUnits = m_backend->GetMaxCombinedTextureUnits(); + m_MaxConstantBufferUnits = 16; // need backend query + + // get initial state + memZero(&m_HardwarePropertyContext, sizeof(m_HardwarePropertyContext)); + + // get default blending functions + m_backend->GetBlendFunc(&m_HardwarePropertyContext.m_BlendFunction); + // set default blend euqation + m_HardwarePropertyContext.m_BlendEquation.m_RGBEquation = NVRenderBlendEquation::Add; + m_HardwarePropertyContext.m_BlendEquation.m_AlphaEquation = NVRenderBlendEquation::Add; + // default state + m_HardwarePropertyContext.m_CullingEnabled = + m_backend->GetRenderState(NVRenderState::CullFace); + m_HardwarePropertyContext.m_DepthFunction = m_backend->GetDepthFunc(); + m_HardwarePropertyContext.m_BlendingEnabled = + m_backend->GetRenderState(NVRenderState::Blend); + m_HardwarePropertyContext.m_DepthWriteEnabled = m_backend->GetDepthWrite(); + m_HardwarePropertyContext.m_DepthTestEnabled = + m_backend->GetRenderState(NVRenderState::DepthTest); + m_HardwarePropertyContext.m_ScissorTestEnabled = + m_backend->GetRenderState(NVRenderState::ScissorTest); + m_backend->GetScissorRect(&m_HardwarePropertyContext.m_ScissorRect); + m_backend->GetViewportRect(&m_HardwarePropertyContext.m_Viewport); + + DoSetClearColor(m_HardwarePropertyContext.m_ClearColor); + } + + NVRenderContextImpl::~NVRenderContextImpl() + { + m_StringTable.release(); + QT3DS_ASSERT(m_VertToImpMap.size() == 0); + m_VertToImpMap.clear(); + QT3DS_ASSERT(m_IndexToImpMap.size() == 0); + m_IndexToImpMap.clear(); + QT3DS_ASSERT(m_ConstantToImpMap.size() == 0); + m_ConstantToImpMap.clear(); + QT3DS_ASSERT(m_StorageToImpMap.size() == 0); + m_StorageToImpMap.clear(); + QT3DS_ASSERT(m_DepthStencilStateToImpMap.size() == 0); + m_DepthStencilStateToImpMap.clear(); + QT3DS_ASSERT(m_RasterizerStateToImpMap.size() == 0); + m_RasterizerStateToImpMap.clear(); + QT3DS_ASSERT(m_PathFontSpecToImpMap.size() == 0); + m_PathFontSpecToImpMap.clear(); + QT3DS_ASSERT(m_Tex2DToImpMap.size() == 0); + m_Tex2DToImpMap.clear(); + QT3DS_ASSERT(m_Tex2DArrayToImpMap.size() == 0); + m_Tex2DArrayToImpMap.clear(); + QT3DS_ASSERT(m_Image2DtoImpMap.size() == 0); + m_Image2DtoImpMap.clear(); + QT3DS_ASSERT(m_ShaderToImpMap.size() == 0); + m_ShaderToImpMap.clear(); + QT3DS_ASSERT(m_RenderBufferToImpMap.size() == 0); + m_RenderBufferToImpMap.clear(); + QT3DS_ASSERT(m_FrameBufferToImpMap.size() == 0); + m_FrameBufferToImpMap.clear(); + + m_backend = NULL; + } + + void NVRenderContextImpl::getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) + { + QT3DSI32 theMaxTextureSize = 0; + m_backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, + &theMaxTextureSize); + + oWidth = (QT3DSU32)theMaxTextureSize; + oHeight = (QT3DSU32)theMaxTextureSize; + } + + NVRenderDepthStencilState *NVRenderContextImpl::CreateDepthStencilState( + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + { + NVRenderDepthStencilState *state = NVRenderDepthStencilState::Create( + *this, enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, + stencilFuncBack, depthStencilOpFront, depthStencilOpBack); + if (state) + m_DepthStencilStateToImpMap.insert( + make_pair(state->GetDepthStencilObjectHandle(), state)); + + return state; + } + + void NVRenderContextImpl::SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) + { + if (inDepthStencilState) { + m_backend->SetDepthStencilState(inDepthStencilState->GetDepthStencilObjectHandle()); + // currently we have a mixture therefore we need to update the context state + SetDepthFunction(inDepthStencilState->GetDepthFunc()); + SetDepthWriteEnabled(inDepthStencilState->GetDepthMask()); + SetDepthTestEnabled(inDepthStencilState->GetDepthEnabled()); + SetStencilTestEnabled(inDepthStencilState->GetStencilEnabled()); + } + } + + void NVRenderContextImpl::StateDestroyed(NVRenderDepthStencilState &state) + { + m_DepthStencilStateToImpMap.erase(state.GetDepthStencilObjectHandle()); + } + + NVRenderRasterizerState * + NVRenderContextImpl::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + { + NVRenderRasterizerState *state = + NVRenderRasterizerState::Create(*this, depthBias, depthScale, cullFace); + if (state) + m_RasterizerStateToImpMap.insert(make_pair(state->GetRasterizerObjectHandle(), state)); + + return state; + } + + void NVRenderContextImpl::SetRasterizerState(NVRenderRasterizerState *inRasterizerState) + { + if (inRasterizerState) + m_backend->SetRasterizerState(inRasterizerState->GetRasterizerObjectHandle()); + } + + void NVRenderContextImpl::StateDestroyed(NVRenderRasterizerState &state) + { + m_RasterizerStateToImpMap.erase(state.GetRasterizerObjectHandle()); + } + + NVRenderVertexBuffer * + NVRenderContextImpl::CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, + QT3DSU32 stride, NVConstDataRef<QT3DSU8> bufferData) + { + NVRenderVertexBuffer *buffer = + NVRenderVertexBuffer::Create(*this, usageType, size, stride, bufferData); + if (buffer) + m_VertToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); + return buffer; + } + + NVRenderVertexBuffer *NVRenderContextImpl::GetVertexBuffer(const void *implementationHandle) + { + nvhash_map<const void *, NVRenderVertexBuffer *>::const_iterator entry = + m_VertToImpMap.find(implementationHandle); + if (entry != m_VertToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderVertexBuffer &buffer) + { + m_VertToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderIndexBuffer * + NVRenderContextImpl::CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, + qt3ds::render::NVRenderComponentTypes::Enum componentType, + size_t size, NVConstDataRef<QT3DSU8> bufferData) + { + NVRenderIndexBuffer *buffer = + NVRenderIndexBuffer::Create(*this, usageType, componentType, size, bufferData); + + if (buffer) { + m_IndexToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); + } + + return buffer; + } + + NVRenderIndexBuffer *NVRenderContextImpl::GetIndexBuffer(const void *implementationHandle) + { + const nvhash_map<const void *, NVRenderIndexBuffer *>::iterator entry = + m_IndexToImpMap.find(implementationHandle); + if (entry != m_IndexToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderIndexBuffer &buffer) + { + m_IndexToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderConstantBuffer * + NVRenderContextImpl::CreateConstantBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, + size_t size, NVConstDataRef<QT3DSU8> bufferData) + { + NVRenderConstantBuffer *buffer = + NVRenderConstantBuffer::Create(*this, bufferName, usageType, size, bufferData); + + if (buffer) { + m_ConstantToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderConstantBuffer *NVRenderContextImpl::GetConstantBuffer(CRegisteredString bufferName) + { + TContextConstantBufferMap::iterator entry = m_ConstantToImpMap.find(bufferName); + if (entry != m_ConstantToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderConstantBuffer &buffer) + { + m_ConstantToImpMap.erase(buffer.GetBufferName()); + } + + QT3DSU32 NVRenderContextImpl::GetNextConstantBufferUnit() + { + QT3DSU32 retval = m_NextConstantBufferUnit; + ++m_NextConstantBufferUnit; + // Too many texture units for a single draw call. + if (retval >= m_MaxConstantBufferUnits) { + QT3DS_ASSERT(false); + retval = retval % m_MaxConstantBufferUnits; + } + return retval; + } + + NVRenderStorageBuffer *NVRenderContextImpl::CreateStorageBuffer( + const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer) + { + NVRenderStorageBuffer *buffer = + NVRenderStorageBuffer::Create(*this, bufferName, usageType, size, bufferData, pBuffer); + + if (buffer) { + m_StorageToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderStorageBuffer *NVRenderContextImpl::GetStorageBuffer(CRegisteredString bufferName) + { + TContextStorageBufferMap::iterator entry = m_StorageToImpMap.find(bufferName); + if (entry != m_StorageToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderStorageBuffer &buffer) + { + m_StorageToImpMap.erase(buffer.GetBufferName()); + } + + NVRenderAtomicCounterBuffer *NVRenderContextImpl::CreateAtomicCounterBuffer( + const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) + { + NVRenderAtomicCounterBuffer *buffer = + NVRenderAtomicCounterBuffer::Create(*this, bufferName, usageType, size, bufferData); + + if (buffer) { + m_AtomicCounterToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderAtomicCounterBuffer * + NVRenderContextImpl::GetAtomicCounterBuffer(CRegisteredString bufferName) + { + TContextAtomicCounterBufferMap::iterator entry = m_AtomicCounterToImpMap.find(bufferName); + if (entry != m_AtomicCounterToImpMap.end()) + return entry->second; + return NULL; + } + + NVRenderAtomicCounterBuffer * + NVRenderContextImpl::GetAtomicCounterBufferByParam(CRegisteredString paramName) + { + // iterate through all atomic counter buffers + for (TContextAtomicCounterBufferMap::iterator iter = m_AtomicCounterToImpMap.begin(), + end = m_AtomicCounterToImpMap.end(); + iter != end; ++iter) { + if (iter->second && iter->second->ContainsParam(paramName)) + return iter->second; + } + + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderAtomicCounterBuffer &buffer) + { + m_AtomicCounterToImpMap.erase(buffer.GetBufferName()); + } + + NVRenderDrawIndirectBuffer *NVRenderContextImpl::CreateDrawIndirectBuffer( + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) + { + NVRenderDrawIndirectBuffer *buffer = + NVRenderDrawIndirectBuffer::Create(*this, usageType, size, bufferData); + + if (buffer) { + m_DrawIndirectToImpMap.insert(make_pair(buffer->GetBuffertHandle(), buffer)); + } + + return buffer; + } + + NVRenderDrawIndirectBuffer *NVRenderContextImpl::GetDrawIndirectBuffer( + NVRenderBackend::NVRenderBackendBufferObject implementationHandle) + { + TContextDrawIndirectBufferMap::iterator entry = + m_DrawIndirectToImpMap.find(implementationHandle); + if (entry != m_DrawIndirectToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderDrawIndirectBuffer &buffer) + { + m_DrawIndirectToImpMap.erase(buffer.GetBuffertHandle()); + } + + void NVRenderContextImpl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) + { + m_backend->SetMemoryBarrier(barriers); + } + + NVRenderOcclusionQuery *NVRenderContextImpl::CreateOcclusionQuery() + { + NVRenderOcclusionQuery *theQuery = NVRenderOcclusionQuery::Create(*this); + + return theQuery; + } + + NVRenderTimerQuery *NVRenderContextImpl::CreateTimerQuery() + { + NVRenderTimerQuery *theQuery = NVRenderTimerQuery::Create(*this); + + return theQuery; + } + + NVRenderSync *NVRenderContextImpl::CreateSync() + { + NVRenderSync *theSync = NVRenderSync::Create(*this); + + return theSync; + } + + NVRenderTexture2D *NVRenderContextImpl::CreateTexture2D() + { + NVRenderTexture2D *retval = NVRenderTexture2D::Create(*this); + if (retval) + m_Tex2DToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderTexture2DArray *NVRenderContextImpl::CreateTexture2DArray() + { + NVRenderTexture2DArray *retval = NVRenderTexture2DArray::Create(*this); + if (retval) + m_Tex2DArrayToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + NVRenderTextureCube *NVRenderContextImpl::CreateTextureCube() + { + NVRenderTextureCube *retval = NVRenderTextureCube::Create(*this); + if (retval) + m_TexCubeToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + NVRenderTexture2D *NVRenderContextImpl::GetTexture2D(const void *implementationHandle) + { + const nvhash_map<const void *, NVRenderTexture2D *>::iterator entry = + m_Tex2DToImpMap.find(implementationHandle); + if (entry != m_Tex2DToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2D &buffer) + { + m_Tex2DToImpMap.erase(buffer.GetImplementationHandle()); + // We would like to find and catch any situations where this texture is being used + // but that would require some real work that we don't want to do right now. + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2DArray &buffer) + { + m_Tex2DArrayToImpMap.erase(buffer.GetTextureObjectHandle()); + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTextureCube &buffer) + { + m_TexCubeToImpMap.erase(buffer.GetTextureObjectHandle()); + } + + NVRenderImage2D *NVRenderContextImpl::CreateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) + { + NVRenderImage2D *retval = NVRenderImage2D::Create(*this, inTexture, inAccess); + if (retval) + m_Image2DtoImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + void NVRenderContextImpl::ImageDestroyed(NVRenderImage2D &image) + { + m_Image2DtoImpMap.erase(image.GetTextureObjectHandle()); + } + + // IF this texture isn't on a texture unit, put it on one. + // If it is on a texture unit, mark it as the most recently used texture. + QT3DSU32 NVRenderContextImpl::GetNextTextureUnit() + { + QT3DSU32 retval = m_NextTextureUnit; + ++m_NextTextureUnit; + // Too many texture units for a single draw call. + if (retval >= m_MaxTextureUnits) { + QT3DS_ASSERT(false); + retval = retval % m_MaxTextureUnits; + } + return retval; + } + + NVRenderRenderBuffer * + NVRenderContextImpl::CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, + QT3DSU32 width, QT3DSU32 height) + { + NVRenderRenderBuffer *retval = + NVRenderRenderBuffer::Create(*this, bufferFormat, width, height); + if (retval != NULL) + m_RenderBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderRenderBuffer *NVRenderContextImpl::GetRenderBuffer(const void *implementationHandle) + { + const nvhash_map<const void *, NVRenderRenderBuffer *>::iterator entry = + m_RenderBufferToImpMap.find(implementationHandle); + if (entry != m_RenderBufferToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::RenderBufferDestroyed(NVRenderRenderBuffer &buffer) + { + m_RenderBufferToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderFrameBuffer *NVRenderContextImpl::CreateFrameBuffer() + { + NVRenderFrameBuffer *retval = NVRenderFrameBuffer::Create(*this); + if (retval != NULL) + m_FrameBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderFrameBuffer *NVRenderContextImpl::GetFrameBuffer(const void *implementationHandle) + { + const nvhash_map<const void *, NVRenderFrameBuffer *>::iterator entry = + m_FrameBufferToImpMap.find(implementationHandle); + if (entry != m_FrameBufferToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::FrameBufferDestroyed(NVRenderFrameBuffer &fb) + { + m_FrameBufferToImpMap.erase(fb.GetImplementationHandle()); + if (m_HardwarePropertyContext.m_FrameBuffer == &fb) + m_HardwarePropertyContext.m_FrameBuffer = NULL; + } + + NVRenderAttribLayout * + NVRenderContextImpl::CreateAttributeLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) + { + return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderAttribLayout)(*this, attribs); + } + + NVRenderInputAssembler *NVRenderContextImpl::CreateInputAssembler( + NVRenderAttribLayout *attribLayout, NVConstDataRef<NVRenderVertexBuffer *> buffers, + const NVRenderIndexBuffer *indexBuffer, NVConstDataRef<QT3DSU32> strides, + NVConstDataRef<QT3DSU32> offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) + { + return QT3DS_NEW(GetFoundation().getAllocator(), + NVRenderInputAssembler)(*this, attribLayout, buffers, indexBuffer, strides, + offsets, primType, patchVertexCount); + } + + void NVRenderContextImpl::SetInputAssembler(NVRenderInputAssembler *inputAssembler) + { + if (m_HardwarePropertyContext.m_InputAssembler != inputAssembler) { + DoSetInputAssembler(inputAssembler); + } + } + + NVRenderVertFragCompilationResult NVRenderContextImpl::CompileSource( + const char *shaderName, NVConstDataRef<QT3DSI8> vertShader, NVConstDataRef<QT3DSI8> fragShader, + NVConstDataRef<QT3DSI8> tessControlShaderSource, + NVConstDataRef<QT3DSI8> tessEvaluationShaderSource, NVConstDataRef<QT3DSI8> geometryShaderSource, + bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram) + { + NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( + *this, shaderName, vertShader, fragShader, tessControlShaderSource, + tessEvaluationShaderSource, geometryShaderSource, separateProgram, type, binaryProgram); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; + } + + NVRenderVertFragCompilationResult NVRenderContextImpl::CompileBinary( + const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, + NVDataRef<QT3DSI8> vertShader, NVDataRef<QT3DSI8> fragShader, + NVDataRef<QT3DSI8> tessControlShaderSource, NVDataRef<QT3DSI8> tessEvaluationShaderSource, + NVConstDataRef<QT3DSI8> geometryShaderSource) + { +#ifndef _MACOSX + NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( + *this, shaderName, vertShader, fragShader, tessControlShaderSource, + tessEvaluationShaderSource, geometryShaderSource, false, type, true); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; +#else + QT3DS_ASSERT(false); + return NVRenderVertFragCompilationResult(); +#endif + } + + NVRenderVertFragCompilationResult + NVRenderContextImpl::CompileComputeSource(const char *shaderName, + NVConstDataRef<QT3DSI8> computeShaderSource) + { + NVRenderVertFragCompilationResult result = + NVRenderShaderProgram::CreateCompute(*this, shaderName, computeShaderSource); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; + } + + NVRenderShaderProgram *NVRenderContextImpl::GetShaderProgram(const void *implementationHandle) + { + const nvhash_map<const void *, NVRenderShaderProgram *>::iterator entry = + m_ShaderToImpMap.find(implementationHandle); + if (entry != m_ShaderToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::ShaderDestroyed(NVRenderShaderProgram &shader) + { + m_ShaderToImpMap.erase(shader.GetShaderProgramHandle()); + if (m_HardwarePropertyContext.m_ActiveShader == &shader) + SetActiveShader(NULL); + } + + NVRenderProgramPipeline *NVRenderContextImpl::CreateProgramPipeline() + { + return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderProgramPipeline)(*this, + GetFoundation()); + } + + NVRenderPathSpecification *NVRenderContextImpl::CreatePathSpecification() + { + return NVRenderPathSpecification::CreatePathSpecification(*this); + } + + NVRenderPathRender *NVRenderContextImpl::CreatePathRender(size_t range) + { + return NVRenderPathRender::Create(*this, range); + } + + void NVRenderContextImpl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) + { + m_backend->SetPathProjectionMatrix(inPathProjection); + } + + void NVRenderContextImpl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) + { + m_backend->SetPathModelViewMatrix(inPathModelview); + } + + void NVRenderContextImpl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) + { + m_backend->SetPathStencilDepthOffset(inSlope, inBias); + } + void NVRenderContextImpl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) + { + m_backend->SetPathCoverDepthFunc(inFunc); + } + + NVRenderPathFontSpecification * + NVRenderContextImpl::CreatePathFontSpecification(CRegisteredString fontName) + { + // first check if it already exists + nvhash_map<CRegisteredString, NVRenderPathFontSpecification *>::const_iterator entry = + m_PathFontSpecToImpMap.find(fontName); + if (entry != m_PathFontSpecToImpMap.end()) + return entry->second; + + // if not create new one + NVRenderPathFontSpecification *pPathFontSpec = + NVRenderPathFontSpecification::CreatePathFontSpecification(*this, fontName); + + if (pPathFontSpec) + m_PathFontSpecToImpMap.insert(make_pair(fontName, pPathFontSpec)); + + return pPathFontSpec; + } + + void + NVRenderContextImpl::ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec) + { + m_PathFontSpecToImpMap.erase(inPathSpec.GetFontName()); + } + + NVRenderPathFontItem *NVRenderContextImpl::CreatePathFontItem() + { + // if not create new one + return NVRenderPathFontItem::CreatePathFontItem(*this); + } + + void NVRenderContextImpl::SetClearColor(QT3DSVec4 inClearColor) + { + if (m_HardwarePropertyContext.m_ClearColor != inClearColor) + DoSetClearColor(inClearColor); + } + + void NVRenderContextImpl::SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) + { + if (memcmp(&inFunctions, &m_HardwarePropertyContext.m_BlendFunction, + sizeof(NVRenderBlendFunctionArgument))) { + DoSetBlendFunction(inFunctions); + } + } + + void NVRenderContextImpl::SetBlendEquation(NVRenderBlendEquationArgument inEquations) + { + if (memcmp(&inEquations, &m_HardwarePropertyContext.m_BlendEquation, + sizeof(NVRenderBlendEquationArgument))) { + DoSetBlendEquation(inEquations); + } + } + + void NVRenderContextImpl::SetCullingEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_CullingEnabled) { + DoSetCullingEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) + { + if (inFunction != m_HardwarePropertyContext.m_DepthFunction) { + DoSetDepthFunction(inFunction); + } + } + + void NVRenderContextImpl::SetBlendingEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_BlendingEnabled) { + DoSetBlendingEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetColorWritesEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_ColorWritesEnabled) { + DoSetColorWritesEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetDepthWriteEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_DepthWriteEnabled) { + m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::DepthWrite); + } + } + + void NVRenderContextImpl::SetDepthTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_DepthTestEnabled) { + DoSetDepthTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetMultisampleEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_MultisampleEnabled) { + DoSetMultisampleEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetStencilTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_StencilTestEnabled) { + DoSetStencilTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetScissorTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_ScissorTestEnabled) { + DoSetScissorTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetScissorRect(NVRenderRect inRect) + { + if (memcmp(&inRect, &m_HardwarePropertyContext.m_ScissorRect, sizeof(NVRenderRect))) { + DoSetScissorRect(inRect); + } + } + + void NVRenderContextImpl::SetViewport(NVRenderRect inViewport) + { + if (memcmp(&inViewport, &m_HardwarePropertyContext.m_Viewport, sizeof(NVRenderRect))) { + DoSetViewport(inViewport); + } + } + + void NVRenderContextImpl::SetActiveShader(NVRenderShaderProgram *inShader) + { + if (inShader != m_HardwarePropertyContext.m_ActiveShader) + DoSetActiveShader(inShader); + } + + void NVRenderContextImpl::SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) + { + if (inProgramPipeline != m_HardwarePropertyContext.m_ActiveProgramPipeline) + DoSetActiveProgramPipeline(inProgramPipeline); + } + + void NVRenderContextImpl::DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) + { + QT3DS_ASSERT(inShader); + + if (inShader != m_HardwarePropertyContext.m_ActiveShader) + DoSetActiveShader(inShader); + + m_backend->DispatchCompute(inShader->GetShaderProgramHandle(), numGroupsX, numGroupsY, + numGroupsZ); + + OnPostDraw(); + } + + void NVRenderContextImpl::SetDrawBuffers(NVConstDataRef<QT3DSI32> inDrawBufferSet) + { + m_backend->SetDrawBuffers( + (m_HardwarePropertyContext.m_FrameBuffer) + ? m_HardwarePropertyContext.m_FrameBuffer->GetFrameBuffertHandle() + : NULL, + inDrawBufferSet); + } + + void NVRenderContextImpl::SetReadBuffer(NVReadFaces::Enum inReadFace) + { + // currently NULL which means the read target must be set with setReadTarget + m_backend->SetReadBuffer(NULL, inReadFace); + } + + void NVRenderContextImpl::ReadPixels(NVRenderRect inRect, + NVRenderReadPixelFormats::Enum inFormat, + NVDataRef<QT3DSU8> inWriteBuffer) + { + // NULL means read from current render target + m_backend->ReadPixel(NULL, inRect.m_X, inRect.m_Y, inRect.m_Width, inRect.m_Height, + inFormat, (void *)inWriteBuffer.begin()); + } + + void NVRenderContextImpl::SetRenderTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { + DoSetRenderTarget(inBuffer); + } + } + + void NVRenderContextImpl::SetReadTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { + DoSetReadTarget(inBuffer); + } + } + + void NVRenderContextImpl::ResetBlendState() + { + QT3DSI32_4 values; + + m_backend->SetRenderState(m_HardwarePropertyContext.m_BlendingEnabled, + NVRenderState::Blend); + const NVRenderBlendFunctionArgument &theBlendArg(m_HardwarePropertyContext.m_BlendFunction); + m_backend->SetBlendFunc(theBlendArg); + } + + // Pop the entire set of properties, potentially forcing the values + // to opengl. + void NVRenderContextImpl::PopPropertySet(bool inForceSetProperties) + { + if (!m_PropertyStack.empty()) { + SNVGLHardPropertyContext &theTopContext(m_PropertyStack.back()); + if (inForceSetProperties) { +#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ + DoSet##setterName(theTopContext.m_##propName); + + ITERATE_HARDWARE_CONTEXT_PROPERTIES + +#undef HANDLE_CONTEXT_HARDWARE_PROPERTY + } else { +#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ + Set##setterName(theTopContext.m_##propName); + + ITERATE_HARDWARE_CONTEXT_PROPERTIES + +#undef HANDLE_CONTEXT_HARDWARE_PROPERTY + } + m_PropertyStack.pop_back(); + } + } + + void NVRenderContextImpl::Clear(NVRenderClearFlags flags) + { + if ((flags & NVRenderClearValues::Depth) + && m_HardwarePropertyContext.m_DepthWriteEnabled == false) { + QT3DS_ASSERT(false); + SetDepthWriteEnabled(true); + } + m_backend->Clear(flags); + } + + void NVRenderContextImpl::Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) + { + NVRenderFrameBuffer *previous = m_HardwarePropertyContext.m_FrameBuffer; + if (previous != &fb) + SetRenderTarget(&fb); + + Clear(flags); + + if (previous != &fb) + SetRenderTarget(previous); + } + + void NVRenderContextImpl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) + { + m_backend->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, flags, + filter); + } + + bool + NVRenderContextImpl::BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler, + NVRenderShaderProgram *shader) + { + // setup the input assembler object + return m_backend->SetInputAssembler(inputAssembler->GetInputAssemblerHandle(), + shader->GetShaderProgramHandle()); + } + + bool NVRenderContextImpl::ApplyPreDrawProperties() + { + // Get the currently bound vertex and shader + NVRenderInputAssembler *inputAssembler = this->m_HardwarePropertyContext.m_InputAssembler; + NVRenderShaderProgram *shader = this->m_HardwarePropertyContext.m_ActiveShader; + + // we could render through a program pipline + if (shader == NULL && this->m_HardwarePropertyContext.m_ActiveProgramPipeline) + shader = this->m_HardwarePropertyContext.m_ActiveProgramPipeline->GetVertexStage(); + + if (inputAssembler == NULL || shader == NULL) { + qCCritical(INVALID_OPERATION, + "Attempting to render no valid shader or input assembler setup"); + QT3DS_ASSERT(false); + return false; + } + + return BindShaderToInputAssembler(inputAssembler, shader); + } + + void NVRenderContextImpl::OnPostDraw() + { + // reset input assembler binding + m_backend->SetInputAssembler(NULL, 0); + // Texture unit 0 is used for setting up and loading textures. + // Bugs happen if we load a texture then setup the sampler. + // Then we load another texture. Because when loading we use texture unit 0, + // the render bindings for the first texture are blown away. + // Again, for this reason, texture unit 0 is reserved for loading textures. + m_NextTextureUnit = 1; + m_NextConstantBufferUnit = 0; + } + + void NVRenderContextImpl::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) + { + if (!ApplyPreDrawProperties()) + return; + + NVRenderIndexBuffer *theIndexBuffer = const_cast<NVRenderIndexBuffer *>( + m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); + if (theIndexBuffer == NULL) + m_backend->Draw(drawMode, offset, count); + else + theIndexBuffer->Draw(drawMode, count, offset); + + OnPostDraw(); + } + + void NVRenderContextImpl::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) + { + if (!ApplyPreDrawProperties()) + return; + + NVRenderIndexBuffer *theIndexBuffer = const_cast<NVRenderIndexBuffer *>( + m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); + if (theIndexBuffer == NULL) + m_backend->DrawIndirect(drawMode, (const void *)offset); + else + theIndexBuffer->DrawIndirect(drawMode, offset); + + OnPostDraw(); + } + + QT3DSMat44 + NVRenderContext::ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection, + const NVRenderRectF &inViewport, + const NVRenderRectF &inVirtualViewport) + { + if (inVirtualViewport == inViewport) + return inProjection; + // Run conversion to floating point once. + NVRenderRectF theVirtualViewport(inVirtualViewport); + NVRenderRectF theViewport(inViewport); + if (theVirtualViewport.m_Width == 0 || theVirtualViewport.m_Height == 0 + || theViewport.m_Width == 0 || theViewport.m_Height == 0) { + QT3DS_ASSERT(false); + return inProjection; + } + QT3DSMat44 theScaleTransMat(QT3DSMat44::createIdentity()); + QT3DSF32 theHeightDiff = theViewport.m_Height - theVirtualViewport.m_Height; + QT3DSF32 theViewportOffY = theVirtualViewport.m_Y - theViewport.m_Y; + QT3DSVec2 theCameraOffsets = QT3DSVec2(theVirtualViewport.m_Width - theViewport.m_Width + + (theVirtualViewport.m_X - theViewport.m_X) * 2.0f, + theHeightDiff + (theViewportOffY - theHeightDiff) * 2.0f); + QT3DSVec2 theCameraScale = QT3DSVec2(theVirtualViewport.m_Width / theViewport.m_Width, + theVirtualViewport.m_Height / theViewport.m_Height); + + QT3DSVec3 theTranslation(theCameraOffsets.x / theViewport.m_Width, + theCameraOffsets.y / theViewport.m_Height, 0); + theScaleTransMat.column3[0] = theTranslation.x; + theScaleTransMat.column3[1] = theTranslation.y; + theScaleTransMat.column0[0] = theCameraScale.x; + theScaleTransMat.column1[1] = theCameraScale.y; + + return theScaleTransMat * inProjection; + } + + NVRenderVertFragCompilationResult NVRenderContext::CompileSource( + const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, const char *fragShader, + QT3DSU32 inFragLen, const char *tessControlShaderSource, QT3DSU32 inTCLen, + const char *tessEvaluationShaderSource, QT3DSU32 inTELen, const char *geometryShaderSource, + QT3DSU32 inGSLen, bool separableProgram) + { + return CompileSource( + shaderName, NVConstDataRef<QT3DSI8>((const QT3DSI8 *)vertShader, inVertLen), + NVConstDataRef<QT3DSI8>((const QT3DSI8 *)fragShader, inFragLen), + NVConstDataRef<QT3DSI8>((const QT3DSI8 *)tessControlShaderSource, inTCLen), + NVConstDataRef<QT3DSI8>((const QT3DSI8 *)tessEvaluationShaderSource, inTELen), + NVConstDataRef<QT3DSI8>((const QT3DSI8 *)geometryShaderSource, inGSLen), separableProgram); + } + + void NVRenderContextImpl::DoSetActiveShader(NVRenderShaderProgram *inShader) + { + m_HardwarePropertyContext.m_ActiveShader = NULL; + if (inShader) + m_backend->SetActiveProgram(inShader->GetShaderProgramHandle()); + else { + m_backend->SetActiveProgram(NULL); + } + m_HardwarePropertyContext.m_ActiveShader = inShader; + } + + void NVRenderContextImpl::DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) + { + if (inProgramPipeline) { + // invalid any bound shader + DoSetActiveShader(NULL); + inProgramPipeline->Bind(); + } else + m_backend->SetActiveProgramPipeline(NULL); + + m_HardwarePropertyContext.m_ActiveProgramPipeline = inProgramPipeline; + } + + NVRenderContext &NVRenderContext::CreateNULL(NVFoundationBase &foundation, + IStringTable &inStringTable) + { + NVRenderContext *retval = NULL; + + // create backend + NVScopedRefCounted<IStringTable> theStringTable(inStringTable); + NVScopedRefCounted<NVRenderBackend> theBackend = + NVRenderBackendNULL::CreateBackend(foundation); + retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, + *theStringTable); + return *retval; + } +} +} // end namespace diff --git a/src/Runtime/Source/render/Qt3DSRenderContext.h b/src/Runtime/Source/render/Qt3DSRenderContext.h new file mode 100644 index 00000000..e5b51341 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderContext.h @@ -0,0 +1,1063 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_CONTEXT_H +#define QT3DS_RENDER_CONTEXT_H +#include "foundation/Qt3DS.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSDataRef.h" +#include "foundation/Qt3DSMemoryBuffer.h" +#include "render/glg/Qt3DSGLImplObjects.h" +#include "render/backends/gl/Q3DSRenderBackendGLES2.h" +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" +#include "render/backends/gl/Qt3DSRenderBackendGL4.h" +#include "render/backends/software/Qt3DSRenderBackendNULL.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderConstantBuffer.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderDepthStencilState.h" +#include "render/Qt3DSRenderRasterizerState.h" +#include "render/Qt3DSRenderDrawable.h" +#include "render/Qt3DSRenderInputAssembler.h" +#include "render/Qt3DSRenderAttribLayout.h" +#include "render/Qt3DSRenderImageTexture.h" +#include "render/Qt3DSRenderOcclusionQuery.h" +#include "render/Qt3DSRenderTimerQuery.h" +#include "render/Qt3DSRenderSync.h" +#include "render/Qt3DSRenderTexture2DArray.h" +#include "render/Qt3DSRenderTextureCube.h" +#include "render/Qt3DSRenderStorageBuffer.h" +#include "render/Qt3DSRenderAtomicCounterBuffer.h" +#include "render/Qt3DSRenderDrawIndirectBuffer.h" +#include "render/Qt3DSRenderProgramPipeline.h" +#include "render/Qt3DSRenderPathRender.h" +#include "render/Qt3DSRenderPathSpecification.h" +#include "render/Qt3DSRenderPathFontSpecification.h" +#include "render/Qt3DSRenderPathFontText.h" + +#include <QSurfaceFormat> + +// When SW fallback is defined we can support (some) object/layer advanced blend modes. If defined, +// the HW implementation is still preperred if available through extensions. SW fallback can't be +// used in custom shaders. +#define ADVANCED_BLEND_SW_FALLBACK +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + using namespace foundation; + + struct NVRenderShaderProgramBinaryType + { + enum Enum { + Unknown = 0, + NVBinary = 1, + }; + }; + + // context dirty flags + struct NVRenderContextDirtyValues + { + enum Enum { + InputAssembler = 1 << 0, + }; + }; + + typedef NVFlags<NVRenderContextDirtyValues::Enum, QT3DSU32> NVRenderContextDirtyFlags; + typedef nvhash_map<CRegisteredString, NVRenderConstantBuffer *> TContextConstantBufferMap; + typedef nvhash_map<CRegisteredString, NVRenderStorageBuffer *> TContextStorageBufferMap; + typedef nvhash_map<CRegisteredString, NVRenderAtomicCounterBuffer *> + TContextAtomicCounterBufferMap; + typedef nvhash_map<NVRenderBackend::NVRenderBackendBufferObject, NVRenderDrawIndirectBuffer *> + TContextDrawIndirectBufferMap; + typedef nvhash_map<NVRenderBackend::NVRenderBackendDepthStencilStateObject, + NVRenderDepthStencilState *> + TContextDepthStencilStateMap; + typedef nvhash_map<NVRenderBackend::NVRenderBackendRasterizerStateObject, + NVRenderRasterizerState *> + TContextRasterizerStateMap; + typedef nvhash_map<NVRenderBackend::NVRenderBackendTextureObject, NVRenderTexture2DArray *> + TContextTex2DArrayToImpMap; + typedef nvhash_map<NVRenderBackend::NVRenderBackendTextureObject, NVRenderTextureCube *> + TContextTexCubeToImpMap; + typedef nvhash_map<NVRenderBackend::NVRenderBackendTextureObject, NVRenderImage2D *> + TContextImage2DToImpMap; + typedef nvhash_map<CRegisteredString, NVRenderPathFontSpecification *> + TContextPathFontSpecificationMap; + + class QT3DS_AUTOTEST_EXPORT NVRenderContext : public NVRefCounted, public NVRenderDrawable + { + public: + virtual NVRenderContextType GetRenderContextType() const = 0; + virtual bool AreMultisampleTexturesSupported() const = 0; + virtual bool GetConstantBufferSupport() const = 0; + virtual void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) = 0; + virtual const char *GetShadingLanguageVersion() = 0; + // Get the bit depth of the currently bound depth buffer. + virtual QT3DSU32 GetDepthBits() const = 0; + virtual QT3DSU32 GetStencilBits() const = 0; + virtual bool + GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const = 0; + virtual bool AreDXTImagesSupported() const = 0; + virtual bool IsDepthStencilSupported() const = 0; + virtual bool IsFpRenderTargetSupported() const = 0; + virtual bool IsTessellationSupported() const = 0; + virtual bool IsGeometryStageSupported() const = 0; + virtual bool IsComputeSupported() const = 0; + virtual bool IsSampleQuerySupported() const = 0; + virtual bool IsTimerQuerySupported() const = 0; + virtual bool IsCommandSyncSupported() const = 0; + virtual bool IsTextureArraySupported() const = 0; + virtual bool IsStorageBufferSupported() const = 0; + virtual bool IsAtomicCounterBufferSupported() const = 0; + virtual bool IsShaderImageLoadStoreSupported() const = 0; + virtual bool IsProgramPipelineSupported() const = 0; + virtual bool IsPathRenderingSupported() const = 0; + virtual bool IsBlendCoherencySupported() const = 0; + virtual bool IsAdvancedBlendHwSupported() const = 0; + virtual bool IsAdvancedBlendHwSupportedKHR() const = 0; + virtual bool IsStandardDerivativesSupported() const = 0; + virtual bool IsTextureLodSupported() const = 0; + + virtual void SetDefaultRenderTarget(QT3DSU64 targetID) = 0; + virtual void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) = 0; + + virtual NVRenderDepthStencilState * + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) = 0; + + virtual NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) = 0; + + virtual NVRenderVertexBuffer * + CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, QT3DSU32 stride = 0, + NVConstDataRef<QT3DSU8> bufferData = NVConstDataRef<QT3DSU8>()) = 0; + virtual NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) = 0; + + virtual NVRenderIndexBuffer * + CreateIndexBuffer(NVRenderBufferUsageType::Enum usageType, + NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef<QT3DSU8> bufferData = NVConstDataRef<QT3DSU8>()) = 0; + virtual NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) = 0; + + virtual NVRenderConstantBuffer * + CreateConstantBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) = 0; + virtual NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) = 0; + + virtual NVRenderStorageBuffer * + CreateStorageBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer) = 0; + virtual NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) = 0; + + virtual NVRenderAtomicCounterBuffer * + CreateAtomicCounterBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) = 0; + virtual NVRenderAtomicCounterBuffer * + GetAtomicCounterBuffer(CRegisteredString bufferName) = 0; + virtual NVRenderAtomicCounterBuffer * + GetAtomicCounterBufferByParam(CRegisteredString paramName) = 0; + + virtual NVRenderDrawIndirectBuffer * + CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) = 0; + virtual NVRenderDrawIndirectBuffer *GetDrawIndirectBuffer( + NVRenderBackend::NVRenderBackendBufferObject implementationHandle) = 0; + + virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0; + + virtual NVRenderOcclusionQuery *CreateOcclusionQuery() = 0; + virtual NVRenderTimerQuery *CreateTimerQuery() = 0; + virtual NVRenderSync *CreateSync() = 0; + + virtual NVRenderTexture2D *CreateTexture2D() = 0; + virtual NVRenderTexture2D *GetTexture2D(const void *implementationHandle) = 0; + virtual NVRenderBackend *GetBackend() = 0; + + virtual NVRenderTexture2DArray *CreateTexture2DArray() = 0; + + virtual NVRenderTextureCube *CreateTextureCube() = 0; + + virtual NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) = 0; + + virtual NVRenderRenderBuffer * + CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width, + QT3DSU32 height) = 0; + virtual NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) = 0; + // Create a new frame buffer and set the current render target to that frame buffer. + virtual NVRenderFrameBuffer *CreateFrameBuffer() = 0; + virtual NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) = 0; + + virtual NVRenderAttribLayout * + CreateAttributeLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) = 0; + + virtual NVRenderInputAssembler * + CreateInputAssembler(NVRenderAttribLayout *attribLayout, + NVConstDataRef<NVRenderVertexBuffer *> buffers, + const NVRenderIndexBuffer *indexBuffer, NVConstDataRef<QT3DSU32> strides, + NVConstDataRef<QT3DSU32> offsets, + NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles, + QT3DSU32 patchVertexCount = 1) = 0; + virtual void SetInputAssembler(NVRenderInputAssembler *inputAssembler) = 0; + + virtual NVRenderVertFragCompilationResult CompileSource( + const char *shaderName, NVConstDataRef<QT3DSI8> vertShader, + NVConstDataRef<QT3DSI8> fragShader, + NVConstDataRef<QT3DSI8> tessControlShaderSource = NVConstDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> tessEvaluationShaderSource = NVConstDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>(), + bool separateProgram = false, + NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, + bool binaryProgram = false) = 0; + + // You must figure out inVertLen and inFragLen yourself, this object doesn't do that. + NVRenderVertFragCompilationResult + CompileSource(const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, + const char *fragShader, QT3DSU32 inFragLen, const char * = NULL, + QT3DSU32 inTCLen = 0, const char *tessEvaluationShaderSource = NULL, + QT3DSU32 inTELen = 0, const char *geometryShaderSource = NULL, QT3DSU32 inGSLen = 0, + bool separableProgram = false); + + virtual NVRenderVertFragCompilationResult + CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, + NVDataRef<QT3DSI8> vertShader, NVDataRef<QT3DSI8> fragShader, + NVDataRef<QT3DSI8> tessControlShaderSource = NVDataRef<QT3DSI8>(), + NVDataRef<QT3DSI8> tessEvaluationShaderSource = NVDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>()) = 0; + + virtual NVRenderVertFragCompilationResult + CompileComputeSource(const char *shaderName, NVConstDataRef<QT3DSI8> computeShaderSource) = 0; + + virtual NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) = 0; + + virtual NVRenderProgramPipeline *CreateProgramPipeline() = 0; + + virtual NVRenderPathSpecification *CreatePathSpecification() = 0; + virtual NVRenderPathRender *CreatePathRender(size_t range = 1) = 0; + virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0; + virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0; + virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0; + virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) = 0; + + virtual NVRenderPathFontSpecification * + CreatePathFontSpecification(CRegisteredString fontName) = 0; + virtual NVRenderPathFontItem *CreatePathFontItem() = 0; + + // Specific setters for the guaranteed-to-exist context properties to set them as fast as + // possible. + // Note that this bypasses the property manage so push/pop will have no effect (unless you + // set these already + // once after a push using the property manager. + virtual void SetClearColor(QT3DSVec4 inClearColor) = 0; + virtual QT3DSVec4 GetClearColor() const = 0; + + virtual void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) = 0; + virtual NVRenderBlendFunctionArgument GetBlendFunction() const = 0; + + virtual void SetBlendEquation(NVRenderBlendEquationArgument inEquations) = 0; + virtual NVRenderBlendEquationArgument GetBlendEquation() const = 0; + + virtual void SetCullingEnabled(bool inEnabled) = 0; + virtual bool IsCullingEnabled() const = 0; + + virtual void SetDepthFunction(NVRenderBoolOp::Enum inFunction) = 0; + virtual qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const = 0; + + virtual void SetBlendingEnabled(bool inEnabled) = 0; + virtual bool IsBlendingEnabled() const = 0; + + virtual void SetDepthWriteEnabled(bool inEnabled) = 0; + virtual bool IsDepthWriteEnabled() const = 0; + + virtual void SetDepthTestEnabled(bool inEnabled) = 0; + virtual bool IsDepthTestEnabled() const = 0; + + virtual void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) = 0; + virtual void SetStencilTestEnabled(bool inEnabled) = 0; + virtual bool IsStencilTestEnabled() const = 0; + + virtual void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) = 0; + + virtual void SetScissorTestEnabled(bool inEnabled) = 0; + virtual bool IsScissorTestEnabled() const = 0; + + virtual void SetScissorRect(NVRenderRect inRect) = 0; + virtual NVRenderRect GetScissorRect() const = 0; + + virtual void SetViewport(NVRenderRect inViewport) = 0; + virtual NVRenderRect GetViewport() const = 0; + + virtual void SetColorWritesEnabled(bool inEnabled) = 0; + virtual bool IsColorWritesEnabled() const = 0; + + virtual void SetMultisampleEnabled(bool inEnabled) = 0; + virtual bool IsMultisampleEnabled() const = 0; + + // Used during layer rendering because we can't set the *actual* viewport to what it should + // be due to hardware problems. + // Set during begin render. + static QT3DSMat44 + ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection, + const NVRenderRectF &inViewport, + const NVRenderRectF &inVirtualViewport); + + virtual void SetRenderTarget(NVRenderFrameBuffer *inBuffer) = 0; + virtual void SetReadTarget(NVRenderFrameBuffer *inBuffer) = 0; + virtual NVRenderFrameBuffer *GetRenderTarget() const = 0; + + virtual void SetActiveShader(NVRenderShaderProgram *inShader) = 0; + virtual NVRenderShaderProgram *GetActiveShader() const = 0; + + virtual void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) = 0; + virtual NVRenderProgramPipeline *GetActiveProgramPipeline() const = 0; + + virtual void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0; + + // Push the entire set of properties. + virtual void PushPropertySet() = 0; + // Pop the entire set of properties, potentially forcing the values + // to opengl. Will set the hardware state to whatever at the time of push. + virtual void PopPropertySet(bool inForceSetProperties) = 0; + + // Ensure the hardware state matches the state we expect. + virtual void ResetBlendState() = 0; + + // Draw buffers are what the system will render to.. Applies to the current render context. + //-1 means none, else the integer is assumed to be an index past the draw buffer index. + // This applies only to the currently bound framebuffer. + virtual void SetDrawBuffers(NVConstDataRef<QT3DSI32> inDrawBufferSet) = 0; + virtual void SetReadBuffer(NVReadFaces::Enum inReadFace) = 0; + + virtual void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat, + NVDataRef<QT3DSU8> inWriteBuffer) = 0; + + // Return the property manager for this render context + // virtual NVRenderPropertyManager& GetPropertyManager() = 0; + // Clear the current render target + virtual void Clear(NVRenderClearFlags flags) = 0; + // Clear this framebuffer without changing the active frame buffer + virtual void Clear(NVRenderFrameBuffer &framebuffer, NVRenderClearFlags flags) = 0; + // copy framebuffer content between read target and render target + virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) = 0; + + // Render, applying these immediate property values just before render. The hardware + // properties are tracked for push/pop + // but the shader properties are just set on the active shader *after* the hardware + // properties have been set. The shader properties are not tracked for push/pop. + // This call is meant to come directly before each draw call to setup the last bit of state + // before the draw operation. Note that there isn't another way to set the immedate + // property values for a given shader because it isn't clear which shader is active + // when the properties are getting set. + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override = 0; + + /** + * @brief Draw the current active vertex buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] indirect Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) = 0; + + virtual NVFoundationBase &GetFoundation() = 0; + virtual qt3ds::foundation::IStringTable &GetStringTable() = 0; + virtual NVAllocatorCallback &GetAllocator() = 0; + + virtual QSurfaceFormat format() const = 0; + + virtual void resetStates() = 0; + + static NVRenderContext &CreateGL(NVFoundationBase &foundation, IStringTable &inStringTable, + const QSurfaceFormat &format); + + static NVRenderContext &CreateNULL(NVFoundationBase &foundation, + IStringTable &inStringTable); + }; + + // Now for scoped property access. + template <typename TDataType> + struct NVRenderContextScopedProperty + : public NVRenderGenericScopedProperty<NVRenderContext, TDataType> + { + typedef typename NVRenderGenericScopedProperty<NVRenderContext, TDataType>::TGetter TGetter; + typedef typename NVRenderGenericScopedProperty<NVRenderContext, TDataType>::TSetter TSetter; + NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter) + : NVRenderGenericScopedProperty<NVRenderContext, TDataType>(ctx, getter, setter) + { + } + NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter, + const TDataType &inNewValue) + : NVRenderGenericScopedProperty<NVRenderContext, TDataType>(ctx, getter, setter, + inNewValue) + { + } + }; + +/** + * A Render Context implementation class + * + */ + +#define ITERATE_HARDWARE_CONTEXT_PROPERTIES \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(RenderTarget, FrameBuffer) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveShader, ActiveShader) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveProgramPipeline, ActiveProgramPipeline) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(InputAssembler, InputAssembler) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendFunction, BlendFunction) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(CullingEnabled, CullingEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthFunction, DepthFunction) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendingEnabled, BlendingEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthWriteEnabled, DepthWriteEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthTestEnabled, DepthTestEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(StencilTestEnabled, StencilTestEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorTestEnabled, ScissorTestEnabled) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorRect, ScissorRect) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(Viewport, Viewport) \ + HANDLE_CONTEXT_HARDWARE_PROPERTY(ClearColor, ClearColor) + + // forward declarations + + class NVRenderContextImpl : public NVRenderContext, public NoCopy + { + public: + // these variables represent the current hardware state of the render context. + SNVGLHardPropertyContext m_HardwarePropertyContext; + + private: + NVScopedRefCounted<NVRenderBackend> m_backend; ///< pointer to our render backend + NVRenderContextDirtyFlags m_DirtyFlags; ///< context dirty flags + + NVRenderBackend::NVRenderBackendRenderTargetObject + m_DefaultOffscreenRenderTarget; ///< this is a special target set from outside if we + ///never render to a window directly (GL only) + QT3DSI32 m_DephBits; ///< this is the depth bits count of the default window render target + QT3DSI32 m_StencilBits; ///< this is the stencil bits count of the default window render target + + protected: + volatile QT3DSI32 mRefCount; + NVFoundationBase &m_Foundation; + qt3ds::foundation::IStringTable &m_StringTable; + + nvhash_map<const void *, NVRenderVertexBuffer *> m_VertToImpMap; + nvhash_map<const void *, NVRenderIndexBuffer *> m_IndexToImpMap; + TContextConstantBufferMap m_ConstantToImpMap; + TContextStorageBufferMap m_StorageToImpMap; + TContextAtomicCounterBufferMap m_AtomicCounterToImpMap; + TContextDrawIndirectBufferMap m_DrawIndirectToImpMap; + TContextDepthStencilStateMap m_DepthStencilStateToImpMap; + TContextRasterizerStateMap m_RasterizerStateToImpMap; + TContextPathFontSpecificationMap m_PathFontSpecToImpMap; + + nvhash_map<const void *, NVRenderTexture2D *> m_Tex2DToImpMap; + TContextTex2DArrayToImpMap m_Tex2DArrayToImpMap; + TContextTexCubeToImpMap m_TexCubeToImpMap; + TContextImage2DToImpMap m_Image2DtoImpMap; + nvhash_map<const void *, NVRenderShaderProgram *> m_ShaderToImpMap; + nvhash_map<const void *, NVRenderRenderBuffer *> m_RenderBufferToImpMap; + nvhash_map<const void *, NVRenderFrameBuffer *> m_FrameBufferToImpMap; + QT3DSU32 m_MaxTextureUnits; + QT3DSU32 m_NextTextureUnit; + QT3DSU32 m_MaxConstantBufferUnits; + QT3DSU32 m_NextConstantBufferUnit; + + nvvector<SNVGLHardPropertyContext> m_PropertyStack; + + void DoSetClearColor(QT3DSVec4 inClearColor) + { + m_HardwarePropertyContext.m_ClearColor = inClearColor; + m_backend->SetClearColor(&inClearColor); + } + + void DoSetBlendFunction(NVRenderBlendFunctionArgument inFunctions) + { + QT3DSI32_4 values; + m_HardwarePropertyContext.m_BlendFunction = inFunctions; + + m_backend->SetBlendFunc(inFunctions); + } + + void DoSetBlendEquation(NVRenderBlendEquationArgument inEquations) + { + QT3DSI32_4 values; + m_HardwarePropertyContext.m_BlendEquation = inEquations; + + m_backend->SetBlendEquation(inEquations); + } + + void DoSetCullingEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_CullingEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::CullFace); + } + + void DoSetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) + { + m_HardwarePropertyContext.m_DepthFunction = inFunction; + m_backend->SetDepthFunc(inFunction); + } + + void DoSetBlendingEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_BlendingEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::Blend); + } + + void DoSetColorWritesEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_ColorWritesEnabled = inEnabled; + m_backend->SetColorWrites(inEnabled, inEnabled, inEnabled, inEnabled); + } + + void DoSetMultisampleEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_MultisampleEnabled = inEnabled; + m_backend->SetMultisample(inEnabled); + } + + void DoSetDepthWriteEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled; + m_backend->SetDepthWrite(inEnabled); + } + + void DoSetDepthTestEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_DepthTestEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::DepthTest); + } + + void DoSetStencilTestEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_StencilTestEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::StencilTest); + } + + void DoSetScissorTestEnabled(bool inEnabled) + { + m_HardwarePropertyContext.m_ScissorTestEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::ScissorTest); + } + + void DoSetScissorRect(NVRenderRect inRect) + { + m_HardwarePropertyContext.m_ScissorRect = inRect; + m_backend->SetScissorRect(inRect); + } + + void DoSetViewport(NVRenderRect inViewport) + { + m_HardwarePropertyContext.m_Viewport = inViewport; + m_backend->SetViewportRect(inViewport); + } + + // Circular dependencies between shader constants and shader programs preclude + // implementation in header + void DoSetActiveShader(NVRenderShaderProgram *inShader); + void DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline); + + void DoSetInputAssembler(NVRenderInputAssembler *inAssembler) + { + m_HardwarePropertyContext.m_InputAssembler = inAssembler; + m_DirtyFlags |= NVRenderContextDirtyValues::InputAssembler; + } + + void DoSetRenderTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer) + m_backend->SetRenderTarget(inBuffer->GetFrameBuffertHandle()); + else + m_backend->SetRenderTarget(m_DefaultOffscreenRenderTarget); + + m_HardwarePropertyContext.m_FrameBuffer = inBuffer; + } + + void DoSetReadTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer) + m_backend->SetReadTarget(inBuffer->GetFrameBuffertHandle()); + else + m_backend->SetReadTarget(NVRenderBackend::NVRenderBackendRenderTargetObject(NULL)); + } + + bool BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler, + NVRenderShaderProgram *shader); + bool ApplyPreDrawProperties(); + void OnPostDraw(); + + public: + NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend, + IStringTable &inStrTable); + virtual ~NVRenderContextImpl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation); + + NVRenderBackend *GetBackend() override { return m_backend; } + + void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) override; + + const char *GetShadingLanguageVersion() override + { + return m_backend->GetShadingLanguageVersion(); + } + + NVRenderContextType GetRenderContextType() const override + { + return m_backend->GetRenderContextType(); + } + + QT3DSU32 GetDepthBits() const override + { + // only query this if a framebuffer is bound + if (m_HardwarePropertyContext.m_FrameBuffer) + return m_backend->GetDepthBits(); + else + return m_DephBits; + } + + QT3DSU32 GetStencilBits() const override + { + // only query this if a framebuffer is bound + if (m_HardwarePropertyContext.m_FrameBuffer) + return m_backend->GetStencilBits(); + else + return m_StencilBits; + } + + bool GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const override + { + return m_backend->GetRenderBackendCap(inCap); + } + + bool AreMultisampleTexturesSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::MsTexture); + } + + bool GetConstantBufferSupport() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ConstantBuffer); + } + + bool AreDXTImagesSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DxtImages); + } + + bool IsDepthStencilSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DepthStencilTexture); + } + + bool IsFpRenderTargetSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::FpRenderTarget); + } + + bool IsTessellationSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Tessellation); + } + + bool IsGeometryStageSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Geometry); + } + + bool IsComputeSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Compute); + } + + bool IsSampleQuerySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::SampleQuery); + } + + bool IsTimerQuerySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TimerQuery); + } + + bool IsCommandSyncSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::CommandSync); + } + bool IsTextureArraySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureArray); + } + bool IsStorageBufferSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StorageBuffer); + } + bool IsAtomicCounterBufferSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AtomicCounterBuffer); + } + bool IsShaderImageLoadStoreSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ShaderImageLoadStore); + } + bool IsProgramPipelineSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ProgramPipeline); + } + bool IsPathRenderingSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::PathRendering); + } + // Are blend modes really supported in HW? + bool IsAdvancedBlendHwSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlend); + } + bool IsAdvancedBlendHwSupportedKHR() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlendKHR); + } + bool IsBlendCoherencySupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::BlendCoherency); + } + bool IsStandardDerivativesSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StandardDerivatives); + } + bool IsTextureLodSupported() const override + { + return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureLod); + } + + void SetDefaultRenderTarget(QT3DSU64 targetID) override + { + m_DefaultOffscreenRenderTarget = + (NVRenderBackend::NVRenderBackendRenderTargetObject)targetID; + } + + void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) override { m_DephBits = depthBits; } + + virtual NVRenderDepthStencilState * + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) override; + void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) override; + virtual void StateDestroyed(NVRenderDepthStencilState &state); + + NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) override; + void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) override; + virtual void StateDestroyed(NVRenderRasterizerState &state); + + NVRenderVertexBuffer *CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, + size_t size, QT3DSU32 stride, + NVConstDataRef<QT3DSU8> bufferData) override; + NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) override; + virtual void BufferDestroyed(NVRenderVertexBuffer &buffer); + + virtual NVRenderIndexBuffer * + CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, + qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) override; + NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) override; + virtual void BufferDestroyed(NVRenderIndexBuffer &buffer); + + virtual NVRenderConstantBuffer * + CreateConstantBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) override; + NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) override; + virtual void BufferDestroyed(NVRenderConstantBuffer &buffer); + + virtual QT3DSU32 GetNextConstantBufferUnit(); + + virtual NVRenderStorageBuffer * + CreateStorageBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer) override; + NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) override; + virtual void BufferDestroyed(NVRenderStorageBuffer &buffer); + + virtual NVRenderAtomicCounterBuffer * + CreateAtomicCounterBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) override; + NVRenderAtomicCounterBuffer *GetAtomicCounterBuffer(CRegisteredString bufferName) override; + virtual NVRenderAtomicCounterBuffer * + GetAtomicCounterBufferByParam(CRegisteredString paramName) override; + virtual void BufferDestroyed(NVRenderAtomicCounterBuffer &buffer); + + virtual NVRenderDrawIndirectBuffer * + CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) override; + virtual NVRenderDrawIndirectBuffer * + GetDrawIndirectBuffer(NVRenderBackend::NVRenderBackendBufferObject implementationHandle) override; + virtual void BufferDestroyed(NVRenderDrawIndirectBuffer &buffer); + + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + + NVRenderOcclusionQuery *CreateOcclusionQuery() override; + NVRenderTimerQuery *CreateTimerQuery() override; + NVRenderSync *CreateSync() override; + + NVRenderTexture2D *CreateTexture2D() override; + NVRenderTexture2D *GetTexture2D(const void *implementationHandle) override; + virtual void TextureDestroyed(NVRenderTexture2D &buffer); + + NVRenderTexture2DArray *CreateTexture2DArray() override; + virtual void TextureDestroyed(NVRenderTexture2DArray &buffer); + + NVRenderTextureCube *CreateTextureCube() override; + virtual void TextureDestroyed(NVRenderTextureCube &buffer); + + virtual QT3DSU32 GetNextTextureUnit(); + + NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) override; + virtual void ImageDestroyed(NVRenderImage2D &buffer); + + virtual NVRenderRenderBuffer * + CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width, + QT3DSU32 height) override; + NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) override; + virtual void RenderBufferDestroyed(NVRenderRenderBuffer &buffer); + + NVRenderFrameBuffer *CreateFrameBuffer() override; + NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) override; + virtual void FrameBufferDestroyed(NVRenderFrameBuffer &fb); + + virtual NVRenderAttribLayout * + CreateAttributeLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) override; + NVRenderInputAssembler *CreateInputAssembler( + NVRenderAttribLayout *attribLayout, NVConstDataRef<NVRenderVertexBuffer *> buffers, + const NVRenderIndexBuffer *indexBuffer, NVConstDataRef<QT3DSU32> strides, + NVConstDataRef<QT3DSU32> offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) override; + void SetInputAssembler(NVRenderInputAssembler *inputAssembler) override; + + NVRenderVertFragCompilationResult CompileSource( + const char *shaderName, NVConstDataRef<QT3DSI8> vertShader, + NVConstDataRef<QT3DSI8> fragShader, + NVConstDataRef<QT3DSI8> tessControlShaderSource = NVConstDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> tessEvaluationShaderSource = NVConstDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>(), + bool separateProgram = false, + NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, + bool binaryProgram = false) override; + + virtual NVRenderVertFragCompilationResult + CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, + NVDataRef<QT3DSI8> vertShader, NVDataRef<QT3DSI8> fragShader, + NVDataRef<QT3DSI8> tessControlShaderSource = NVDataRef<QT3DSI8>(), + NVDataRef<QT3DSI8> tessEvaluationShaderSource = NVDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>()) override; + + virtual NVRenderVertFragCompilationResult + CompileComputeSource(const char *shaderName, NVConstDataRef<QT3DSI8> computeShaderSource) override; + + NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) override; + virtual void ShaderDestroyed(NVRenderShaderProgram &shader); + + NVRenderProgramPipeline *CreateProgramPipeline() override; + NVRenderPathSpecification *CreatePathSpecification() override; + NVRenderPathRender *CreatePathRender(size_t range = 1) override; + void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override; + void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override; + void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override; + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) override; + + virtual NVRenderPathFontSpecification * + CreatePathFontSpecification(CRegisteredString fontName) override; + virtual void ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec); + NVRenderPathFontItem *CreatePathFontItem() override; + + void SetClearColor(QT3DSVec4 inClearColor) override; + QT3DSVec4 GetClearColor() const override { return m_HardwarePropertyContext.m_ClearColor; } + + void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) override; + NVRenderBlendFunctionArgument GetBlendFunction() const override + { + return m_HardwarePropertyContext.m_BlendFunction; + } + + void SetBlendEquation(NVRenderBlendEquationArgument inEquations) override; + NVRenderBlendEquationArgument GetBlendEquation() const override + { + return m_HardwarePropertyContext.m_BlendEquation; + }; + + void SetCullingEnabled(bool inEnabled) override; + bool IsCullingEnabled() const override { return m_HardwarePropertyContext.m_CullingEnabled; } + + void SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) override; + qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const override + { + return m_HardwarePropertyContext.m_DepthFunction; + } + + void SetBlendingEnabled(bool inEnabled) override; + bool IsBlendingEnabled() const override + { + return m_HardwarePropertyContext.m_BlendingEnabled; + } + + void SetDepthWriteEnabled(bool inEnabled) override; + bool IsDepthWriteEnabled() const override + { + return m_HardwarePropertyContext.m_DepthWriteEnabled; + } + void SetDepthTestEnabled(bool inEnabled) override; + bool IsDepthTestEnabled() const override + { + return m_HardwarePropertyContext.m_DepthTestEnabled; + } + + void SetStencilTestEnabled(bool inEnabled) override; + bool IsStencilTestEnabled() const override + { + return m_HardwarePropertyContext.m_StencilTestEnabled; + } + + void SetScissorTestEnabled(bool inEnabled) override; + bool IsScissorTestEnabled() const override + { + return m_HardwarePropertyContext.m_ScissorTestEnabled; + } + void SetScissorRect(NVRenderRect inRect) override; + NVRenderRect GetScissorRect() const override + { + return m_HardwarePropertyContext.m_ScissorRect; + } + + void SetViewport(NVRenderRect inViewport) override; + NVRenderRect GetViewport() const override { return m_HardwarePropertyContext.m_Viewport; } + + void SetColorWritesEnabled(bool inEnabled) override; + bool IsColorWritesEnabled() const override + { + return m_HardwarePropertyContext.m_ColorWritesEnabled; + } + + void SetMultisampleEnabled(bool inEnabled) override; + bool IsMultisampleEnabled() const override + { + return m_HardwarePropertyContext.m_MultisampleEnabled; + } + + void SetActiveShader(NVRenderShaderProgram *inShader) override; + NVRenderShaderProgram *GetActiveShader() const override + { + return m_HardwarePropertyContext.m_ActiveShader; + } + + void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) override; + NVRenderProgramPipeline *GetActiveProgramPipeline() const override + { + return m_HardwarePropertyContext.m_ActiveProgramPipeline; + } + + void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + + void SetDrawBuffers(NVConstDataRef<QT3DSI32> inDrawBufferSet) override; + void SetReadBuffer(NVReadFaces::Enum inReadFace) override; + + void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat, + NVDataRef<QT3DSU8> inWriteBuffer) override; + + void SetRenderTarget(NVRenderFrameBuffer *inBuffer) override; + void SetReadTarget(NVRenderFrameBuffer *inBuffer) override; + NVRenderFrameBuffer *GetRenderTarget() const override + { + return m_HardwarePropertyContext.m_FrameBuffer; + } + + void ResetBlendState() override; + + // Push the entire set of properties. + void PushPropertySet() override { m_PropertyStack.push_back(m_HardwarePropertyContext); } + + // Pop the entire set of properties, potentially forcing the values + // to opengl. + void PopPropertySet(bool inForceSetProperties) override; + + // clear current bound render target + void Clear(NVRenderClearFlags flags) override; + // clear passed in rendertarget + void Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) override; + + // copy framebuffer content between read target and render target + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override; + void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) override; + + NVFoundationBase &GetFoundation() override { return m_Foundation; } + qt3ds::foundation::IStringTable &GetStringTable() override { return m_StringTable; } + NVAllocatorCallback &GetAllocator() override { return m_Foundation.getAllocator(); } + QSurfaceFormat format() const override + { + return m_backend->format(); + } + virtual void resetStates() + { + PushPropertySet(); + PopPropertySet(true); + } + }; +} +} +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp new file mode 100644 index 00000000..b00b0af0 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderDataBuffer.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderDataBuffer::NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, + size_t size, NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_UsageType(usageType) + , m_BindFlags(bindFlags) + , m_BufferData(data) + , m_BufferCapacity(data.size()) + , m_BufferSize(size) + , m_OwnsData(false) + , m_Mapped(false) + { + m_BufferHandle = + m_Backend->CreateBuffer(size, bindFlags, usageType, (const void *)m_BufferData.begin()); + } + + NVRenderDataBuffer::~NVRenderDataBuffer() + { + if (m_BufferHandle) { + m_Backend->ReleaseBuffer(m_BufferHandle); + } + m_BufferHandle = 0; + + releaseMemory(); + } + + void NVRenderDataBuffer::releaseMemory() + { + // chekc if we should release memory + if (m_BufferData.size() && m_OwnsData) { + m_Foundation.getAllocator().deallocate(m_BufferData.begin()); + } + + m_BufferData = NVDataRef<QT3DSU8>(); + m_OwnsData = false; + } + + NVDataRef<QT3DSU8> NVRenderDataBuffer::MapBuffer() + { + // don't map twice + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer"); + QT3DS_ASSERT(false); + } + + QT3DSU8 *pData = (QT3DSU8 *)m_Backend->MapBuffer( + m_BufferHandle, m_BindFlags, 0, m_BufferSize, + NVRenderBufferAccessFlags(NVRenderBufferAccessTypeValues::Read + | NVRenderBufferAccessTypeValues::Write)); + + releaseMemory(); + m_BufferData = toDataRef(const_cast<QT3DSU8 *>(pData), (QT3DSU32)m_BufferSize); + m_BufferCapacity = (QT3DSU32)m_BufferSize; + m_OwnsData = false; + + // currently we return a reference to the system memory + m_Mapped = true; + return m_BufferData; + } + + NVDataRef<QT3DSU8> NVRenderDataBuffer::MapBufferRange(size_t offset, size_t size, + NVRenderBufferAccessFlags flags) + { + // don't map twice + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer"); + QT3DS_ASSERT(false); + } + // don't map out of range + if ((m_BufferSize < (offset + size)) || (size == 0)) { + qCCritical(INVALID_OPERATION, "Attempting to map out of buffer range"); + QT3DS_ASSERT(false); + } + + QT3DSU8 *pData = + (QT3DSU8 *)m_Backend->MapBuffer(m_BufferHandle, m_BindFlags, offset, size, flags); + + releaseMemory(); + m_BufferData = toDataRef(const_cast<QT3DSU8 *>(pData), (QT3DSU32)size); + m_BufferCapacity = (QT3DSU32)size; + m_OwnsData = false; + + // currently we return a reference to the system memory + m_Mapped = true; + return m_BufferData; + } + + void NVRenderDataBuffer::UnmapBuffer() + { + if (m_Mapped) { + // update hardware + m_Backend->UnmapBuffer(m_BufferHandle, m_BindFlags); + m_Mapped = false; + releaseMemory(); + } + } + + void NVRenderDataBuffer::UpdateBuffer(NVConstDataRef<QT3DSU8> data, bool ownsMemory) + { + // don't update a mapped buffer + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to update a mapped buffer"); + QT3DS_ASSERT(false); + } + + releaseMemory(); + + m_BufferData = toDataRef(const_cast<QT3DSU8 *>(data.begin()), data.size()); + m_BufferCapacity = data.mSize; + m_OwnsData = ownsMemory; + // update hardware + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferCapacity, m_UsageType, + (const void *)m_BufferData.begin()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h new file mode 100644 index 00000000..579e2361 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DATA_BUFFER_H +#define QT3DS_RENDER_DATA_BUFFER_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + class NVRenderBackend; + + ///< Base class + class NVRenderDataBuffer : public NVRefCounted, public NVRenderImplemented + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBufferUsageType::Enum m_UsageType; ///< usage type + NVRenderBufferBindFlags m_BindFlags; ///< bind flags + NVDataRef<QT3DSU8> m_BufferData; ///< buffer data pointer + QT3DSU32 m_BufferCapacity; ///< size of internal backup buffer (m_BufferData) + size_t m_BufferSize; ///< size of buffer + bool m_OwnsData; ///< true when we own m_BufferData + bool m_Mapped; ///< true when locked for reading or writing to m_BufferData + NVRenderBackend::NVRenderBackendBufferObject m_BufferHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return No return. + */ + NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data); + + virtual ~NVRenderDataBuffer(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + /** + * @brief Get Buffer usage type + * + * @return Return usage tyoe + */ + virtual NVRenderBufferUsageType::Enum GetBufferUsageType() const + { + return m_UsageType; + } + + /** + * @brief Get Buffer usage type + * Should be overwritten + * + * @return Return usage tyoe + */ + virtual NVRenderBufferBindFlags GetBufferBindings() const { return m_BindFlags; } + + /** + * @brief Return buffer size in byte + * + * @return Return size + */ + virtual QT3DSU32 Size() { return (QT3DSU32)m_BufferSize; } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + virtual void Bind() = 0; + + /** + * @brief Map the buffer + * Mapped buffers cannot be used for rendering + * + * @return Return mapped pointer to data + */ + virtual NVDataRef<QT3DSU8> MapBuffer(); + + /** + * @brief Map a range of a buffer + * Mapped buffers cannot be used for rendering + * + * @param[in] offset Offset in bytes into the buffer + * @param[in] size Range in bytes to map + * @param[in] flags Buffer access flags + * + * @return Return mapped pointer to data + */ + virtual NVDataRef<QT3DSU8> MapBufferRange(size_t offset, size_t size, + NVRenderBufferAccessFlags flags); + + /** + * @brief Unmap the buffer + * This updates the data to the hardware + * + * @return no return + */ + virtual void UnmapBuffer(); + + /** + * @brief constructor + * + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * @param[in] ownsMemory If true data will be owned by this object and can therefore be + * released + * + * @return No return. + */ + virtual void UpdateBuffer(NVConstDataRef<QT3DSU8> data, bool ownsMemory = false); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const = 0; + + // this will be obsolete + const void *GetImplementationHandle() const override = 0; + + private: + void releaseMemory(); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp new file mode 100644 index 00000000..3ea47e23 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderDepthStencilState.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderDepthStencilState::NVRenderDepthStencilState( + NVRenderContextImpl &context, NVFoundationBase &fnd, bool enableDepth, bool depthMask, + NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_DepthEnabled(enableDepth) + , m_DepthMask(depthMask) + , m_DepthFunc(depthFunc) + , m_StencilEnabled(enableStencil) + , m_StencilFuncFront(stencilFuncFront) + , m_StencilFuncBack(stencilFuncBack) + , m_DepthStencilOpFront(depthStencilOpFront) + , m_DepthStencilOpBack(depthStencilOpBack) + { + // create backend handle + m_StateHandle = m_Backend->CreateDepthStencilState( + enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack, + depthStencilOpFront, depthStencilOpBack); + } + + NVRenderDepthStencilState::~NVRenderDepthStencilState() + { + if (m_StateHandle) { + m_Context.StateDestroyed(*this); + m_Backend->ReleaseDepthStencilState(m_StateHandle); + } + } + + NVRenderDepthStencilState * + NVRenderDepthStencilState::Create(NVRenderContextImpl &context, bool enableDepth, + bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderDepthStencilState)( + context, context.GetFoundation(), enableDepth, depthMask, depthFunc, enableStencil, + stencilFuncFront, stencilFuncBack, depthStencilOpFront, depthStencilOpBack); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h new file mode 100644 index 00000000..e6b31981 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_DEPTH_STENCIL_STATE_H +#define QT3DS_RENDER_DEPTH_STENCIL_STATE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + + // currently this handles only stencil state + class NVRenderDepthStencilState : public NVRefCounted + { + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendDepthStencilStateObject + m_StateHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] enableDepth enable depth test + * @param[in] depthMask enable depth writes + * @param[in] depthFunc depth compare function + * @param[in] enableStencil enable stencil test + * @param[in] stencilFuncFront stencil setup front faces + * @param[in] stencilFuncBack stencil setup back faces + * @param[in] depthStencilOpFront depth/stencil operations front faces + * @param[in] depthStencilOpBack depth/stencil operations back faces + * + * @return No return. + */ + NVRenderDepthStencilState(NVRenderContextImpl &context, NVFoundationBase &fnd, + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack); + + virtual ~NVRenderDepthStencilState(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + ///< various get functions + const NVRenderStencilFunctionArgument GetStencilFunc(NVRenderFaces::Enum face) const + { + return (face == NVRenderFaces::Back) ? m_StencilFuncBack : m_StencilFuncFront; + } + const NVRenderStencilOperationArgument GetStencilOp(NVRenderFaces::Enum face) const + { + return (face == NVRenderFaces::Back) ? m_DepthStencilOpBack : m_DepthStencilOpFront; + } + NVRenderBoolOp::Enum GetDepthFunc() const { return m_DepthFunc; } + bool GetDepthEnabled() const { return m_DepthEnabled; } + bool GetStencilEnabled() const { return m_StencilEnabled; } + bool GetDepthMask() const { return m_DepthMask; } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendDepthStencilStateObject + GetDepthStencilObjectHandle() + { + return m_StateHandle; + } + + static NVRenderDepthStencilState * + Create(NVRenderContextImpl &context, bool enableDepth, bool depthMask, + NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack); + + private: + bool m_DepthEnabled; ///< depth test enabled + bool m_DepthMask; ///< depth writes enabled + NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func + bool m_StencilEnabled; ///< stencil test enabled + NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup front faces + NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup back faces + NVRenderStencilOperationArgument + m_DepthStencilOpFront; ///< depth stencil operation front faces + NVRenderStencilOperationArgument + m_DepthStencilOpBack; ///< depth stencil operation back faces + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp new file mode 100644 index 00000000..9940003f --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderDrawIndirectBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + NVRenderDrawIndirectBuffer::NVRenderDrawIndirectBuffer(NVRenderContextImpl &context, + size_t size, + NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Draw_Indirect, usageType, data) + , m_Dirty(true) + { + } + + NVRenderDrawIndirectBuffer::~NVRenderDrawIndirectBuffer() { m_Context.BufferDestroyed(*this); } + + void NVRenderDrawIndirectBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderDrawIndirectBuffer::Update() + { + // we only update the buffer if it is dirty and we actually have some data + if (m_Dirty && m_BufferData.size()) { + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, + m_BufferData.begin()); + m_Dirty = false; + } + } + + void NVRenderDrawIndirectBuffer::UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data) + { + // we only update the buffer if we something + if (data.size()) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, + data.begin() + offset); + } + + NVRenderDrawIndirectBuffer * + NVRenderDrawIndirectBuffer::Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderDrawIndirectBuffer *retval = NULL; + + // these are the context flags which do not support this drawing mode + NVRenderContextType noDrawIndirectSupported( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2 | NVRenderContextValues::GL3 + | NVRenderContextValues::GLES3); + NVRenderContextType ctxType = context.GetRenderContextType(); + + if (!(ctxType & noDrawIndirectSupported)) { + QT3DSU32 bufSize = sizeof(NVRenderDrawIndirectBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "DrawIndirectBuffer"); + retval = new (newMem) NVRenderDrawIndirectBuffer( + context, size, usageType, + toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size())); + } else { + QT3DS_ASSERT(false); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h new file mode 100644 index 00000000..81cd59d1 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + + struct DrawArraysIndirectCommand + { + QT3DSU32 count; + QT3DSU32 primCount; + QT3DSU32 first; + QT3DSU32 baseInstance; + }; + + struct DrawElementsIndirectCommand + { + QT3DSU32 count; + QT3DSU32 primCount; + QT3DSU32 firstIndex; + QT3DSU32 baseVertex; + QT3DSU32 baseInstance; + }; + + ///< Constant (uniform) buffer representation + class NVRenderDrawIndirectBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderDrawIndirectBuffer(NVRenderContextImpl &context, size_t size, + NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data); + + ///< destructor + virtual ~NVRenderDrawIndirectBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief update a piece of memory directly within the storage buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 (430) layout which guarantees a specific layout behavior across + *all HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into storage buffer + * @param[in] data pointer to data + * + * @return no return + */ + void UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_BufferHandle); + } + + /** + * @brief create a NVRenderDrawIndirectBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the buffer object or NULL + */ + static NVRenderDrawIndirectBuffer *Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + size_t size, NVConstDataRef<QT3DSU8> bufferData); + + private: + bool m_Dirty; ///< true if buffer is dirty + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawable.h b/src/Runtime/Source/render/Qt3DSRenderDrawable.h new file mode 100644 index 00000000..0f78aacc --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderDrawable.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H +#define QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H +#include "Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + class NVRenderDrawable + { + protected: + virtual ~NVRenderDrawable() {} + + public: + /** + * Draw using this object. + * offset is in num elements, not in number of bytes + * because the various different draw functions differ in what datatype + * offset is (gl drawarrays vs gl drawindexedarras). + */ + virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) = 0; + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp new file mode 100644 index 00000000..e2f31f1b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderFragmentShader.h" + +namespace qt3ds { +namespace render { + + NVRenderFragmentShader::NVRenderFragmentShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateFragmentShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderFragmentShader::~NVRenderFragmentShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseFragmentShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h new file mode 100644 index 00000000..f661605c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_FRAGMENT_SHADER_H +#define QT3DS_RENDER_FRAGMENT_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a fragment shader + class NVRenderFragmentShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderFragmentShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram); + + /// @brief destructor + ~NVRenderFragmentShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendFragmentShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendFragmentShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp new file mode 100644 index 00000000..0ab38428 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp @@ -0,0 +1,300 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSFoundation.h" +#include "render/Qt3DSRenderFrameBuffer.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderFrameBuffer::NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_BufferHandle(NULL) + , m_AttachmentBits(0) + { + m_BufferHandle = m_Backend->CreateRenderTarget(); + QT3DS_ASSERT(m_BufferHandle); + } + + NVRenderFrameBuffer::~NVRenderFrameBuffer() + { + m_Context.FrameBufferDestroyed(*this); + m_Backend->ReleaseRenderTarget(m_BufferHandle); + m_BufferHandle = 0; + m_AttachmentBits = 0; + + // release attachments + QT3DS_FOREACH(idx, (QT3DSU32)NVRenderFrameBufferAttachments::LastAttachment) + { + if ((NVRenderFrameBufferAttachments::Enum)idx + != NVRenderFrameBufferAttachments::DepthStencil + || m_Context.IsDepthStencilSupported()) + releaseAttachment((NVRenderFrameBufferAttachments::Enum)idx); + } + } + + inline void CheckAttachment(NVRenderContext &ctx, + NVRenderFrameBufferAttachments::Enum attachment) + { +#ifdef _DEBUG + QT3DS_ASSERT(attachment != NVRenderFrameBufferAttachments::DepthStencil + || ctx.IsDepthStencilSupported()); +#endif + (void)ctx; + (void)attachment; + } + + NVRenderTextureTargetType::Enum + NVRenderFrameBuffer::releaseAttachment(NVRenderFrameBufferAttachments::Enum idx) + { + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Unknown; + + NVRenderTextureOrRenderBuffer Attach = m_Attachments[idx]; + if (Attach.HasTexture2D()) { + target = (Attach.GetTexture2D()->IsMultisampleTexture()) + ? NVRenderTextureTargetType::Texture2D_MS + : NVRenderTextureTargetType::Texture2D; + Attach.GetTexture2D()->release(); + } else if (Attach.HasTexture2DArray()) { + target = (Attach.GetTexture2DArray()->IsMultisampleTexture()) + ? NVRenderTextureTargetType::Texture2D_MS + : NVRenderTextureTargetType::Texture2D_Array; + Attach.GetTexture2DArray()->release(); + } else if (Attach.HasTextureCube()) { + target = (Attach.GetTextureCube()->IsMultisampleTexture()) + ? NVRenderTextureTargetType::Texture2D_MS + : NVRenderTextureTargetType::TextureCube; + Attach.GetTextureCube()->release(); + } else if (Attach.HasRenderBuffer()) + Attach.GetRenderBuffer()->release(); + + CheckAttachment(m_Context, idx); + m_Attachments[idx] = NVRenderTextureOrRenderBuffer(); + + m_AttachmentBits &= ~(1 << idx); + + return target; + } + + NVRenderTextureOrRenderBuffer + NVRenderFrameBuffer::GetAttachment(NVRenderFrameBufferAttachments::Enum attachment) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return NVRenderTextureOrRenderBuffer(); + } + CheckAttachment(m_Context, attachment); + return m_Attachments[attachment]; + } + + void NVRenderFrameBuffer::Attach(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureTargetType::Enum target) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return; + } + + // early out + // if there is nothing to detach + if (!buffer.HasTexture2D() && !buffer.HasRenderBuffer() && !buffer.HasTexture2DArray() + && !(m_AttachmentBits & (1 << attachment))) + return; + + CheckAttachment(m_Context, attachment); + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + // release previous attachments + NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); + + if (buffer.HasTexture2D()) { + // On the same attachment point there could be a something attached with a different + // target MSAA <--> NoMSAA + if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target) + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTexture2D()->GetTextureObjectHandle(), target); + buffer.GetTexture2D()->addRef(); + m_AttachmentBits |= (1 << attachment); + } else if (buffer.HasTexture2DArray()) { + // On the same attachment point there could be a something attached with a different + // target MSAA <--> NoMSAA + if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target) + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTexture2D()->GetTextureObjectHandle(), target); + buffer.GetTexture2DArray()->addRef(); + m_AttachmentBits |= (1 << attachment); + } else if (buffer.HasRenderBuffer()) { + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetRenderBuffer()->GetRenderBuffertHandle()); + buffer.GetRenderBuffer()->addRef(); + m_AttachmentBits |= (1 << attachment); + } else if (theRelTarget == NVRenderTextureTargetType::Unknown) { + // detach renderbuffer + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendRenderbufferObject(NULL)); + } else { + // detach texture + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + } + m_Attachments[attachment] = buffer; + } + + void NVRenderFrameBuffer::AttachLayer(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer, + QT3DSI32 level) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return; + } + + // This function is only used for attaching a layer + // If texture exists probably something is wrong + if (!buffer.HasTexture2DArray()) { + QT3DS_ASSERT(false); + return; + } + + CheckAttachment(m_Context, attachment); + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + // release previous attachments + NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); + + // On the same attachment point there could be a something attached with a different target + // MSAA <--> NoMSAA + if (theRelTarget != NVRenderTextureTargetType::Unknown + && theRelTarget != NVRenderTextureTargetType::Texture2D_Array) + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTexture2DArray()->GetTextureObjectHandle(), level, + layer); + buffer.GetTexture2DArray()->addRef(); + m_AttachmentBits |= (1 << attachment); + + m_Attachments[attachment] = buffer; + } + + void NVRenderFrameBuffer::AttachFace(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureCubeFaces::Enum face) + { + if (attachment == NVRenderFrameBufferAttachments::Unknown + || attachment > NVRenderFrameBufferAttachments::LastAttachment) { + qCCritical(INVALID_PARAMETER, "Attachment out of range"); + return; + } + + if (face == NVRenderTextureCubeFaces::InvalidFace) { + QT3DS_ASSERT(false); + return; + } + + CheckAttachment(m_Context, attachment); + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + // release previous attachments + NVRenderTextureTargetType::Enum attachTarget = static_cast<NVRenderTextureTargetType::Enum>( + (int)NVRenderTextureTargetType::TextureCube + (int)face); + NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment); + + // If buffer has no texture cube, this call is used to detach faces. + // If release target is not cube, there is something else attached to that + // attachment point, so we want to release that first. E.g (MSAA <--> NoMSAA) + if (theRelTarget == NVRenderTextureTargetType::TextureCube && !buffer.HasTextureCube()) { + theRelTarget = attachTarget; + attachTarget = NVRenderTextureTargetType::Unknown; + } else if (theRelTarget == NVRenderTextureTargetType::TextureCube) { + theRelTarget = NVRenderTextureTargetType::Unknown; + } + if (theRelTarget != NVRenderTextureTargetType::Unknown) { + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + NVRenderBackend::NVRenderBackendTextureObject(NULL), + theRelTarget); + } + + if (attachTarget != NVRenderTextureTargetType::Unknown) { + m_Backend->RenderTargetAttach(m_BufferHandle, attachment, + buffer.GetTextureCube()->GetTextureObjectHandle(), + attachTarget); + buffer.GetTextureCube()->addRef(); + m_AttachmentBits |= (1 << attachment); + } + + m_Attachments[attachment] = buffer; + } + + bool NVRenderFrameBuffer::IsComplete() + { + // Ensure we are the bound framebuffer + m_Context.SetRenderTarget(this); + + return m_Backend->RenderTargetIsValid(m_BufferHandle); + } +} +} + +qt3ds::render::NVRenderFrameBuffer * +qt3ds::render::NVRenderFrameBuffer::Create(NVRenderContextImpl &context) +{ + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderFrameBuffer)(context, context.GetFoundation()); +} diff --git a/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h new file mode 100644 index 00000000..1882a27d --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAssert.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTexture2D; + class NVRenderRenderBuffer; + class NVRenderTexture2DArray; + class NVRenderTextureCube; + + class NVRenderTextureOrRenderBuffer + { + NVRenderTexture2D *m_Texture2D; + NVRenderTexture2DArray *m_Texture2DArray; + NVRenderTextureCube *m_TextureCube; + NVRenderRenderBuffer *m_RenderBuffer; + + public: + NVRenderTextureOrRenderBuffer(NVRenderTexture2D &texture) + : m_Texture2D(&texture) + , m_Texture2DArray(NULL) + , m_TextureCube(NULL) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer(NVRenderRenderBuffer &render) + : m_Texture2D(NULL) + , m_Texture2DArray(NULL) + , m_TextureCube(NULL) + , m_RenderBuffer(&render) + { + } + NVRenderTextureOrRenderBuffer(NVRenderTexture2DArray &textureArray) + : m_Texture2D(NULL) + , m_Texture2DArray(&textureArray) + , m_TextureCube(NULL) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer(NVRenderTextureCube &textureCube) + : m_Texture2D(NULL) + , m_Texture2DArray(NULL) + , m_TextureCube(&textureCube) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer() + : m_Texture2D(NULL) + , m_Texture2DArray(NULL) + , m_TextureCube(NULL) + , m_RenderBuffer(NULL) + { + } + NVRenderTextureOrRenderBuffer(const NVRenderTextureOrRenderBuffer &other) + : m_Texture2D(other.m_Texture2D) + , m_Texture2DArray(other.m_Texture2DArray) + , m_TextureCube(other.m_TextureCube) + , m_RenderBuffer(other.m_RenderBuffer) + { + } + NVRenderTextureOrRenderBuffer &operator=(const NVRenderTextureOrRenderBuffer &other) + { + if (this != &other) { + m_Texture2D = const_cast<NVRenderTexture2D *>(other.m_Texture2D); + m_Texture2DArray = const_cast<NVRenderTexture2DArray *>(other.m_Texture2DArray); + m_RenderBuffer = const_cast<NVRenderRenderBuffer *>(other.m_RenderBuffer); + m_TextureCube = const_cast<NVRenderTextureCube *>(other.m_TextureCube); + } + return *this; + } + + bool HasTexture2D() const { return m_Texture2D != NULL; } + bool HasTexture2DArray() const { return m_Texture2DArray != NULL; } + bool HasTextureCube() const { return m_TextureCube != NULL; } + bool HasRenderBuffer() const { return m_RenderBuffer != NULL; } + + NVRenderTexture2D *GetTexture2D() const + { + QT3DS_ASSERT(HasTexture2D()); + return m_Texture2D; + } + NVRenderTexture2DArray *GetTexture2DArray() const + { + QT3DS_ASSERT(HasTexture2DArray()); + return m_Texture2DArray; + } + NVRenderTextureCube *GetTextureCube() const + { + QT3DS_ASSERT(HasTextureCube()); + return m_TextureCube; + } + NVRenderRenderBuffer *GetRenderBuffer() const + { + QT3DS_ASSERT(HasRenderBuffer()); + return m_RenderBuffer; + } + }; + + class NVRenderFrameBuffer : public NVRefCounted, public NVRenderImplemented + { + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + + NVRenderTextureOrRenderBuffer + m_Attachments[NVRenderFrameBufferAttachments::LastAttachment]; ///< attachments array + NVRenderBackend::NVRenderBackendRenderTargetObject + m_BufferHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd); + + /// destructor + virtual ~NVRenderFrameBuffer(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + /** + * @brief query attachment + * + * + * @return buffer format + */ + virtual NVRenderTextureOrRenderBuffer + GetAttachment(NVRenderFrameBufferAttachments::Enum attachment); + + /** + * @brief Attach a render or texture buffer to a render target + * For texture attachments we use always level 0 + * + * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) + * @param[in] buffer Contains a pointer to the attachment + * @param[in] target Attachment texture target + * + * @return no return + */ + virtual void + Attach(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D); + + /** + * @brief Attach a particular layer of the texture 2D array to a render target + * + * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) + * @param[in] buffer Pointer to the Texture Array which contains the + * layers + * @param[in] layer The index to the layer that will be attached to the + * target + * @param[in] level Mip level of the texture that will be attached + * (default 0) + * + * @return no return + */ + virtual void AttachLayer(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer, + QT3DSI32 level = 0); + + /** + * @brief Attach a particular face of the texture cubemap to a render target + * + * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...) + * @param[in] buffer Pointer to the Texture Array which contains the + * layers + * @param[in] face The face of the cubemap that will be attached to the + * target + * @param[in] level Mip level of the texture that will be attached + * (default 0) + * + * @return no return + */ + virtual void AttachFace(NVRenderFrameBufferAttachments::Enum attachment, + NVRenderTextureOrRenderBuffer buffer, + NVRenderTextureCubeFaces::Enum face); + + /** + * @brief Check that this framebuffer is complete and can be rendered to. + * + * + * @return true if complete + */ + virtual bool IsComplete(); + + /** + * @brief query if framebuffer has any attachment + * + * @return true if any attachment + */ + virtual bool HasAnyAttachment() { return (m_AttachmentBits != 0); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendRenderTargetObject GetFrameBuffertHandle() + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<const void *>(m_BufferHandle); + } + + /** + * @brief static creator function + * + * @param[in] context Pointer to context + * + * @return a pointer to framebuffer object. + */ + static NVRenderFrameBuffer *Create(NVRenderContextImpl &context); + + private: + /** + * @brief releaes an attached object + * + * @return which target we released + */ + NVRenderTextureTargetType::Enum releaseAttachment(NVRenderFrameBufferAttachments::Enum idx); + + QT3DSU32 m_AttachmentBits; ///< holds flags for current attached buffers + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp new file mode 100644 index 00000000..50567287 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderGeometryShader.h" + +namespace qt3ds { +namespace render { + + NVRenderGeometryShader::NVRenderGeometryShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateGeometryShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderGeometryShader::~NVRenderGeometryShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseGeometryShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h new file mode 100644 index 00000000..2a643cfc --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GEOMETRY_SHADER_H +#define QT3DS_RENDER_GEOMETRY_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a vertex shader + class NVRenderGeometryShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderGeometryShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram); + + /// @brief destructor + ~NVRenderGeometryShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendGeometryShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendGeometryShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp b/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp new file mode 100644 index 00000000..e987cc31 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderImageTexture.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderImage2D::NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_Texture2D(inTexture) + , m_TextureUnit(QT3DS_MAX_U32) + , m_AccessType(inAccess) + , m_TextureLevel(0) + { + inTexture->addRef(); + } + + NVRenderImage2D::~NVRenderImage2D() + { + m_Context.ImageDestroyed(*this); + m_Texture2D->release(); + } + + void NVRenderImage2D::SetTextureLevel(QT3DSI32 inLevel) + { + if (m_Texture2D && m_Texture2D->GetNumMipmaps() >= (QT3DSU32)inLevel) { + m_TextureLevel = inLevel; + } + } + + void NVRenderImage2D::Bind(QT3DSU32 unit) + { + if (unit == -1) + m_TextureUnit = m_Context.GetNextTextureUnit(); + else + m_TextureUnit = unit; + + STextureDetails theDetails(m_Texture2D->GetTextureDetails()); + + // note it is the callers responsibility that the texture format is supported by the compute + // shader + m_Backend->BindImageTexture(m_Texture2D->GetTextureObjectHandle(), m_TextureUnit, + m_TextureLevel, false, 0, m_AccessType, theDetails.m_Format); + } + + NVRenderBackend::NVRenderBackendTextureObject NVRenderImage2D::GetTextureObjectHandle() + { + return m_Texture2D->GetTextureObjectHandle(); + } + + NVRenderImage2D *NVRenderImage2D::Create(NVRenderContextImpl &context, + NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) + { + if (inTexture) + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderImage2D)(context, context.GetFoundation(), inTexture, inAccess); + else + return NULL; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderImageTexture.h b/src/Runtime/Source/render/Qt3DSRenderImageTexture.h new file mode 100644 index 00000000..8b3469b0 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderImageTexture.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H +#define QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTexture2D; + + // a wrapper class for NVRenderTexture2D + // to use with compute shaders and load / store image shaders + + class NVRenderImage2D : public NVRefCounted + { + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderTexture2D *m_Texture2D; ///< pointer to texture + QT3DSI32 m_TextureUnit; ///< texture unit this texture should use + NVRenderImageAccessType::Enum + m_AccessType; ///< texture / image access type ( read, write, read_write ) + QT3DSU32 m_TextureLevel; ///< texture level we use for this image + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] inTexture Pointer to a NVRenderTexture2D object + * @param[in] inAccess Image access type ( read, write, read_write ) + * + * @return No return. + */ + NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTexture2D *inTexture, NVRenderImageAccessType::Enum inAccess); + + virtual ~NVRenderImage2D(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Set the access rights within the shader. + * Can be read, write or read_write. + * + * @param[in] inAccess Image access type ( read, write, read_write ) + * + * @return No return. + */ + virtual void SetAccessType(NVRenderImageAccessType::Enum inAccess) + { + m_AccessType = inAccess; + } + + /** + * @brief Set the texture level we use for this image + * + * @param[in] inLevel texture level ( must be in range of max levels ) + * + * @return No return. + */ + virtual void SetTextureLevel(QT3DSI32 inLevel); + + /** + * @brief Get texture unit used + * + * + * @return texture unit bound to. + */ + virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; } + + /** + * @brief Bind a texture for shader access + * + * @param[in] unit The binding point + * + * @return No return. + */ + virtual void Bind(QT3DSU32 unit); + + /** + * @brief get the backend object handle + * here we return the handle from the wrapped texture + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle(); + + /** + * @brief static creation function + * + * @param[in] context Pointer to context + * @param[in] inTexture Pointer to a NVRenderTexture2D object + * @param[in] inAccess Image access type ( read, write, read_write ) + * + * @return No return. + */ + static NVRenderImage2D *Create(NVRenderContextImpl &context, NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp new file mode 100644 index 00000000..37f56bd2 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderIndexBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + NVRenderIndexBuffer::NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size, + NVRenderComponentTypes::Enum componentType, + NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Index, usageType, data) + , m_ComponentType(componentType) + { + } + + NVRenderIndexBuffer::~NVRenderIndexBuffer() { m_Context.BufferDestroyed(*this); } + + QT3DSU32 NVRenderIndexBuffer::GetNumIndices() const + { + QT3DSU32 dtypeSize = NVRenderComponentTypes::getSizeofType(m_ComponentType); + return m_BufferCapacity / dtypeSize; + } + + void NVRenderIndexBuffer::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) + { + m_Backend->DrawIndexed( + drawMode, count, m_ComponentType, + (const void *)(offset * NVRenderComponentTypes::getSizeofType(m_ComponentType))); + } + + void NVRenderIndexBuffer::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) + { + m_Backend->DrawIndexedIndirect(drawMode, m_ComponentType, (const void *)offset); + } + + void NVRenderIndexBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + NVRenderIndexBuffer *NVRenderIndexBuffer::Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + NVRenderComponentTypes::Enum componentType, + size_t size, NVConstDataRef<QT3DSU8> bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + if (componentType != NVRenderComponentTypes::QT3DSU32 + && componentType != NVRenderComponentTypes::QT3DSU16 + && componentType != NVRenderComponentTypes::QT3DSU8) { + qCCritical(INVALID_PARAMETER, "Invalid component type for index buffer"); + QT3DS_ASSERT(false); + return NULL; + } + + QT3DSU32 ibufSize = sizeof(NVRenderIndexBuffer); + QT3DSU8 *baseMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), ibufSize, "IndexBuffer"); + NVRenderIndexBuffer *retval = new (baseMem) NVRenderIndexBuffer( + context, size, componentType, usageType, + toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size())); + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h new file mode 100644 index 00000000..6b9c4711 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_INDEX_BUFFER_H +#define QT3DS_RENDER_INDEX_BUFFER_H +#include "render/Qt3DSRenderDataBuffer.h" +#include "render/Qt3DSRenderDrawable.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + class NVRenderIndexBuffer : public NVRenderDataBuffer, public NVRenderDrawable + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] componentType Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return No return. + */ + NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size, + NVRenderComponentTypes::Enum componentType, + NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data); + + ///< destruvtor + ~NVRenderIndexBuffer(); + + /** + * @brief get the component type (QT3DSU8, QT3DSU16) + * + * @return the component type + */ + virtual NVRenderComponentTypes::Enum GetComponentType() const { return m_ComponentType; } + + /** + * @brief get the index count + * + * @return actual index count + */ + virtual QT3DSU32 GetNumIndices() const; + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief draw the buffer + * + * @param[in] drawMode draw mode (e.g Triangles...) + * @param[in] count vertex count + * @param[in] offset start offset in byte + * + * @return no return. + */ + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override; + + /** + * @brief draw the buffer via indirec draw buffer setup + * + * @param[in] drawMode draw mode (e.g Triangles...) + * @param[in] offset byte offset into the bound drawIndirectBuffer see + * NVRenderDrawIndirectBuffer + * + * @return no return. + */ + virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_BufferHandle); + } + + static NVRenderIndexBuffer *Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + NVRenderComponentTypes::Enum componentType, size_t size, + NVConstDataRef<QT3DSU8> bufferData); + + private: + NVRenderComponentTypes::Enum m_ComponentType; ///< component type (QT3DSU8, QT3DSU16) + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp new file mode 100644 index 00000000..e4d38b9d --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderInputAssembler.h" +#include "render/Qt3DSRenderAttribLayout.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + ///< constructor + NVRenderInputAssembler::NVRenderInputAssembler( + NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout, + NVConstDataRef<NVRenderVertexBuffer *> buffers, const NVRenderIndexBuffer *indexBuffer, + NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets, + NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) + : m_Context(context) + , m_Foundation(context.GetFoundation()) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_AttribLayout(attribLayout) + , m_VertexBuffers(context.GetAllocator(), "m_VertexBuffers") + , m_IndexBuffer(indexBuffer) + , m_PrimitiveType(primType) + , m_PatchVertexCount(patchVertexCount) + { + // we cannot currently attach more than 16 vertex buffers + QT3DS_ASSERT(buffers.size() < 16); + // if primitive is "Patch" we need a patch per vertex count > 0 + QT3DS_ASSERT(m_PrimitiveType != NVRenderDrawMode::Patches || m_PatchVertexCount > 1); + + QT3DSU32 entrySize = sizeof(NVRenderBackend::NVRenderBackendBufferObject) * buffers.size(); + NVRenderBackend::NVRenderBackendBufferObject *bufferHandle = + (NVRenderBackend::NVRenderBackendBufferObject *)QT3DS_ALLOC( + m_Foundation.getAllocator(), entrySize, "NVRenderInputAssembler"); + // setup vertex buffer backend handle array + QT3DS_FOREACH(idx, buffers.size()) + { + m_VertexBuffers.push_back(buffers.mData[idx]); + bufferHandle[idx] = buffers.mData[idx]->GetBuffertHandle(); + }; + + m_VertexbufferHandles = toConstDataRef(bufferHandle, buffers.size()); + + m_InputAssemblertHandle = m_Backend->CreateInputAssembler( + m_AttribLayout->GetAttribLayoutHandle(), m_VertexbufferHandles, + (m_IndexBuffer) ? m_IndexBuffer->GetBuffertHandle() : NULL, strides, offsets, + patchVertexCount); + + attribLayout->addRef(); + } + + ///< destructor + NVRenderInputAssembler::~NVRenderInputAssembler() + { + m_AttribLayout->release(); + + if (m_InputAssemblertHandle) { + m_Backend->ReleaseInputAssembler(m_InputAssemblertHandle); + } + + QT3DS_FREE(m_Foundation.getAllocator(), (void *)m_VertexbufferHandles.mData); + } + + QT3DSU32 NVRenderInputAssembler::GetIndexCount() const + { + return (m_IndexBuffer) ? m_IndexBuffer->GetNumIndices() : 0; + } + + QT3DSU32 NVRenderInputAssembler::GetVertexCount() const + { + // makes only sense if we have a single vertex buffer + QT3DS_ASSERT(m_VertexBuffers.size() == 1); + + return m_VertexBuffers[0]->GetNumVertexes(); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h new file mode 100644 index 00000000..adac4c42 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_INPUT_ASSEMBLER_H +#define QT3DS_RENDER_INPUT_ASSEMBLER_H + +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + // forward declarations + class NVRenderContextImpl; + class NVRenderBackend; + class NVRenderAttribLayout; + + ///< this class handles the vertex attribute layout setup + class NVRenderInputAssembler : public NVRefCounted + { + public: + /** + * @brief constructor + * + * NOTE: The limit for buffers count is currently 16 + * + * @param[in] context Pointer to context + * @param[in] attribLayout Pointer to NVRenderAttribLayout object + * @param[in] buffers list of vertex buffers + * @param[in] indexBuffer pointer to index buffer. Can be NULL + * @param[in] strides list of strides of the buffer + * @param[in] offsets list of offsets into the buffer + * @param[in] primType primitive type used for drawing + * @param[in] patchVertexCount if primitive is "Patch" this is the vertex count for a + *single patch + * + * @return No return. + */ + NVRenderInputAssembler(NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout, + NVConstDataRef<NVRenderVertexBuffer *> buffers, + const NVRenderIndexBuffer *indexBuffer, + NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets, + NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles, + QT3DSU32 patchVertexCount = 1); + ///< destructor + ~NVRenderInputAssembler(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendInputAssemblerObject GetInputAssemblerHandle() const + { + return m_InputAssemblertHandle; + } + + /** + * @brief get the attached index buffer + * + * @return the index buffer + */ + const NVRenderIndexBuffer *GetIndexBuffer() { return m_IndexBuffer; } + + /** + * @brief get the index count of the attached index buffer (if any) + * + * @return the index buffer count + */ + QT3DSU32 GetIndexCount() const; + + /** + * @brief get the vertex count of the buffer + * Note this makes only sense if we have a single + * interleaved buffer + * + * @return the vertex buffer count + */ + QT3DSU32 GetVertexCount() const; + + /** + * @brief get the primitive type used for drawing + * + * @return primitive type + */ + NVRenderDrawMode::Enum GetPrimitiveType() const { return m_PrimitiveType; } + + /** + * @brief set the per vertex patch count + * + * @return none + */ + void SetPatchVertexCount(QT3DSU32 count) + { + if (count != m_PatchVertexCount) { + // clamp to 1; + m_PatchVertexCount = (count == 0) ? 1 : count; + ; + m_Backend->SetPatchVertexCount(m_InputAssemblertHandle, m_PatchVertexCount); + } + } + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + + NVRenderAttribLayout *m_AttribLayout; ///< pointer to attribute layout + nvvector<NVRenderVertexBuffer *> m_VertexBuffers; ///< vertex buffers + const NVRenderIndexBuffer *m_IndexBuffer; ///< index buffer + NVConstDataRef<NVRenderBackend::NVRenderBackendBufferObject> + m_VertexbufferHandles; ///< opaque vertex buffer backend handles + + NVRenderBackend::NVRenderBackendInputAssemblerObject + m_InputAssemblertHandle; ///< opaque backend handle + NVRenderDrawMode::Enum m_PrimitiveType; ///< primitive type used for drawing + QT3DSU32 m_PatchVertexCount; ///< vertex count if primitive type is patch + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp new file mode 100644 index 00000000..d1b62d4c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderOcclusionQuery.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + NVRenderOcclusionQuery::NVRenderOcclusionQuery(NVRenderContextImpl &context, + NVFoundationBase &fnd) + : NVRenderQueryBase(context, fnd) + { + } + + NVRenderOcclusionQuery::~NVRenderOcclusionQuery() {} + + void NVRenderOcclusionQuery::Begin() + { + m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Samples); + } + + void NVRenderOcclusionQuery::End() + { + m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Samples); + } + + void NVRenderOcclusionQuery::GetResult(QT3DSU32 *params) + { + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); + } + + bool NVRenderOcclusionQuery::GetResultAvailable() + { + QT3DSU32 param; + + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::ResultAvailable, ¶m); + + return (param == 1); + } + + NVRenderOcclusionQuery *NVRenderOcclusionQuery::Create(NVRenderContextImpl &context) + { + if (!context.IsSampleQuerySupported()) + return NULL; + + NVRenderOcclusionQuery *retval = + QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderOcclusionQuery)(context, context.GetFoundation()); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h new file mode 100644 index 00000000..04f64e97 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_OCCLUSION_QUERY_H +#define QT3DS_RENDER_OCCLUSION_QUERY_H + +#include "render/Qt3DSRenderQueryBase.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + class NVRenderOcclusionQuery : public NVRenderQueryBase + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderOcclusionQuery(NVRenderContextImpl &context, NVFoundationBase &fnd); + + ///< destructor + ~NVRenderOcclusionQuery(); + + /** + * @brief Get query type + * + * @return Return query type + */ + NVRenderQueryType::Enum GetQueryType() const override + { + return NVRenderQueryType::Samples; + } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief begin a query + * + * @return no return. + */ + void Begin() override; + + /** + * @brief end a query + * + * @return no return. + */ + void End() override; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + void GetResult(QT3DSU32 *params) override; + + /** + * @brief query if a result is available + * + * + * @return true if available. + */ + virtual bool GetResultAvailable(); + + /* + * @brief static creation function + * + * * @return a occlusion query object on success + */ + static NVRenderOcclusionQuery *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp new file mode 100644 index 00000000..3e9276aa --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderPathFontSpecification.h" +#include "render/Qt3DSRenderPathFontText.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderPathFontSpecification::NVRenderPathFontSpecification(NVRenderContextImpl &context, + NVFoundationBase &fnd, + CRegisteredString fontName) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_NumFontGlyphs(0) + , m_EmScale(2048) // 2048 is default true type scale + , m_Type(NVRenderPathFormatType::UByte) + , m_TransformType(NVRenderPathTransformType::Translate2D) + , m_FontName(fontName) + { + } + + NVRenderPathFontSpecification::~NVRenderPathFontSpecification() + { + m_Context.ReleasePathFontSpecification(*this); + } + + void NVRenderPathFontSpecification::LoadPathGlyphs(const char *fontName, + NVRenderPathFormatType::Enum type) + { + // check if we already created it + if (m_NumFontGlyphs) + return; + + m_Type = type; + + // create fonts based on the input + m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::FileFont, fontName, NVRenderPathFontStyleFlags(), 0, m_EmScale, + &m_NumFontGlyphs); + + // Fallback in case the previuos call fails + // This is a no-op if the previous call succeeds + // Note that sans is an inbuild driver font + if (!m_PathRenderHandle) { + m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::SystemFont, "Arial", NVRenderPathFontStyleFlags(), 0, + m_EmScale, &m_NumFontGlyphs); + } + + // we should have some glyphs + QT3DS_ASSERT(m_NumFontGlyphs); + } + + void + NVRenderPathFontSpecification::StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem) + { + const void *glyphIDs = inPathFontItem.GetGlyphIDs(); + const QT3DSF32 *spacing = inPathFontItem.GetSpacing(); + if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) { + QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount()); + return; + } + + m_Backend->StencilFillPathInstanced(m_PathRenderHandle, inPathFontItem.GetGlyphsCount(), + m_Type, glyphIDs, NVRenderPathFillMode::Fill, 0xFF, + m_TransformType, spacing); + } + + void NVRenderPathFontSpecification::CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem) + { + const void *glyphIDs = inPathFontItem.GetGlyphIDs(); + const QT3DSF32 *spacing = inPathFontItem.GetSpacing(); + if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) { + QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount()); + return; + } + + m_Backend->CoverFillPathInstanced( + m_PathRenderHandle, inPathFontItem.GetGlyphsCount(), m_Type, glyphIDs, + NVRenderPathCoverMode::BoundingBoxOfBoundingBox, m_TransformType, spacing); + } + + QT3DSU32 + NVRenderPathFontSpecification::getSizeofType(NVRenderPathFormatType::Enum type) + { + switch (type) { + case NVRenderPathFormatType::Byte: + return sizeof(QT3DSI8); + case NVRenderPathFormatType::UByte: + return sizeof(QT3DSU8); + case NVRenderPathFormatType::Bytes2: + return sizeof(QT3DSU16); + case NVRenderPathFormatType::Uint: + return sizeof(QT3DSU32); + case NVRenderPathFormatType::Utf8: + return sizeof(QT3DSU32); + default: + QT3DS_ASSERT(false); + return 1; + } + } + + NVRenderPathFontSpecification * + NVRenderPathFontSpecification::CreatePathFontSpecification(NVRenderContextImpl &context, + CRegisteredString fontName) + { + QT3DS_ASSERT(context.IsPathRenderingSupported()); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathFontSpecification)(context, context.GetFoundation(), fontName); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h new file mode 100644 index 00000000..dad3f6bb --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #pragma once +#ifndef QT3DS_RENDER_PATH_FONT_SPECIFICATION_H +#define QT3DS_RENDER_PATH_FONT_SPECIFICATION_H +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "foundation/StringTable.h" +#include "EASTL/string.h" +#include "render/backends/Qt3DSRenderBackend.h" + + namespace qt3ds +{ + namespace render { + + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderPathRender; + class NVRenderPathFontItem; + + class NVRenderPathFontSpecification : public NVRefCounted + { + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 + mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] fontName Name of font ( may include path + * ) + * + * @return No return. + */ + NVRenderPathFontSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd, + CRegisteredString fontName); + + /// @NVRenderPathSpecification destructor + ~NVRenderPathFontSpecification(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Load numGlyphs glyphs from specified font file + * + * @param[in] pathBase Base of path objects + * @param[in] fontName Name of font ( may include path + * ) + * @param[in] numGlyphs Glyph count + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes character string + * + * @return No return + */ + virtual void LoadPathGlyphs(const char *fontName, NVRenderPathFormatType::Enum type); + + /** + * @brief Render a stencil fill pass for fonts + * + * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification + * + * @return no return + */ + void StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem); + + /** + * @brief Render a cover fill pass for fonts + * + * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification + * + * @return no return + */ + void CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem); + + /** + * @brief get type for font path set + * + * @return path font type + */ + NVRenderPathFormatType::Enum GetPathFontType() { return m_Type; } + + /** + * @brief get font glyph count + * + * @return get glyph count + */ + QT3DSU32 GetFontGlyphsCount() { return m_NumFontGlyphs; } + + /** + * @brief get spacing for char set + * + * @return spacing array + */ + QT3DSF32 GetEmScale() const { return m_EmScale; } + + /** + * @brief Get font name + * + * @return name set + */ + CRegisteredString GetFontName() const { return m_FontName; } + + private: + QT3DSU32 m_NumFontGlyphs; ///< glyph count of the entire font set + QT3DSF32 m_EmScale; ///< true type scale + NVRenderPathFormatType::Enum m_Type; ///< type ( byte, int,... ) + NVRenderPathTransformType::Enum m_TransformType; ///< transform type default 2D + CRegisteredString m_FontName; ///< Name of Font + NVRenderBackend::NVRenderBackendPathObject + m_PathRenderHandle; ///< opaque backend handle + + private: + /** + * @brief Get size of type + * + * @param[in] type type ( byte, int,... ) + * + * @return true if successful + */ + QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type); + + public: + static NVRenderPathFontSpecification * + CreatePathFontSpecification(NVRenderContextImpl &context, CRegisteredString fontName); + }; + } +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp b/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp new file mode 100644 index 00000000..aeaad13c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderPathFontText.h" +#include "render/Qt3DSRenderPathFontSpecification.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderPathRender.h" + +namespace qt3ds { +namespace render { + + // see NVprSDK for explanation + // Math from page 54-56 of "Digital Image Warping" by George Wolberg, + // though credited to Paul Heckert's "Fundamentals of Texture + // Mapping and Image Warping" 1989 Master's thesis. + static QT3DSMat33 mapSquareToQuad(QT3DSVec2 inSquare[4]) + { + QT3DSMat33 ret; + + QT3DSVec2 d1(inSquare[1] - inSquare[2]); + QT3DSVec2 d2(inSquare[3] - inSquare[2]); + QT3DSVec2 d3(inSquare[0] - inSquare[1] + inSquare[2] - inSquare[3]); + + QT3DSF32 denom = d1.x * d2.y - d2.x * d1.y; + if (denom == 0.0) { + return QT3DSMat33::createIdentity(); + } + + ret[2][0] = (d3.x * d2.y - d2.x * d3.y) / denom; + ret[2][1] = (d1.x * d3.y - d3.x * d1.y) / denom; + ret[2][2] = 1.0; + ret[0][0] = inSquare[1].x - inSquare[0].x + ret[2][0] * inSquare[1].x; + ret[1][0] = inSquare[1].y - inSquare[0].y + ret[2][0] * inSquare[1].y; + ret[0][1] = inSquare[3].x - inSquare[0].x + ret[2][1] * inSquare[3].x; + ret[1][1] = inSquare[3].y - inSquare[0].y + ret[2][1] * inSquare[3].y; + ret[0][2] = inSquare[0].x; + ret[1][2] = inSquare[0].y; + + return ret; + } + + static QT3DSMat33 mapQuadToSquare(QT3DSVec2 inSquare[4]) + { + return mapSquareToQuad(inSquare).getInverse(); + } + + static QT3DSMat33 mapQuadToQuad(QT3DSVec2 fromSquare[4], QT3DSVec2 toSquare[4]) + { + return (mapSquareToQuad(toSquare) * mapQuadToSquare(fromSquare)); + } + + static QT3DSMat44 mapBoxToQuad(QT3DSVec4 inBox, QT3DSVec2 inSquare[4]) + { + QT3DSVec2 fromSquare[4] = { QT3DSVec2(inBox.x, inBox.y), QT3DSVec2(inBox.z, inBox.y), + QT3DSVec2(inBox.z, inBox.w), QT3DSVec2(inBox.x, inBox.w) }; + + QT3DSMat33 ret = mapQuadToQuad(fromSquare, inSquare); + + return QT3DSMat44(ret.column0, ret.column1, ret.column2, QT3DSVec3(0.0, 0.0, 0.0)); + } + + NVRenderPathFontItem::NVRenderPathFontItem(NVFoundationBase &fnd) + : m_Foundation(fnd) + , mRefCount(0) + , m_NumGlyphs(0) + , m_GlyphIDs(NULL) + , m_TranslateXY(NULL) + { + } + + NVRenderPathFontItem::~NVRenderPathFontItem() + { + if (m_TranslateXY) + QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY); + if (m_GlyphIDs) + QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs); + } + + void NVRenderPathFontItem::InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs, + NVRenderPathFormatType::Enum type, QT3DSF32 *posArray, + QT3DSVec2 pixelBound, QT3DSVec2 logicalBound, QT3DSF32 emScale) + { + m_NumGlyphs = glyphCount; + + // allocate glyphs array + if (m_GlyphIDs) + QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs); + + // allocate position array + if (m_TranslateXY) + QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY); + + m_GlyphIDs = (QT3DSU32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), + glyphCount * getSizeofType(type), "NVRenderPathFontItem"); + m_TranslateXY = + (QT3DSF32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), 2 * (glyphCount + 1) * sizeof(QT3DSF32), + "NVRenderPathFontItem"); + + if (!m_GlyphIDs || !m_TranslateXY) + return; + + QT3DSU32 *pTheGlyphIDs = (QT3DSU32 *)m_GlyphIDs; + QT3DSU32 *pInGlyphs = (QT3DSU32 *)glyphIDs; + + /// copy glyphs array + for (size_t i = 0; i < glyphCount; i++) { + pTheGlyphIDs[i] = pInGlyphs[i]; + } + + // copy position array + // we copy what we got from our layout system + if (posArray != NULL) { + for (size_t i = 0, k = 0; i < glyphCount * 2; i += 2, k++) { + m_TranslateXY[i] = posArray[i] * emScale; + m_TranslateXY[i + 1] = posArray[i + 1] * emScale; + } + } + + // setup transform + QT3DSVec2 square[4] = { QT3DSVec2(0.0, 0.0), QT3DSVec2(pixelBound.x, 0.0), + QT3DSVec2(pixelBound.x, pixelBound.y), QT3DSVec2(0.0, pixelBound.y) }; + QT3DSVec4 box(0.0, 0.0, logicalBound.x * emScale, logicalBound.y * emScale); + + m_ModelMatrix = mapBoxToQuad(box, square); + } + + const QT3DSMat44 NVRenderPathFontItem::GetTransform() + { + return QT3DSMat44(QT3DSVec4(m_ModelMatrix[0][0], m_ModelMatrix[1][0], 0.0, m_ModelMatrix[2][0]), + QT3DSVec4(m_ModelMatrix[0][1], m_ModelMatrix[1][1], 0.0, m_ModelMatrix[2][1]), + QT3DSVec4(0.0, 0.0, 1.0, 0.0), + QT3DSVec4(m_ModelMatrix[0][2], m_ModelMatrix[1][2], 0.0, m_ModelMatrix[2][2])); + } + + QT3DSU32 + NVRenderPathFontItem::getSizeofType(NVRenderPathFormatType::Enum type) + { + switch (type) { + case NVRenderPathFormatType::Byte: + return sizeof(QT3DSI8); + case NVRenderPathFormatType::UByte: + return sizeof(QT3DSU8); + case NVRenderPathFormatType::Bytes2: + return sizeof(QT3DSU16); + case NVRenderPathFormatType::Uint: + return sizeof(QT3DSU32); + case NVRenderPathFormatType::Utf8: + return sizeof(QT3DSU32); + default: + QT3DS_ASSERT(false); + return 1; + } + } + + NVRenderPathFontItem *NVRenderPathFontItem::CreatePathFontItem(NVRenderContextImpl &context) + { + QT3DS_ASSERT(context.IsPathRenderingSupported()); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathFontItem)(context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontText.h b/src/Runtime/Source/render/Qt3DSRenderPathFontText.h new file mode 100644 index 00000000..a1d103ac --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathFontText.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #pragma once +#ifndef QT3DS_RENDER_PATH_FONT_TEXT_H +#define QT3DS_RENDER_PATH_FONT_TEXT_H +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "EASTL/string.h" +#include "render/backends/Qt3DSRenderBackend.h" + + namespace qt3ds +{ + namespace render { + + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderPathFontSpecification; + + class NVRenderPathFontItem : public NVRefCounted + { + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 + mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderPathFontItem(NVFoundationBase &fnd); + + /// @NVRenderPathFontItem destructor + ~NVRenderPathFontItem(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Setup text + * + * @param[in] glyphCount number of glyphs + * @param[in] glyphIDs array of glyhp ID's + * @param[in] type type ( byte, int,... ) + * @param[in] posArray array of glyhp positions + * @param[in] pixelBound pixel boundary + * @param[in] logicalBound logical boundary + * @param[in] emScale true type scale + * + * @return No return. + */ + void InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs, + NVRenderPathFormatType::Enum type, QT3DSF32 *posArray, QT3DSVec2 pixelBound, + QT3DSVec2 logicalBound, QT3DSF32 emScale); + + /** + * @brief get glyph count + * + * @return get glyph count + */ + size_t GetGlyphsCount() { return m_NumGlyphs; } + + /** + * @brief get spacing for char set + * + * @return spacing array + */ + const QT3DSF32 *GetSpacing() { return m_TranslateXY; } + + /** + * @brief get name set + * + * @return name set + */ + const void *GetGlyphIDs() { return (void *)m_GlyphIDs; } + + /** + * @brief Get Y bound of font metric + * + * @return transform matrix + */ + const QT3DSMat44 GetTransform(); + + private: + /** + * @brief Get size of type + * + * @param[in] type type ( byte, int,... ) + * + * @return true if successful + */ + QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type); + + private: + size_t m_NumGlyphs; ///< glyph count + QT3DSU32 *m_GlyphIDs; ///< array glyph ID's + QT3DSF32 * + m_TranslateXY; ///< pointer to arrray for character advance information like kerning + QT3DSMat44 m_ModelMatrix; ///< Matrix which converts from font space to box space + + public: + static NVRenderPathFontItem *CreatePathFontItem(NVRenderContextImpl &context); + }; + } +} + +#endif
\ No newline at end of file diff --git a/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp b/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp new file mode 100644 index 00000000..42982498 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderPathRender.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderPathSpecification.h" +#include "render/Qt3DSRenderPathFontSpecification.h" + +namespace qt3ds { +namespace render { + + NVRenderPathRender::NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd, + size_t range) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_StrokeWidth(0.0f) + { + m_Range = range; + m_PathRenderHandle = m_Backend->CreatePathNVObject(range); + } + + NVRenderPathRender::~NVRenderPathRender() + { + if (m_PathRenderHandle) { + m_Backend->ReleasePathNVObject(m_PathRenderHandle, m_Range); + } + } + + void NVRenderPathRender::SetPathSpecification(NVRenderPathSpecification &inCommandBuffer) + { + m_Backend->SetPathSpecification(m_PathRenderHandle, inCommandBuffer.GetPathCommands(), + inCommandBuffer.GetPathCoords()); + } + + NVBounds3 NVRenderPathRender::GetPathObjectBoundingBox() + { + return m_Backend->GetPathObjectBoundingBox(m_PathRenderHandle); + } + + NVBounds3 NVRenderPathRender::GetPathObjectFillBox() + { + return m_Backend->GetPathObjectFillBox(m_PathRenderHandle); + } + + NVBounds3 NVRenderPathRender::GetPathObjectStrokeBox() + { + return m_Backend->GetPathObjectStrokeBox(m_PathRenderHandle); + } + + void NVRenderPathRender::SetStrokeWidth(QT3DSF32 inStrokeWidth) + { + if (inStrokeWidth != m_StrokeWidth) { + m_StrokeWidth = inStrokeWidth; + m_Backend->SetStrokeWidth(m_PathRenderHandle, inStrokeWidth); + } + } + + QT3DSF32 NVRenderPathRender::GetStrokeWidth() const { return m_StrokeWidth; } + + void NVRenderPathRender::StencilStroke() { m_Backend->StencilStrokePath(m_PathRenderHandle); } + + void NVRenderPathRender::StencilFill() { m_Backend->StencilFillPath(m_PathRenderHandle); } + + NVRenderPathRender *NVRenderPathRender::Create(NVRenderContextImpl &context, size_t range) + { + if (!context.IsPathRenderingSupported()) + return NULL; + + NVRenderPathRender *retval = + QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathRender)(context, context.GetFoundation(), range); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathRender.h b/src/Runtime/Source/render/Qt3DSRenderPathRender.h new file mode 100644 index 00000000..c261ca31 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathRender.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_RENDER_H +#define QT3DS_RENDER_PATH_RENDER_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "foundation/Qt3DSBounds3.h" +#include <EASTL/string.h> + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderPathSpecification; + class NVRenderPathFontSpecification; + + ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....) + class NVRenderPathRender : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] range Number of internal objects + * + * @return No return. + */ + NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t range); + + /// @brief destructor + ~NVRenderPathRender(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendPathObject GetPathHandle() { return m_PathRenderHandle; } + + // The render context can create a path specification object. + void SetPathSpecification(NVRenderPathSpecification &inCommandBuffer); + + NVBounds3 GetPathObjectBoundingBox(); + NVBounds3 GetPathObjectFillBox(); + NVBounds3 GetPathObjectStrokeBox(); + + void SetStrokeWidth(QT3DSF32 inStrokeWidth); + QT3DSF32 GetStrokeWidth() const; + + void StencilStroke(); + void StencilFill(); + + /** + * @brief static create function + * + * @param[in] context Pointer to render context + * @param[in] range Number of internal objects + * + * @return the backend object handle. + */ + static NVRenderPathRender *Create(NVRenderContextImpl &context, size_t range); + + private: + NVRenderBackend::NVRenderBackendPathObject m_PathRenderHandle; ///< opaque backend handle + size_t m_Range; ///< range of internal objects + QT3DSF32 m_StrokeWidth; + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp new file mode 100644 index 00000000..f4b26f11 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2015 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderPathSpecification.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderPathSpecification::NVRenderPathSpecification(NVRenderContextImpl &context, + NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_PathCommands(fnd.getAllocator(), "m_PathCommands") + , m_PathCoords(fnd.getAllocator(), "m_PathCoords") + { + } + + NVRenderPathSpecification::~NVRenderPathSpecification() {} + + void NVRenderPathSpecification::Reset() + { + m_PathCommands.clear(); + m_PathCoords.clear(); + } + + void NVRenderPathSpecification::P(QT3DSVec2 inData) + { + m_PathCoords.push_back(inData.x); + m_PathCoords.push_back(inData.y); + } + + void NVRenderPathSpecification::MoveTo(QT3DSVec2 inPoint) + { + // we should actually query the backend for command converesion + // but will we support any other pather render system than nv path? + StaticAssert<NVRenderPathCommands::MoveTo == 0x02>::valid_expression(); + + m_PathCommands.push_back(NVRenderPathCommands::MoveTo); + P(inPoint); + } + + void NVRenderPathSpecification::CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest) + { + // we should actually query the backend for command converesion + // but will we support any other pather render system than nv path? + StaticAssert<NVRenderPathCommands::CubicCurveTo == 0x0C>::valid_expression(); + + m_PathCommands.push_back(NVRenderPathCommands::CubicCurveTo); + P(inC1); + P(inC2); + P(inDest); + } + + void NVRenderPathSpecification::ClosePath() + { + // we should actually query the backend for command converesion + // but will we support any other pather render system than nv path? + StaticAssert<NVRenderPathCommands::Close == 0x00>::valid_expression(); + + m_PathCommands.push_back(NVRenderPathCommands::Close); + } + + NVRenderPathSpecification * + NVRenderPathSpecification::CreatePathSpecification(NVRenderContextImpl &context) + { + QT3DS_ASSERT(context.IsPathRenderingSupported()); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderPathSpecification)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h new file mode 100644 index 00000000..7c6faeda --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PATH_SPECIFICATION_H +#define QT3DS_RENDER_PATH_SPECIFICATION_H +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSContainers.h" +#include "foundation/Qt3DSAllocatorCallback.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + class NVRenderContextImpl; + + class NVRenderPathSpecification : public NVRefCounted + { + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderPathSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd); + + /// @NVRenderPathSpecification destructor + ~NVRenderPathSpecification(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief reset commands and coordiantes + * + * @return No return. + */ + virtual void Reset(); + + /** + * @brief add new move to command + * + * @param[in] inPoint Coordinate + * + * @return No return. + */ + virtual void MoveTo(QT3DSVec2 inPoint); + + /** + * @brief add new cubic curve command + * + * @param[in] inC1 control point 1 + * @param[in] inC2 control point 2 + * @param[in] inDest final point + * + * @return No return. + */ + virtual void CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest); + + /** + * @brief add new close command + * + * + * @return No return. + */ + virtual void ClosePath(); + + /** + * @brief Get path command list + * + * + * @return path commands + */ + virtual NVConstDataRef<QT3DSU8> GetPathCommands() { return m_PathCommands; } + + /** + * @brief Get path coordinates list + * + * + * @return path coordinates + */ + virtual NVConstDataRef<QT3DSF32> GetPathCoords() { return m_PathCoords; } + + private: + nvvector<QT3DSU8> m_PathCommands; + nvvector<QT3DSF32> m_PathCoords; + + /** + * @brief add a new point to the coordinates + * + * @param[in] inPoint Coordinate + * + * @return No return. + */ + void P(QT3DSVec2 inData); + + public: + static NVRenderPathSpecification *CreatePathSpecification(NVRenderContextImpl &context); + }; +} +} + +#endif
\ No newline at end of file diff --git a/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp new file mode 100644 index 00000000..b0a9f271 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderProgramPipeline.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + NVRenderProgramPipeline::NVRenderProgramPipeline(NVRenderContextImpl &context, + NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , mRefCount(0) + , m_Program(NULL) + , m_VertexProgram(NULL) + , m_FragmentProgram(NULL) + , m_TessControlProgram(NULL) + , m_TessEvalProgram(NULL) + , m_GeometryProgram(NULL) + , m_ComputProgram(NULL) + { + m_ProgramPipelineHandle = m_Backend->CreateProgramPipeline(); + } + + NVRenderProgramPipeline::~NVRenderProgramPipeline() + { + if (m_ProgramPipelineHandle) { + m_Backend->ReleaseProgramPipeline(m_ProgramPipelineHandle); + } + + if (m_VertexProgram) + m_VertexProgram->release(); + if (m_FragmentProgram) + m_FragmentProgram->release(); + if (m_TessControlProgram) + m_TessControlProgram->release(); + if (m_TessEvalProgram) + m_TessEvalProgram->release(); + if (m_GeometryProgram) + m_GeometryProgram->release(); + } + + bool NVRenderProgramPipeline::IsValid() { return (m_ProgramPipelineHandle != NULL); } + + void NVRenderProgramPipeline::SetProgramStages(NVRenderShaderProgram *inProgram, + NVRenderShaderTypeFlags flags) + { + bool bDirty = false; + + if (flags & NVRenderShaderTypeValue::Vertex && inProgram != m_VertexProgram) { + if (m_VertexProgram) + m_VertexProgram->release(); + if (inProgram) + inProgram->addRef(); + m_VertexProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::Fragment && inProgram != m_FragmentProgram) { + if (m_FragmentProgram) + m_FragmentProgram->release(); + if (inProgram) + inProgram->addRef(); + m_FragmentProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::TessControl && inProgram != m_TessControlProgram) { + if (m_TessControlProgram) + m_TessControlProgram->release(); + if (inProgram) + inProgram->addRef(); + m_TessControlProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::TessEvaluation && inProgram != m_TessEvalProgram) { + if (m_TessEvalProgram) + m_TessEvalProgram->release(); + if (inProgram) + inProgram->addRef(); + m_TessEvalProgram = inProgram; + bDirty = true; + } + if (flags & NVRenderShaderTypeValue::Geometry && inProgram != m_GeometryProgram) { + if (m_GeometryProgram) + m_GeometryProgram->release(); + if (inProgram) + inProgram->addRef(); + m_GeometryProgram = inProgram; + bDirty = true; + } + + if (bDirty) { + m_Backend->SetProgramStages(m_ProgramPipelineHandle, flags, + (inProgram) ? inProgram->GetShaderProgramHandle() : NULL); + } + } + + void NVRenderProgramPipeline::Bind() + { + m_Backend->SetActiveProgramPipeline(m_ProgramPipelineHandle); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h new file mode 100644 index 00000000..ce47146a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_PROGRAM_PIPLINE_H +#define QT3DS_RENDER_PROGRAM_PIPLINE_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderContext.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include <EASTL/string.h> + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + class NVRenderShaderProgram; + + ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....) + class QT3DS_AUTOTEST_EXPORT NVRenderProgramPipeline : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderProgramPipeline(NVRenderContextImpl &context, NVFoundationBase &fnd); + + /// @brief destructor + ~NVRenderProgramPipeline(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Query if pipeline is valid + * + * @return True if valid. + */ + bool IsValid(); + + /** + * @brief enable / disable a program stage in the pipeline + * + * @param[in] pProgram Pointer to program. If NULL stage will be disabled + * @param[in] flags Flags to which stage this program is bound to. Can more than + * one stage + * + * @return no return. + */ + void SetProgramStages(NVRenderShaderProgram *pProgram, NVRenderShaderTypeFlags flags); + + /** + * @brief Make the program pipeline active + * + * @return True if valid. + */ + void Bind(); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendProgramPipeline GetShaderHandle() + { + return m_ProgramPipelineHandle; + } + + /** + * @brief get the vertex stage program + * + * @return the backend object handle. + */ + NVRenderShaderProgram *GetVertexStage() { return m_VertexProgram; } + + private: + NVRenderBackend::NVRenderBackendProgramPipeline + m_ProgramPipelineHandle; ///< opaque backend handle + + NVRenderShaderProgram + *m_Program; ///< for non separable programs this contains the entire program + NVRenderShaderProgram + *m_VertexProgram; ///< for separable programs this contains the vertex program + NVRenderShaderProgram + *m_FragmentProgram; ///< for separable programs this contains the fragment program + NVRenderShaderProgram *m_TessControlProgram; ///< for separable programs this contains the + ///tessellation control program + NVRenderShaderProgram *m_TessEvalProgram; ///< for separable programs this contains the + ///tessellation evaluation program + NVRenderShaderProgram + *m_GeometryProgram; ///< for separable programs this contains the geometry program + NVRenderShaderProgram + *m_ComputProgram; ///< for separable programs this contains the compute program + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp b/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp new file mode 100644 index 00000000..f13bc499 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderQueryBase.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderQueryBase::NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + { + m_QueryHandle = m_Backend->CreateQuery(); + } + + NVRenderQueryBase::~NVRenderQueryBase() + { + if (m_QueryHandle) + m_Backend->ReleaseQuery(m_QueryHandle); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderQueryBase.h b/src/Runtime/Source/render/Qt3DSRenderQueryBase.h new file mode 100644 index 00000000..7a7ead87 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderQueryBase.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QUERY_BASE_H +#define QT3DS_RENDER_QUERY_BASE_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + class NVRenderBackend; + + ///< Base class + class NVRenderQueryBase : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendQueryObject m_QueryHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd); + + virtual ~NVRenderQueryBase(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Get query type + * + * @return Return query type + */ + virtual NVRenderQueryType::Enum GetQueryType() const = 0; + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief begin a query + * + * @return no return. + */ + virtual void Begin() = 0; + + /** + * @brief end a query + * + * @return no return. + */ + virtual void End() = 0; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + virtual void GetResult(QT3DSU32 *params) = 0; + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendQueryObject GetQuerytHandle() const + { + return m_QueryHandle; + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp new file mode 100644 index 00000000..e7daf7f4 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderRasterizerState.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderRasterizerState::NVRenderRasterizerState(NVRenderContextImpl &context, + NVFoundationBase &fnd, QT3DSF32 depthBias, + QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + { + // create backend handle + m_StateHandle = m_Backend->CreateRasterizerState(depthBias, depthScale, cullFace); + } + + NVRenderRasterizerState::~NVRenderRasterizerState() + { + if (m_StateHandle) { + m_Backend->ReleaseRasterizerState(m_StateHandle); + m_Context.StateDestroyed(*this); + } + } + + NVRenderRasterizerState *NVRenderRasterizerState::Create(NVRenderContextImpl &context, + QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderRasterizerState)( + context, context.GetFoundation(), depthBias, depthScale, cullFace); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h new file mode 100644 index 00000000..9b71ae42 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_RASTERIZER_STATE_H +#define QT3DS_RENDER_RASTERIZER_STATE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + + // currently this handles only stencil state + class NVRenderRasterizerState : public NVRefCounted + { + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendRasterizerStateObject + m_StateHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] depthBias depth bias + * @param[in] depthScale depth multiplicator + * @param[in] cullFace which face to cull front or back + * + * @return No return. + */ + NVRenderRasterizerState(NVRenderContextImpl &context, NVFoundationBase &fnd, + QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace); + + virtual ~NVRenderRasterizerState(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendRasterizerStateObject GetRasterizerObjectHandle() + { + return m_StateHandle; + } + + static NVRenderRasterizerState *Create(NVRenderContextImpl &context, QT3DSF32 depthBias, + QT3DSF32 depthScale, NVRenderFaces::Enum cullFace); + + private: + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp new file mode 100644 index 00000000..b682bc1b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderRenderBuffer.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderRenderBuffer::NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderRenderBufferFormats::Enum format, + QT3DSU32 width, QT3DSU32 height) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_Width(width) + , m_Height(height) + , m_StorageFormat(format) + , m_BufferHandle(NULL) + { + SetDimensions(NVRenderRenderBufferDimensions(width, height)); + } + + NVRenderRenderBuffer::~NVRenderRenderBuffer() + { + m_Context.RenderBufferDestroyed(*this); + m_Backend->ReleaseRenderbuffer(m_BufferHandle); + m_BufferHandle = 0; + } + + void NVRenderRenderBuffer::SetDimensions(const NVRenderRenderBufferDimensions &inDimensions) + { + QT3DSU32 maxWidth, maxHeight; + m_Width = inDimensions.m_Width; + m_Height = inDimensions.m_Height; + + // get max size and clamp to max value + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (m_Width > maxWidth || m_Height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + m_Width = NVMin(m_Width, maxWidth); + m_Height = NVMin(m_Height, maxHeight); + } + + bool success = true; + + if (m_BufferHandle == NULL) + m_BufferHandle = m_Backend->CreateRenderbuffer(m_StorageFormat, m_Width, m_Height); + else + success = + m_Backend->ResizeRenderbuffer(m_BufferHandle, m_StorageFormat, m_Width, m_Height); + + if (m_BufferHandle == NULL || !success) { + // We could try smaller sizes + QT3DS_ASSERT(false); + qCCritical(INTERNAL_ERROR, "Unable to create render buffer %s, %dx%d", + NVRenderRenderBufferFormats::toString(m_StorageFormat), m_Width, + m_Height); + } + } +} +} + +qt3ds::render::NVRenderRenderBuffer * +qt3ds::render::NVRenderRenderBuffer::Create(NVRenderContextImpl &context, + NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, + QT3DSU32 height) +{ + NVRenderRenderBuffer *retval = NULL; + if (width == 0 || height == 0) { + qCCritical(INVALID_PARAMETER, "Invalid renderbuffer width or height"); + return retval; + } + + retval = QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderRenderBuffer)(context, context.GetFoundation(), format, width, height); + + return retval; +} diff --git a/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h new file mode 100644 index 00000000..41f4068a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + class NVRenderContextImpl; + + struct NVRenderRenderBufferDimensions + { + QT3DSU32 m_Width; ///< buffer width + QT3DSU32 m_Height; ///< buffer height + + NVRenderRenderBufferDimensions(QT3DSU32 w, QT3DSU32 h) + : m_Width(w) + , m_Height(h) + { + } + NVRenderRenderBufferDimensions() + : m_Width(0) + , m_Height(0) + { + } + }; + + class NVRenderRenderBuffer : public NVRefCounted, public NVRenderImplemented + { + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + QT3DSU32 m_Width; ///< buffer width + QT3DSU32 m_Height; ///< buffer height + NVRenderRenderBufferFormats::Enum m_StorageFormat; ///< buffer storage format + + NVRenderBackend::NVRenderBackendRenderbufferObject + m_BufferHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] format Renderbuffer format + * @param[in] width Renderbuffer width + * @param[in] height Renderbuffer height + * + * @return No return. + */ + NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, QT3DSU32 height); + + /// destructor + virtual ~NVRenderRenderBuffer(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + /** + * @brief query buffer format + * + * + * @return buffer format + */ + virtual NVRenderRenderBufferFormats::Enum GetStorageFormat() const + { + return m_StorageFormat; + } + + /** + * @brief query buffer dimension + * + * + * @return NVRenderRenderBufferDimensions object + */ + virtual NVRenderRenderBufferDimensions GetDimensions() const + { + return NVRenderRenderBufferDimensions(m_Width, m_Height); + } + + /** + * @brief constructor + * + * @param[in] inDimensions A dimension object + * + * @return buffer format + */ + virtual void SetDimensions(const NVRenderRenderBufferDimensions &inDimensions); + + /** + * @brief static creator function + * + * @param[in] context Pointer to context + * @param[in] format Renderbuffer format + * @param[in] width Renderbuffer width + * @param[in] height Renderbuffer height + * + * @return No return. + */ + static NVRenderRenderBuffer *Create(NVRenderContextImpl &context, + NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, + QT3DSU32 height); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendRenderbufferObject GetRenderBuffertHandle() + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_BufferHandle); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderSampler.cpp b/src/Runtime/Source/render/Qt3DSRenderSampler.cpp new file mode 100644 index 00000000..b02fc615 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSampler.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSDataRef.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" + +namespace qt3ds { +namespace render { + + NVRenderTextureSampler::NVRenderTextureSampler( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, NVRenderTextureSwizzleMode::Enum swizzleMode, + QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, NVRenderTextureCompareMode::Enum compareMode, + NVRenderTextureCompareOp::Enum compareFunc, QT3DSF32 anisotropy, QT3DSF32 *borderColor) + : m_MinFilter(minFilter) + , m_MagFilter(magFilter) + , m_WrapS(wrapS) + , m_WrapT(wrapT) + , m_WrapR(wrapR) + , m_SwizzleMode(swizzleMode) + , m_MinLod(minLod) + , m_MaxLod(maxLod) + , m_LodBias(lodBias) + , m_CompareMode(compareMode) + , m_CompareOp(compareFunc) + , m_Anisotropy(anisotropy) + , m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_SamplerHandle(NULL) + { + // create backend handle + m_SamplerHandle = m_Backend->CreateSampler(); + + if (borderColor) { + m_BorderColor[0] = borderColor[0]; + m_BorderColor[1] = borderColor[1]; + m_BorderColor[2] = borderColor[2]; + m_BorderColor[3] = borderColor[3]; + } + } + + NVRenderTextureSampler::~NVRenderTextureSampler() + { + if (m_SamplerHandle) + m_Backend->ReleaseSampler(m_SamplerHandle); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderSampler.h b/src/Runtime/Source/render/Qt3DSRenderSampler.h new file mode 100644 index 00000000..77d3f008 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSampler.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H +#define QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + + class NVRenderTextureSampler + { + public: + NVRenderTextureMinifyingOp::Enum m_MinFilter; + NVRenderTextureMagnifyingOp::Enum m_MagFilter; + NVRenderTextureCoordOp::Enum m_WrapS; + NVRenderTextureCoordOp::Enum m_WrapT; + NVRenderTextureCoordOp::Enum m_WrapR; + NVRenderTextureSwizzleMode::Enum m_SwizzleMode; + QT3DSF32 m_MinLod; + QT3DSF32 m_MaxLod; + QT3DSF32 m_LodBias; + NVRenderTextureCompareMode::Enum m_CompareMode; + NVRenderTextureCompareOp::Enum m_CompareOp; + QT3DSF32 m_Anisotropy; + QT3DSF32 m_BorderColor[4]; + + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] swizzleMode Texture swizzle mode + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail bias (unused) + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] (unused) + * + * @return No return. + */ + NVRenderTextureSampler( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL); + + /** + * @brief destructor + * + */ + virtual ~NVRenderTextureSampler(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendSamplerObject GetSamplerHandle() const + { + return m_SamplerHandle; + } + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendSamplerObject m_SamplerHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderShader.h b/src/Runtime/Source/render/Qt3DSRenderShader.h new file mode 100644 index 00000000..8d0a62c4 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShader.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_H +#define QT3DS_RENDER_SHADER_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderContext.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include <EASTL/string.h> + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< A shader program is an object composed of a multiple shaders (vertex, fragment, + ///geometry,....) + class NVRenderShader + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackend *m_Backend; ///< pointer to backend + NVConstDataRef<QT3DSI8> m_Source; ///< shader source code + bool m_Binary; ///< true for binary programs + eastl::string m_ErrorMessage; ///< contains the error message if linking fails + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram) + : m_Context(context) + , m_Foundation(fnd) + , m_Backend(context.GetBackend()) + , m_Source(source) + , m_Binary(binaryProgram) + { + } + + /// @brief destructor + ~NVRenderShader(){} + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + virtual bool IsValid() = 0; + + /** + * @brief Get Error Message + * + * @param[out] messageLength Pointer to error string + * @param[out] messageLength Size of error meesage + * + * @return no return + */ + virtual void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage) + { + // Since we do not have any error message just generate a generic one + if (m_Binary) + m_ErrorMessage = "Binary shader compilation failed"; + + *messageLength = m_ErrorMessage.size(); + errorMessage = m_ErrorMessage.c_str(); + } + + /** + * @brief Get Error Message + * + * + * @return error message. + */ + virtual const char *GetErrorMessage() + { + if (m_Binary) + m_ErrorMessage = "Binary shader compilation failed"; + + return m_ErrorMessage.c_str(); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h b/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h new file mode 100644 index 00000000..7fb57ffe --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h @@ -0,0 +1,448 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_CONSTANT_H +#define QT3DS_RENDER_SHADER_CONSTANT_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "foundation/Qt3DSMat33.h" +#include "foundation/Qt3DSMat44.h" +#include "EASTL/string.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + ///< forward declarations + class NVRenderContextImpl; + class NVRenderConstantBuffer; + + ///< A shader constant belongs to a program + class QT3DS_AUTOTEST_EXPORT NVRenderShaderConstantBase + { + public: + NVRenderBackend *m_Backend; ///< pointer to backend + CRegisteredString m_Name; ///< register constant name + QT3DSI32 m_Location; ///< constant index + QT3DSI32 m_ElementCount; ///< constant element count for arrays + NVRenderShaderDataTypes::Enum m_Type; ///< constant type + QT3DSI32 m_Binding; ///< sampler/imnage binding point + + public: + NVRenderShaderConstantBase(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding) + : m_Backend(backend) + , m_Name(name) + , m_Location(location) + , m_ElementCount(elementCount) + , m_Type(type) + , m_Binding(binding) + { + } + + NVRenderShaderDataTypes::Enum GetShaderConstantType() const { return m_Type; } + + virtual void Release() = 0; + }; + + ///< A general class for shader types + template <typename TDataType> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + TDataType m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + memset(&m_Value, 0, sizeof(TDataType)); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for textures + template <> + class NVRenderShaderConstant<NVRenderTexture2DPtr> : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for textures + template <> + class NVRenderShaderConstant<NVRenderTexture2DHandle> : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QVector<QT3DSU32> m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value.resize(elementCount); + m_Value.fill(QT3DS_MAX_U32); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for texture arrays + template <> + class NVRenderShaderConstant<NVRenderTexture2DArrayPtr> : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for cubemap textures + template <> + class NVRenderShaderConstant<NVRenderTextureCubePtr> : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for cubemap textures + template <> + class NVRenderShaderConstant<NVRenderTextureCubeHandle> : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QVector<QT3DSU32> m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value.resize(elementCount); + m_Value.fill(QT3DS_MAX_U32); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< A specialized class for texture image buffer + template <> + class NVRenderShaderConstant<NVRenderImage2DPtr> : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSU32 m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value = QT3DS_MAX_U32; + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + + ///< Base for any buffer ( constant, texture, ... ) which is used by this program + class NVRenderShaderBufferBase + { + public: + NVRenderContextImpl &m_Context; ///< pointer to context + CRegisteredString m_Name; ///< buffer name + QT3DSU32 m_Location; ///< program buffer block location + QT3DSU32 m_Binding; ///< program buffer binding + QT3DSI32 m_Size; ///< buffer size + + public: + NVRenderShaderBufferBase(NVRenderContextImpl &context, CRegisteredString name, + QT3DSI32 location, QT3DSI32 binding, QT3DSI32 size) + : m_Context(context) + , m_Name(name) + , m_Location(location) + , m_Binding(binding) + , m_Size(size) + { + } + + virtual void Release() = 0; + + virtual void Validate(NVRenderShaderProgram *inShader) = 0; + virtual void BindToProgram(NVRenderShaderProgram *inShader) = 0; + virtual void Update() = 0; + }; + + class NVRenderShaderConstantBuffer : public NVRenderShaderBufferBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer + NVRenderConstantBuffer *m_pCB; ///< pointer to constant buffer + + public: + NVRenderShaderConstantBuffer(NVRenderContextImpl &context, CRegisteredString name, + QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, + NVRenderConstantBuffer *pCB, NVFoundationBase &allocator) + : NVRenderShaderBufferBase(context, name, location, binding, size) + , m_Foundation(allocator) + , m_ParamCount(count) + , m_pCB(pCB) + { + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override + { + if (m_pCB) + m_pCB->release(); + + NVDelete(GetFoundation().getAllocator(), this); + } + + void Validate(NVRenderShaderProgram *inShader) override + { + // A constant buffer might not be set at first call + // due to the fact that they are compiled from a cache file + // Now it must exists. + if (m_pCB) + return; + + NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(m_Name); + if (cb) { + cb->SetupBuffer(inShader, m_Location, m_Size, m_ParamCount); + cb->addRef(); + m_pCB = cb; + } else { + QT3DS_ASSERT(false); + } + } + + void Update() override + { + if (m_pCB) + m_pCB->Update(); + } + + void BindToProgram(NVRenderShaderProgram *inShader) override + { + if (m_pCB) + m_pCB->BindToShaderProgram(inShader, m_Location, m_Binding); + } + }; + + class NVRenderShaderStorageBuffer : public NVRenderShaderBufferBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer + NVRenderStorageBuffer *m_pSB; ///< pointer to storage buffer + + public: + NVRenderShaderStorageBuffer(NVRenderContextImpl &context, CRegisteredString name, + QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, + NVRenderStorageBuffer *pSB, NVFoundationBase &allocator) + : NVRenderShaderBufferBase(context, name, location, binding, size) + , m_Foundation(allocator) + , m_ParamCount(count) + , m_pSB(pSB) + { + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override + { + if (m_pSB) + m_pSB->release(); + + NVDelete(GetFoundation().getAllocator(), this); + } + + void Validate(NVRenderShaderProgram * /*inShader*/) override + { + // A constant buffer might not be set at first call + // due to the fact that they are compile from a cache file + // Now it must exists. + if (m_pSB) + return; + + NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(m_Name); + if (sb) { + sb->addRef(); + m_pSB = sb; + } else { + QT3DS_ASSERT(false); + } + } + + void Update() override + { + if (m_pSB) + m_pSB->Update(); + } + + void BindToProgram(NVRenderShaderProgram * /*inShader*/) override + { + if (m_pSB) + m_pSB->BindToShaderProgram(m_Location); + } + }; + + class NVRenderShaderAtomicCounterBuffer : public NVRenderShaderBufferBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer + NVRenderAtomicCounterBuffer *m_pAcB; ///< pointer to atomic counter buffer + + public: + NVRenderShaderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString name, + QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count, + NVRenderAtomicCounterBuffer *pAcB, + NVFoundationBase &allocator) + : NVRenderShaderBufferBase(context, name, location, binding, size) + , m_Foundation(allocator) + , m_ParamCount(count) + , m_pAcB(pAcB) + { + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override + { + if (m_pAcB) + m_pAcB->release(); + + NVDelete(GetFoundation().getAllocator(), this); + } + + void Validate(NVRenderShaderProgram * /*inShader*/) override + { + // A constant buffer might not be set at first call + // due to the fact that they are compile from a cache file + // Now it must exists. + if (m_pAcB) + return; + + NVRenderAtomicCounterBuffer *acb = m_Context.GetAtomicCounterBuffer(m_Name); + if (acb) { + acb->addRef(); + m_pAcB = acb; + } else { + QT3DS_ASSERT(false); + } + } + + void Update() override + { + if (m_pAcB) + m_pAcB->Update(); + } + + void BindToProgram(NVRenderShaderProgram * /*inShader*/) override + { + if (m_pAcB) + m_pAcB->BindToShaderProgram(m_Location); + } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp new file mode 100644 index 00000000..09f1094b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp @@ -0,0 +1,1248 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "render/Qt3DSRenderVertexShader.h" +#include "render/Qt3DSRenderFragmentShader.h" +#include "render/Qt3DSRenderTessellationShader.h" +#include "render/Qt3DSRenderGeometryShader.h" +#include "render/Qt3DSRenderComputeShader.h" +#include "render/Qt3DSRenderImageTexture.h" + +namespace qt3ds { +namespace render { + + template <typename TDataType> + struct ShaderConstantApplier + { + bool force_compile_error; + }; + + template <> + struct ShaderConstantApplier<QT3DSI32> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32 &inValue, + QT3DSI32 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSI32_2> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_2 &inValue, + QT3DSI32_2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSI32_3> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_3 &inValue, + QT3DSI32_3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSI32_4> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_4 &inValue, + QT3DSI32_4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSRenderBool> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + const QT3DSRenderBool inValue, QT3DSRenderBool &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<bool_2> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_2 &inValue, + bool_2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<bool_3> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_3 &inValue, + bool_3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<bool_4> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_4 &inValue, + bool_4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSF32> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSF32 &inValue, + QT3DSF32 &oldValue) + { + if (count > 1 || !(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSVec2> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec2 &inValue, + QT3DSVec2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSVec3> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec3 &inValue, + QT3DSVec3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSVec4> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec4 &inValue, + QT3DSVec4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSU32> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32 &inValue, + QT3DSU32 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSU32_2> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_2 &inValue, + QT3DSU32_2 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSU32_3> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_3 &inValue, + QT3DSU32_3 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSU32_4> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_4 &inValue, + QT3DSU32_4 &oldValue) + { + if (!(inValue == oldValue)) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + &inValue.x); + oldValue = inValue; + } + } + }; + + template <> + struct ShaderConstantApplier<QT3DSMat33> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat33 inValue, + QT3DSMat33 &, bool inTranspose) + { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + inValue.front(), inTranspose); + } + }; + + template <> + struct ShaderConstantApplier<QT3DSMat44> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat44 inValue, + QT3DSMat44 &, bool inTranspose) + { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + inValue.front(), inTranspose); + } + + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVConstDataRef<QT3DSMat44> inValue, QT3DSMat44 &, bool inTranspose) + { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count, + reinterpret_cast<const GLfloat *>(inValue.begin()), + inTranspose); + } + }; + + template <> + struct ShaderConstantApplier<NVRenderTexture2DPtr> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTexture2DPtr inValue, QT3DSU32 &oldValue) + { + if (inValue) { + NVRenderTexture2D *texObj = reinterpret_cast<NVRenderTexture2D *>(inValue); + texObj->Bind(); + QT3DSU32 texUnit = texObj->GetTextureUnit(); + if (texUnit != oldValue) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + oldValue = texUnit; + } + } + } + }; + + template <> + struct ShaderConstantApplier<NVRenderTexture2DHandle> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, + QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTexture2DHandle inValue, QVector<QT3DSU32> &oldValue) + { + Q_UNUSED(type) + if (inValue) { + bool update = false; + for (int i = 0; i < count; i++) { + NVRenderTexture2D *texObj = reinterpret_cast<NVRenderTexture2D *>(inValue[i]); + QT3DSU32 texUnit = QT3DS_MAX_U32; + if (texObj) { + texObj->Bind(); + texUnit = texObj->GetTextureUnit(); + } + if (texUnit != oldValue[i]) { + update = true; + oldValue[i] = texUnit; + } + } + if (update) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, + NVRenderShaderDataTypes::NVRenderTexture2DPtr, + count, oldValue.data()); + } + } + }; + + template <> + struct ShaderConstantApplier<NVRenderTexture2DArrayPtr> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTexture2DArrayPtr inValue, QT3DSU32 &oldValue) + { + if (inValue) { + NVRenderTexture2DArray *texObj = + reinterpret_cast<NVRenderTexture2DArray *>(inValue); + texObj->Bind(); + QT3DSU32 texUnit = texObj->GetTextureUnit(); + if (texUnit != oldValue) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + oldValue = texUnit; + } + } + } + }; + + template <> + struct ShaderConstantApplier<NVRenderTextureCubePtr> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTextureCubePtr inValue, QT3DSU32 &oldValue) + { + if (inValue) { + NVRenderTextureCube *texObj = reinterpret_cast<NVRenderTextureCube *>(inValue); + texObj->Bind(); + QT3DSU32 texUnit = texObj->GetTextureUnit(); + if (texUnit != oldValue) { + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + oldValue = texUnit; + } + } + } + }; + + template <> + struct ShaderConstantApplier<NVRenderTextureCubeHandle> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, + QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTextureCubeHandle inValue, QVector<QT3DSU32> &oldValue) + { + Q_UNUSED(type) + if (inValue) { + bool update = false; + for (int i = 0; i < count; i++) { + NVRenderTextureCube *texObj = reinterpret_cast<NVRenderTextureCube *>(inValue[i]); + QT3DSU32 texUnit = QT3DS_MAX_U32; + if (texObj) { + texObj->Bind(); + texUnit = texObj->GetTextureUnit(); + } + if (texUnit != oldValue[i]) { + update = true; + oldValue[i] = texUnit; + } + } + if (update) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, + NVRenderShaderDataTypes::NVRenderTextureCubePtr, + count, oldValue.data()); + } + } + }; + + template <> + struct ShaderConstantApplier<NVRenderImage2DPtr> + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location, + QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderImage2DPtr inValue, QT3DSU32 &oldValue, QT3DSI32 binding) + { + if (inValue) { + NVRenderImage2D *imgObj = reinterpret_cast<NVRenderImage2D *>(inValue); + imgObj->Bind(binding); + QT3DSU32 texUnit = imgObj->GetTextureUnit(); + if (texUnit != oldValue) { + // on ES we need a explicit binding value + QT3DS_ASSERT(backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS + || binding != -1); + // this is not allowed on ES 3+ for image types + if (backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, + count, &texUnit); + + oldValue = texUnit; + } + } + } + }; + + NVRenderShaderProgram::NVRenderShaderProgram(NVRenderContextImpl &context, + NVFoundationBase &fnd, const char *programName, + bool separableProgram) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_ProgramName(programName) + , m_ProgramHandle(NULL) + , m_Constants(context.GetFoundation().getAllocator(), "NVRenderShaderProgram::m_Constants") + , m_ShaderBuffers(context.GetFoundation().getAllocator(), + "NVRenderShaderProgram::m_ShaderBuffers") + , m_ProgramType(ProgramType::Graphics) + { + m_ProgramHandle = m_Backend->CreateShaderProgram(separableProgram); + + QT3DS_ASSERT(m_ProgramHandle); + } + + NVRenderShaderProgram::~NVRenderShaderProgram() + { + m_Context.ShaderDestroyed(*this); + + if (m_ProgramHandle) + m_Backend->ReleaseShaderProgram(m_ProgramHandle); + + for (TShaderConstantMap::iterator iter = m_Constants.begin(), end = m_Constants.end(); + iter != end; ++iter) { + iter->second->Release(); + } + + m_Constants.clear(); + + for (TShaderBufferMap::iterator iter = m_ShaderBuffers.begin(), end = m_ShaderBuffers.end(); + iter != end; ++iter) { + iter->second->Release(); + } + + m_ShaderBuffers.clear(); + + m_ProgramHandle = NULL; + } + + template <typename TShaderObject> + void NVRenderShaderProgram::Attach(TShaderObject *pShader) + { + m_Backend->AttachShader(m_ProgramHandle, pShader->GetShaderHandle()); + } + + template <typename TShaderObject> + void NVRenderShaderProgram::Detach(TShaderObject *pShader) + { + m_Backend->DetachShader(m_ProgramHandle, pShader->GetShaderHandle()); + } + + static NVRenderShaderConstantBase * + ShaderConstantFactory(NVRenderBackend *backend, CRegisteredString inName, + NVFoundationBase &alloc, QT3DSI32 uniLoc, QT3DSI32 elementCount, + NVRenderShaderDataTypes::Enum inConstantType, QT3DSI32 binding) + { + switch (inConstantType) { +#define HANDLE_QT3DS_SHADER_DATA_TYPE(nv) \ + case NVRenderShaderDataTypes::nv: \ + return QT3DS_NEW(alloc.getAllocator(), NVRenderShaderConstant<nv>)( \ + backend, inName, uniLoc, elementCount, inConstantType, binding, alloc); + ITERATE_QT3DS_SHADER_DATA_TYPES +#undef HANDLE_QT3DS_SHADER_DATA_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return NULL; + } + + template <typename TShaderBufferType, typename TBufferDataType> + static NVRenderShaderBufferBase * + ShaderBufferFactory(NVRenderContextImpl &context, CRegisteredString inName, + NVFoundationBase &alloc, QT3DSI32 cbLoc, QT3DSI32 cbBinding, QT3DSI32 cbSize, + QT3DSI32 cbCount, TBufferDataType *pBuffer) + { + return QT3DS_NEW(alloc.getAllocator(), TShaderBufferType)(context, inName, cbLoc, cbBinding, + cbSize, cbCount, pBuffer, alloc); + } + + bool NVRenderShaderProgram::Link() + { + bool success = m_Backend->LinkProgram(m_ProgramHandle, m_ErrorMessage); + + if (success) { + char nameBuf[512]; + QT3DSI32 location, elementCount, binding; + NVRenderShaderDataTypes::Enum type; + + QT3DSI32 constantCount = m_Backend->GetConstantCount(m_ProgramHandle); + + QT3DS_FOREACH(idx, constantCount) + { + location = m_Backend->GetConstantInfoByID(m_ProgramHandle, idx, 512, &elementCount, + &type, &binding, nameBuf); + + // sampler arrays have different type + if (type == NVRenderShaderDataTypes::NVRenderTexture2DPtr && elementCount > 1) { + type = NVRenderShaderDataTypes::NVRenderTexture2DHandle; + } else if (type == NVRenderShaderDataTypes::NVRenderTextureCubePtr + && elementCount > 1) { + type = NVRenderShaderDataTypes::NVRenderTextureCubeHandle; + } + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + m_Constants.insert(eastl::make_pair( + theName, + ShaderConstantFactory(m_Backend, theName, m_Context.GetFoundation(), + location, elementCount, type, binding))); + } + } + + // next query constant buffers info + QT3DSI32 length, bufferSize, paramCount; + QT3DSI32 constantBufferCount = m_Backend->GetConstantBufferCount(m_ProgramHandle); + QT3DS_FOREACH(idx, constantBufferCount) + { + location = m_Backend->GetConstantBufferInfoByID( + m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); + + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + + // find constant buffer in our DB + NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(theName); + if (cb) { + cb->SetupBuffer(this, location, bufferSize, paramCount); + cb->addRef(); + } + + m_ShaderBuffers.insert(eastl::make_pair( + theName, + ShaderBufferFactory<NVRenderShaderConstantBuffer, NVRenderConstantBuffer>( + m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize, + paramCount, cb))); + } + } + + // next query storage buffers + QT3DSI32 storageBufferCount = m_Backend->GetStorageBufferCount(m_ProgramHandle); + QT3DS_FOREACH(idx, storageBufferCount) + { + location = m_Backend->GetStorageBufferInfoByID( + m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); + + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + + // find constant buffer in our DB + NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(theName); + if (sb) { + sb->addRef(); + } + + m_ShaderBuffers.insert(eastl::make_pair( + theName, + ShaderBufferFactory<NVRenderShaderStorageBuffer, NVRenderStorageBuffer>( + m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize, + paramCount, sb))); + } + } + + // next query atomic counter buffers + QT3DSI32 atomicBufferCount = m_Backend->GetAtomicCounterBufferCount(m_ProgramHandle); + QT3DS_FOREACH(idx, atomicBufferCount) + { + location = m_Backend->GetAtomicCounterBufferInfoByID( + m_ProgramHandle, idx, 512, ¶mCount, &bufferSize, &length, nameBuf); + + if (location != -1) { + CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); + + // find atomic counter buffer in our DB + // The buffer itself is not used in the program itself. + // Instead uniform variables are used but the interface to set the value is like + // for buffers. + // This is a bit insane but that is how it is. + // The theName variable contains the uniform name associated with an atomic + // counter buffer. + // We get the actual buffer name by searching for this uniform name + // See NVRenderTestAtomicCounterBuffer.cpp how the setup works + NVRenderAtomicCounterBuffer *acb = + m_Context.GetAtomicCounterBufferByParam(theName); + if (acb) { + acb->addRef(); + + m_ShaderBuffers.insert(eastl::make_pair( + acb->GetBufferName(), + ShaderBufferFactory<NVRenderShaderAtomicCounterBuffer, + NVRenderAtomicCounterBuffer>( + m_Context, acb->GetBufferName(), m_Context.GetFoundation(), + location, -1, bufferSize, paramCount, acb))); + } + } + } + } + + return success; + } + + void NVRenderShaderProgram::GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage) + { + *messageLength = m_ErrorMessage.size(); + errorMessage = m_ErrorMessage.c_str(); + } + + const char *NVRenderShaderProgram::GetErrorMessage() { return m_ErrorMessage.c_str(); } + + NVRenderShaderConstantBase *NVRenderShaderProgram::GetShaderConstant(const char *constantName) + { + TShaderConstantMap::iterator theIter = + m_Constants.find(m_Context.GetStringTable().RegisterStr(constantName)); + + if (theIter != m_Constants.end()) { + NVRenderShaderConstantBase *theConstant = + static_cast<NVRenderShaderConstantBase *>(theIter->second); + return theConstant; + } + + return NULL; + } + + NVRenderShaderBufferBase *NVRenderShaderProgram::GetShaderBuffer(const char *bufferName) + { + TShaderBufferMap::iterator theIter = + m_ShaderBuffers.find(m_Context.GetStringTable().RegisterStr(bufferName)); + + if (theIter != m_ShaderBuffers.end()) { + return theIter->second; + } + + return NULL; + } + + NVRenderContextImpl &NVRenderShaderProgram::GetRenderContext() { return m_Context; } + + template <typename TDataType> + void SetConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const TDataType &inValue, const QT3DSI32 inCount) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) { + NVRenderShaderConstant<TDataType> *inConstant = + static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase); + ShaderConstantApplier<TDataType>().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, + inValue, inConstant->m_Value); + } else { + QT3DS_ASSERT(false); + } + } + + template <typename TDataType> + void SetSamplerConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const TDataType &inValue, const QT3DSI32 inCount) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) { + NVRenderShaderConstant<TDataType> *inConstant = + static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase); + ShaderConstantApplier<TDataType>().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, + inValue, inConstant->m_Value, inConstant->m_Binding); + } else { + QT3DS_ASSERT(false); + } + } + + template <typename TDataType> + void SetMatrixConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const TDataType &inValue, const QT3DSI32 inCount, + bool inTranspose) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) { + NVRenderShaderConstant<TDataType> *inConstant = + static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase); + ShaderConstantApplier<TDataType>().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type, + inValue, inConstant->m_Value, inTranspose); + } else { + QT3DS_ASSERT(false); + } + } + + template <typename TDataType> + void SetMatrixConstantValueOfType(NVRenderShaderProgram *program, + NVRenderShaderConstantBase *inConstantBase, + const NVConstDataRef<TDataType> inValue, + const QT3DSI32 /*inCount*/, bool inTranspose) + { + if (inConstantBase == NULL) { + QT3DS_ASSERT(false); + return; + } + + QT3DS_ASSERT(inConstantBase->m_ElementCount >= (QT3DSI32)inValue.size()); + + if (inConstantBase->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) { + NVRenderShaderConstant<TDataType> *inConstant = + static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase); + ShaderConstantApplier<TDataType>().ApplyConstant( + program, inConstant->m_Backend, inConstant->m_Location, inValue.size(), + inConstant->m_Type, inValue, inConstant->m_Value, inTranspose); + } else { + QT3DS_ASSERT(false); + } + } + + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + QT3DSI32 inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSI32_2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSI32_3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSI32_4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + QT3DSRenderBool inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const bool_2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const bool_3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const bool_4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSF32 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSVec2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSVec3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSVec4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32_2 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32_3 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSU32_4 &inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSMat33 &inValue, const QT3DSI32 inCount, + bool inTranspose) + { + SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const QT3DSMat44 &inValue, const QT3DSI32 inCount, + bool inTranspose) + { + SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + const NVConstDataRef<QT3DSMat44> inValue, + const QT3DSI32 inCount) + { + SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, false); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2D *inValue, const QT3DSI32 inCount) + { + Q_UNUSED(inCount) + SetConstantValueOfType(this, inConstant, inValue, 1); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2D **inValue, + const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2DArray *inValue, + const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTextureCube *inValue, const QT3DSI32 inCount) + { + Q_UNUSED(inCount) + SetConstantValueOfType(this, inConstant, inValue, 1); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTextureCube **inValue, + const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderImage2D *inValue, const QT3DSI32 inCount) + { + SetSamplerConstantValueOfType(this, inConstant, inValue, inCount); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *, NVRenderDataBuffer *, + const QT3DSI32) + { + // this is merely a dummy right now + } + + void NVRenderShaderProgram::BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex) + { + NVRenderBackend::NVRenderBackendBufferObject obj(NULL); + if (inBuffer) + obj = inBuffer->GetBuffertHandle(); + m_Backend->ProgramSetStorageBuffer(inIndex, obj); + } + + namespace { + void WriteErrorMessage(NVFoundationBase &fnd, const char *tag, const char *message) + { + Q_UNUSED(fnd) + eastl::string messageData(nonNull(message)); + eastl::vector<eastl::string> lines; + for (eastl::string::size_type pos = messageData.find('\n'); pos != eastl::string::npos; + pos = messageData.find('\n')) { + eastl::string line = messageData.substr(0, pos); + messageData.erase(messageData.begin(), messageData.begin() + pos + 1); + if (line.size()) + qCCritical(INVALID_OPERATION, "%s: %s", tag, line.c_str()); + } + } + } + + Option<NVRenderVertexShader *> NVRenderShaderProgram::createVertexShader( + NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> vertexShaderSource, bool binaryProgram) + { + if (vertexShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderVertexShader(context, context.GetFoundation(), vertexShaderSource, + binaryProgram)); + } + + Option<NVRenderFragmentShader *> NVRenderShaderProgram::createFragmentShader( + NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> fragmentShaderSource, bool binaryProgram) + { + if (fragmentShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderFragmentShader(context, context.GetFoundation(), fragmentShaderSource, + binaryProgram)); + } + + Option<NVRenderTessControlShader *> + NVRenderShaderProgram::createTessControlShader(NVRenderContextImpl &context, + NVConstDataRef<QT3DSI8> tessControlShaderSource, + bool binaryProgram) + { + if (tessControlShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTessControlShader(context, context.GetFoundation(), + tessControlShaderSource, binaryProgram)); + } + + Option<NVRenderTessEvaluationShader *> + NVRenderShaderProgram::createTessEvaluationShader(NVRenderContextImpl &context, + NVConstDataRef<QT3DSI8> tessControlShaderSource, + bool binaryProgram) + { + if (tessControlShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTessEvaluationShader(context, context.GetFoundation(), + tessControlShaderSource, binaryProgram)); + } + + Option<NVRenderGeometryShader *> NVRenderShaderProgram::createGeometryShader( + NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> geometryShaderSource, bool binaryProgram) + { + if (geometryShaderSource.size() == 0) + return Empty(); + + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderGeometryShader(context, context.GetFoundation(), geometryShaderSource, + binaryProgram)); + } + + NVRenderVertFragCompilationResult NVRenderShaderProgram::Create( + NVRenderContextImpl &context, const char *programName, + NVConstDataRef<QT3DSI8> vertShaderSource, NVConstDataRef<QT3DSI8> fragShaderSource, + NVConstDataRef<QT3DSI8> tessControlShaderSource, + NVConstDataRef<QT3DSI8> tessEvaluationShaderSource, NVConstDataRef<QT3DSI8> geometryShaderSource, + bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram) + { + NVRenderVertFragCompilationResult result; + NVRenderShaderProgram *pProgram = NULL; + bool bProgramIsValid = false; + + result.mShaderName = programName; + + // our minimum requirement is a vertex and a fragment shader or geometry shader + // if we should treat it as a separate program we don't care + if (!separateProgram + && (vertShaderSource.size() == 0 + || (fragShaderSource.size() == 0 && geometryShaderSource.size() == 0))) { + qCCritical(INVALID_PARAMETER, + "Vertex or fragment (geometry) source have 0 length"); + QT3DS_ASSERT(false); + return result; + } + + if (binaryProgram && type != NVRenderShaderProgramBinaryType::NVBinary) { + qCCritical(INVALID_PARAMETER, "Unrecoginzed binary format"); + QT3DS_ASSERT(false); + return result; + } + + // first create and compile shader + Option<NVRenderVertexShader *> vtxShader = + createVertexShader(context, vertShaderSource, binaryProgram); + Option<NVRenderFragmentShader *> fragShader = + createFragmentShader(context, fragShaderSource, binaryProgram); + Option<NVRenderTessControlShader *> tcShader = + createTessControlShader(context, tessControlShaderSource, binaryProgram); + Option<NVRenderTessEvaluationShader *> teShader = + createTessEvaluationShader(context, tessEvaluationShaderSource, binaryProgram); + Option<NVRenderGeometryShader *> geShader = + createGeometryShader(context, geometryShaderSource, binaryProgram); + + bool vertexValid = (vtxShader.hasValue()) ? vtxShader.getValue()->IsValid() : true; + bool fragValid = (fragShader.hasValue()) ? fragShader.getValue()->IsValid() : true; + bool tcValid = (tcShader.hasValue()) ? tcShader.getValue()->IsValid() : true; + bool teValid = (teShader.hasValue()) ? teShader.getValue()->IsValid() : true; + bool geValid = (geShader.hasValue()) ? geShader.getValue()->IsValid() : true; + + if (vertexValid && fragValid && tcValid && teValid && geValid) { + // shaders were succesfuly created + pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)( + context, context.GetFoundation(), programName, separateProgram); + + if (pProgram) { + // attach programs + if (vtxShader.hasValue() && vtxShader.getValue()->IsValid()) + pProgram->Attach(vtxShader.getValue()); + if (fragShader.hasValue() && fragShader.getValue()->IsValid()) + pProgram->Attach(fragShader.getValue()); + if (tcShader.hasValue() && tcShader.getValue()->IsValid()) + pProgram->Attach(tcShader.getValue()); + if (teShader.hasValue() && teShader.getValue()->IsValid()) + pProgram->Attach(teShader.getValue()); + if (geShader.hasValue() && geShader.getValue()->IsValid()) + pProgram->Attach(geShader.getValue()); + + // link program + bProgramIsValid = pProgram->Link(); + } + } + + // if anything went wrong print out + if (!vertexValid || !fragValid || !tcValid || !teValid || !geValid || !bProgramIsValid) { + NVFoundationBase &foundation(context.GetFoundation()); + + if (!vertexValid) { + qCCritical(INTERNAL_ERROR, "Failed to generate vertex shader!!"); + qCCritical(INTERNAL_ERROR, "Vertex source:\n%s", + nonNull((const char *)vertShaderSource.begin())); + WriteErrorMessage(foundation, "Vertex compilation output:", + vtxShader.getValue()->GetErrorMessage()); + } + + if (!fragValid) { + qCCritical(INTERNAL_ERROR, "Failed to generate fragment shader!!"); + qCCritical(INTERNAL_ERROR, "Fragment source:\n%s", + nonNull((const char *)fragShaderSource.begin())); + WriteErrorMessage(foundation, "Fragment compilation output:", + fragShader.getValue()->GetErrorMessage()); + } + + if (!tcValid) { + qCCritical(INTERNAL_ERROR, + "Failed to generate tessellation control shader!!"); + qCCritical(INTERNAL_ERROR, "Tessellation control source:\n%s", + nonNull((const char *)tessControlShaderSource.begin())); + WriteErrorMessage(foundation, "Tessellation control compilation output:", + tcShader.getValue()->GetErrorMessage()); + } + + if (!teValid) { + qCCritical(INTERNAL_ERROR, + "Failed to generate tessellation evaluation shader!!"); + qCCritical(INTERNAL_ERROR, "Tessellation evaluation source:\n%s", + nonNull((const char *)tessEvaluationShaderSource.begin())); + WriteErrorMessage(foundation, "Tessellation evaluation compilation output:", + teShader.getValue()->GetErrorMessage()); + } + + if (!geValid) { + qCCritical(INTERNAL_ERROR, "Failed to generate geometry shader!!"); + qCCritical(INTERNAL_ERROR, "Geometry source:\n%s", + nonNull((const char *)geometryShaderSource.begin())); + WriteErrorMessage(foundation, "Geometry compilation output:", + geShader.getValue()->GetErrorMessage()); + } + + if (!bProgramIsValid && pProgram) { + qCCritical(INTERNAL_ERROR, "Failed to link program!!"); + WriteErrorMessage(foundation, "Program link output:", pProgram->GetErrorMessage()); + + // delete program + QT3DS_FREE(context.GetFoundation().getAllocator(), pProgram); + pProgram = NULL; + } + } + + // clean up + if (vtxShader.hasValue()) { + if (bProgramIsValid && vtxShader.getValue()->IsValid()) + pProgram->Detach(vtxShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), vtxShader.getValue()); + } + if (fragShader.hasValue()) { + if (bProgramIsValid && fragShader.getValue()->IsValid()) + pProgram->Detach(fragShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), fragShader.getValue()); + } + if (tcShader.hasValue()) { + if (bProgramIsValid && tcShader.getValue()->IsValid()) + pProgram->Detach(tcShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), tcShader.getValue()); + } + if (teShader.hasValue()) { + if (bProgramIsValid && teShader.getValue()->IsValid()) + pProgram->Detach(teShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), teShader.getValue()); + } + if (geShader.hasValue()) { + if (bProgramIsValid && geShader.getValue()->IsValid()) + pProgram->Detach(geShader.getValue()); + QT3DS_FREE(context.GetFoundation().getAllocator(), geShader.getValue()); + } + + // set program + result.mShader = pProgram; + + return result; + } + + NVRenderVertFragCompilationResult + NVRenderShaderProgram::CreateCompute(NVRenderContextImpl &context, const char *programName, + NVConstDataRef<QT3DSI8> computeShaderSource) + { + NVRenderVertFragCompilationResult result; + NVRenderShaderProgram *pProgram = NULL; + bool bProgramIsValid = true; + + result.mShaderName = programName; + + // check source + if (computeShaderSource.size() == 0) { + qCCritical(INVALID_PARAMETER, "compute source has 0 length"); + QT3DS_ASSERT(false); + return result; + } + + NVRenderComputeShader computeShader(context, context.GetFoundation(), computeShaderSource, + false); + + if (computeShader.IsValid()) { + // shaders were succesfuly created + pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)( + context, context.GetFoundation(), programName, false); + + if (pProgram) { + // attach programs + pProgram->Attach(&computeShader); + + // link program + bProgramIsValid = pProgram->Link(); + + // set program type + pProgram->SetProgramType(ProgramType::Compute); + } + } + + // if anything went wrong print out + if (!computeShader.IsValid() || !bProgramIsValid) { + NVFoundationBase &foundation(context.GetFoundation()); + + if (!computeShader.IsValid()) { + qCCritical(INTERNAL_ERROR, "Failed to generate compute shader!!"); + qCCritical(INTERNAL_ERROR, "Vertex source:\n%s", + nonNull((const char *)computeShaderSource.begin())); + WriteErrorMessage(foundation, "Compute shader compilation output:", + computeShader.GetErrorMessage()); + } + } + + // set program + result.mShader = pProgram; + + return result; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h new file mode 100644 index 00000000..054db64b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h @@ -0,0 +1,540 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SHADER_PROGRAM_H +#define QT3DS_RENDER_SHADER_PROGRAM_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShaderConstant.h" +#include "EASTL/string.h" +#include "EASTL/utility.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + ///< forward declarations + class NVRenderContextImpl; + class NVRenderVertexShader; + class NVRenderFragmentShader; + class NVRenderTessControlShader; + class NVRenderTessEvaluationShader; + class NVRenderGeometryShader; + class NVRenderShaderConstantBase; + class NVRenderShaderBufferBase; + class NVRenderComputeShader; + + typedef nvhash_map<CRegisteredString, NVRenderShaderConstantBase *> TShaderConstantMap; + typedef nvhash_map<CRegisteredString, NVRenderShaderBufferBase *> TShaderBufferMap; + + ///< A shader program is an object composed of a multiple shaders (vertex, fragment, + ///geometry,....) + class QT3DS_AUTOTEST_EXPORT NVRenderShaderProgram : public NVRefCounted + { + public: + struct ProgramType + { + enum Enum { Graphics, Compute }; + }; + + private: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + const char *m_ProgramName; /// Name of the program + NVRenderBackend::NVRenderBackendShaderProgramObject + m_ProgramHandle; ///< opaque backend handle + TShaderConstantMap m_Constants; ///< map of shader constants + TShaderBufferMap m_ShaderBuffers; ///< map of shader buffers + ProgramType::Enum m_ProgramType; ///< shader type + eastl::string m_ErrorMessage; ///< contains the error message if linking fails + + /** + * @brief create vertex shader + * + * @param[in] context Pointer to render context + * @param[in] vertexShaderSource Fragment shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to vertex shader object + */ + static Option<NVRenderVertexShader *> + createVertexShader(NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> vertexShaderSource, + bool binaryProgram = false); + + /** + * @brief create fragment shader + * + * @param[in] context Pointer to render context + * @param[in] fragmentShaderSource Fragment shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to fragment shader object + */ + static Option<NVRenderFragmentShader *> + createFragmentShader(NVRenderContextImpl &context, + NVConstDataRef<QT3DSI8> fragmentShaderSource, bool binaryProgram = false); + + /** + * @brief create tesselation control shader + * + * @param[in] context Pointer to render context + * @param[in] tessControlShaderSource Tessellation control shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to tessellation control shader + */ + static Option<NVRenderTessControlShader *> + createTessControlShader(NVRenderContextImpl &context, + NVConstDataRef<QT3DSI8> tessControlShaderSource, + bool binaryProgram = false); + + /** + * @brief create tesselation evaluation shader + * + * @param[in] context Pointer to render context + * @param[in] tessEvaluationShaderSource Tessellation evaluation shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to tessellation evaluation shader + */ + static Option<NVRenderTessEvaluationShader *> + createTessEvaluationShader(NVRenderContextImpl &context, + NVConstDataRef<QT3DSI8> tessEvaluationShaderSource, + bool binaryProgram = false); + + /** + * @brief create geometry shader + * + * @param[in] context Pointer to render context + * @param[in] geometryShaderSource Geometry shader source code + * @param[in] binaryProgram True if binary program + * + * @return pointer to geometry shader + */ + static Option<NVRenderGeometryShader *> + createGeometryShader(NVRenderContextImpl &context, + NVConstDataRef<QT3DSI8> geometryShaderSource, bool binaryProgram = false); + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] programName Pointer to string of program name + * @param[in] separableProgram True if this is a separable program + * + * @return No return. + */ + NVRenderShaderProgram(NVRenderContextImpl &context, NVFoundationBase &fnd, + const char *programName, bool separableProgram); + + /// destructor + ~NVRenderShaderProgram(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief attach a shader to the program + * + * @param[in] pShader Pointer to shader object + * + * @return No return. + */ + template <typename TShaderObject> + void Attach(TShaderObject *pShader); + + /** + * @brief detach a shader from the program + * + * @param[in] pShader Pointer to shader object + * + * @return No return. + */ + template <typename TShaderObject> + void Detach(TShaderObject *pShader); + + /** + * @brief link a program + * + * + * @return true if succesfuly linked. + */ + bool Link(); + + /** + * @brief set a shader type + * + * @param[in] type shader type ( graphics or compute ) + * + * @return No return. + */ + void SetProgramType(ProgramType::Enum type) { m_ProgramType = type; } + ProgramType::Enum GetProgramType() const { return m_ProgramType; } + + /** + * @brief Get Error Message + * + * @param[out] messageLength Pointer to error string + * @param[out] messageLength Size of error meesage + * + * @return no return. + */ + void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage); + + /** + * @brief Get Error Message + * + * + * @return error message. + */ + const char *GetErrorMessage(); + + /** + * @brief Query constant class + * + * @param[in] constantName Pointer to constant name + * + * @return return a pointer to a constant class. + */ + NVRenderShaderConstantBase *GetShaderConstant(const char *constantName); + + /** + * @brief Query a shader buffer (constant, ... ) + * + * @param[in] bufferName Pointer to constant name + * + * @return return a pointer to a constant class. + */ + NVRenderShaderBufferBase *GetShaderBuffer(const char *bufferName); + + // concrete set functions + void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSI32 inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSRenderBool inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSF32 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_2 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_3 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_4 &inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat33 &inValue, + const QT3DSI32 inCount, bool inTranspose = false); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat44 &inValue, + const QT3DSI32 inCount, bool inTranspose = false); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, + const NVConstDataRef<QT3DSMat44> inValue, const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D *inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D **inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2DArray *inValue, const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube *inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube **inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderImage2D *inValue, + const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderDataBuffer *inValue, + const QT3DSI32 inCount); + + /** + * @brief Template to set constant value via name + * + * @param[in] inConstantName Pointer to constant name + * @param[in] inValue Pointer to data + * @param[in] inCount Number of elements (array count) + * + * @return return a pointer to a constant class. + */ + template <typename TDataType> + void SetPropertyValue(const char *inConstantName, const TDataType &inValue, + const QT3DSI32 inCount = 1) + { + NVRenderShaderConstantBase *theConstant = GetShaderConstant(inConstantName); + + if (theConstant) { + if (theConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) { + SetConstantValue(theConstant, inValue, inCount); + } else { + // Types don't match or property not found + QT3DS_ASSERT(false); + } + } + } + + /** + * @brief Template to set constant value shader constant object + * + * @param[in] inConstant Pointer shader constant object + * @param[in] inValue Pointer to data + * @param[in] inCount Number of elements (array count) + * + * @return return a pointer to a constant class. + */ + template <typename TDataType> + void SetPropertyValue(NVRenderShaderConstantBase *inConstant, const TDataType &inValue, + const QT3DSI32 inCount = 1) + { + if (inConstant) { + if (inConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) { + SetConstantValue(inConstant, inValue, inCount); + } else { + // Types don't match or property not found + QT3DS_ASSERT(false); + } + } + } + + virtual void BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendShaderProgramObject GetShaderProgramHandle() const + { + return m_ProgramHandle; + } + + /** + * @brief get the context object + * + * @return context which this shader belongs to. + */ + NVRenderContextImpl &GetRenderContext(); + + /** + * @brief Create a shader program + * + * @param[in] context Pointer to context + * @param[in] programName Name of the program + * @param[in] vertShaderSource Vertex shader source code + * @param[in] fragShaderSource Fragment shader source code + * @param[in] tessControlShaderSource tessellation control shader source code + * @param[in] tessEvaluationShaderSource tessellation evaluation shader source code + * @param[in] separateProgram True if this will we a separate + * program + * @param[in] type Binary program type + * @param[in] binaryProgram True if program is binary + * + * @return a render result + */ + static NVRenderVertFragCompilationResult Create( + NVRenderContextImpl &context, const char *programName, + NVConstDataRef<QT3DSI8> vertShaderSource, NVConstDataRef<QT3DSI8> fragShaderSource, + NVConstDataRef<QT3DSI8> tessControlShaderSource = NVConstDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> tessEvaluationShaderSource = NVConstDataRef<QT3DSI8>(), + NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>(), + bool separateProgram = false, + NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown, + bool binaryProgram = false); + + /** + * @brief Create a compute shader program + * + * @param[in] context Pointer to context + * @param[in] programName Name of the program + * @param[in] computeShaderSource Compute shader source code + * + * @return a render result + */ + static NVRenderVertFragCompilationResult + CreateCompute(NVRenderContextImpl &context, const char *programName, + NVConstDataRef<QT3DSI8> computeShaderSource); + }; + + // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe + // way. + template <typename TDataType> + struct NVRenderCachedShaderProperty + { + NVRenderShaderProgram *m_Shader; ///< pointer to shader program + NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object + + NVRenderCachedShaderProperty(const QString &inConstantName, NVRenderShaderProgram &inShader) + : NVRenderCachedShaderProperty(qPrintable(inConstantName), inShader) + { + } + + NVRenderCachedShaderProperty(const char *inConstantName, NVRenderShaderProgram &inShader) + : m_Shader(&inShader) + , m_Constant(NULL) + { + NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName); + if (theConstant) { + if (theConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) { + m_Constant = theConstant; + } else { + // Property types do not match, this probably indicates that the shader changed + // while the + // code creating this object did not change. + QT3DS_ASSERT(false); + } + } + } + + NVRenderCachedShaderProperty() + : m_Shader(NULL) + , m_Constant(NULL) + { + } + + void Set(const TDataType &inValue) + { + if (m_Constant) + m_Shader->SetPropertyValue(m_Constant, inValue); + } + + bool IsValid() const { return m_Constant != 0; } + }; + + template <typename TDataType, int size> + struct NVRenderCachedShaderPropertyArray + { + NVRenderShaderProgram *m_Shader; ///< pointer to shader program + NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object + TDataType m_array[size]; + + NVRenderCachedShaderPropertyArray(const QString &inConstantName, + NVRenderShaderProgram &inShader) + : NVRenderCachedShaderPropertyArray(qPrintable(inConstantName), inShader) + { + + } + + NVRenderCachedShaderPropertyArray(const char *inConstantName, + NVRenderShaderProgram &inShader) + : m_Shader(&inShader) + , m_Constant(nullptr) + { + memset(m_array, 0, sizeof(m_array)); + NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName); + if (theConstant) { + if (theConstant->m_ElementCount > 1 && theConstant->m_ElementCount <= size && + theConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap<TDataType*>::GetType()) { + m_Constant = theConstant; + } else { + // Property types do not match, this probably indicates that the shader changed + // while the code creating this object did not change. + QT3DS_ASSERT(false); + } + } + } + + NVRenderCachedShaderPropertyArray() + : m_Shader(nullptr) + , m_Constant(nullptr) + { + memset(m_array, 0, sizeof(m_array)); + } + + void Set(int count) + { + if (m_Constant) + m_Shader->SetPropertyValue(m_Constant, (TDataType*)m_array, qMin(size, count)); + } + + bool IsValid() const { return m_Constant != 0; } + }; + + // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe + // way. + template <typename TDataType> + struct NVRenderCachedShaderBuffer + { + NVRenderShaderProgram *m_Shader; ///< pointer to shader program + TDataType m_ShaderBuffer; ///< poiner to shader buffer object + + NVRenderCachedShaderBuffer(const char *inShaderBufferName, NVRenderShaderProgram &inShader) + : m_Shader(&inShader) + , m_ShaderBuffer(NULL) + { + TDataType theShaderBuffer = + static_cast<TDataType>(inShader.GetShaderBuffer(inShaderBufferName)); + if (theShaderBuffer) { + m_ShaderBuffer = theShaderBuffer; + } + } + NVRenderCachedShaderBuffer() + : m_Shader(NULL) + , m_ShaderBuffer(NULL) + { + } + + void Set() + { + if (m_ShaderBuffer) { + m_ShaderBuffer->Validate(m_Shader); + m_ShaderBuffer->Update(); + m_ShaderBuffer->BindToProgram(m_Shader); + } + } + + bool IsValid() const { return m_ShaderBuffer != 0; } + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp new file mode 100644 index 00000000..ab632189 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderStorageBuffer.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderShaderProgram.h" + +namespace qt3ds { +namespace render { + + NVRenderStorageBuffer::NVRenderStorageBuffer(NVRenderContextImpl &context, + CRegisteredString bufferName, size_t size, + NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data, NVRenderDataBuffer *pBuffer) + : NVRenderDataBuffer(context, context.GetFoundation(), size, + NVRenderBufferBindValues::Storage, usageType, data) + , m_Name(bufferName) + , m_WrappedBuffer(pBuffer) + , m_Dirty(true) + { + QT3DS_ASSERT(context.IsStorageBufferSupported()); + + if (pBuffer) + pBuffer->addRef(); + } + + NVRenderStorageBuffer::~NVRenderStorageBuffer() + { + if (m_WrappedBuffer) + m_WrappedBuffer->release(); + + m_Context.BufferDestroyed(*this); + } + + void NVRenderStorageBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + if (m_WrappedBuffer) + m_WrappedBuffer->Bind(); + else + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + void NVRenderStorageBuffer::BindToShaderProgram(QT3DSU32 index) + { + m_Backend->ProgramSetStorageBuffer( + index, (m_WrappedBuffer) ? m_WrappedBuffer->GetBuffertHandle() : m_BufferHandle); + } + + void NVRenderStorageBuffer::Update() + { + // we only update the buffer if it is dirty and we actually have some data + if (m_Dirty && m_BufferData.size()) { + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType, + m_BufferData.begin()); + m_Dirty = false; + } + } + + void NVRenderStorageBuffer::UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data) + { + // we only update the buffer if it is not just a wrapper + if (!m_WrappedBuffer) + m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType, + data.begin() + offset); + } + + NVRenderStorageBuffer * + NVRenderStorageBuffer::Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer) + { + NVFoundationBase &fnd(context.GetFoundation()); + NVRenderStorageBuffer *retval = NULL; + + if (context.IsStorageBufferSupported()) { + CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName)); + QT3DSU32 cbufSize = sizeof(NVRenderStorageBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "StorageBuffer"); + retval = new (newMem) NVRenderStorageBuffer( + context, theBufferName, size, usageType, + toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size()), pBuffer); + } else { + QString errorMsg = QObject::tr("Shader storage buffers are not supported: %1") + .arg(bufferName); + qCCritical(INVALID_OPERATION) << errorMsg; + QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); + } + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h new file mode 100644 index 00000000..fefe6b08 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "foundation/StringTable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + // forward declaration + class NVRenderContextImpl; + class NVRenderVertexBuffer; + + ///< Constant (uniform) buffer representation + class NVRenderStorageBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] bufferName Name of the buffer. Must match the name used in programs + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * @param[in] pBuffer Pointer to the buffer + * + * @return No return. + */ + NVRenderStorageBuffer(NVRenderContextImpl &context, CRegisteredString bufferName, + size_t size, NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data, NVRenderDataBuffer *pBuffer = NULL); + + ///< destructor + virtual ~NVRenderStorageBuffer(); + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief bind the buffer to a shader program + * + * @param[in] index Index of the constant buffer within the program + * + * @return no return. + */ + virtual void BindToShaderProgram(QT3DSU32 index); + + /** + * @brief update the buffer to hardware + * + * @return no return. + */ + virtual void Update(); + + /** + * @brief update a piece of memory directly within the storage buffer + * + * Note: When you use this function you should know what you are doing. + * The memory layout within C++ must exactly match the memory layout in the + *shader. + * We use std140 (430) layout which guarantees a specific layout behavior across + *all HW vendors. + * How the memory layout is computed can be found in the GL spec. + * + * @param[in] offset offset into storage buffer + * @param[in] data pointer to data + * + * @return no return + */ + void UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data); + + /** + * @brief get the buffer name + * + * @return the buffer name + */ + CRegisteredString GetBufferName() const { return m_Name; } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_BufferHandle); + } + + /** + * @brief create a NVRenderStorageBuffer object + * + * @param[in] context Pointer to context + * @param[in] size Size of the buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + * application. + * + * @return the buffer object or NULL + */ + static NVRenderStorageBuffer *Create(NVRenderContextImpl &context, const char *bufferName, + NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef<QT3DSU8> bufferData, + NVRenderDataBuffer *pBuffer); + + private: + CRegisteredString m_Name; ///< buffer name + NVRenderDataBuffer *m_WrappedBuffer; ///< pointer to wrapped buffer + bool m_Dirty; ///< true if buffer is dirty + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderSync.cpp b/src/Runtime/Source/render/Qt3DSRenderSync.cpp new file mode 100644 index 00000000..02d153a6 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSync.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSync.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSFoundation.h" + +namespace qt3ds { +namespace render { + + NVRenderSync::NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_SyncHandle(NULL) + { + } + + NVRenderSync::~NVRenderSync() + { + if (m_SyncHandle) + m_Backend->ReleaseSync(m_SyncHandle); + } + + void NVRenderSync::Sync() + { + // On every sync call we need to create a new sync object + // A sync object can only be used once + + // First delete the old object + // We can safely do this because it is actually not deleted until + // it is unused + if (m_SyncHandle) + m_Backend->ReleaseSync(m_SyncHandle); + + m_SyncHandle = + m_Backend->CreateSync(NVRenderSyncType::GpuCommandsComplete, NVRenderSyncFlags()); + } + + void NVRenderSync::Wait() + { + // wait until the sync object is signaled or a timeout happens + if (m_SyncHandle) + m_Backend->WaitSync(m_SyncHandle, NVRenderCommandFlushFlags(), 0); + } + + NVRenderSync *NVRenderSync::Create(NVRenderContextImpl &context) + { + if (!context.IsCommandSyncSupported()) + return NULL; + + NVRenderSync *retval = QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderSync)(context, context.GetFoundation()); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderSync.h b/src/Runtime/Source/render/Qt3DSRenderSync.h new file mode 100644 index 00000000..9dfeb28a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderSync.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_SYNC_H +#define QT3DS_RENDER_SYNC_H +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + class NVRenderBackend; + + ///< Base class + class NVRenderSync : public NVRefCounted + { + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendSyncObject m_SyncHandle; ///< opaque backend handle + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd); + + virtual ~NVRenderSync(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + /** + * @brief Get sync type + * + * @return Return query type + */ + virtual NVRenderSyncType::Enum GetSyncType() const + { + return NVRenderSyncType::GpuCommandsComplete; + } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief Create a sync object and place it in command stream. + * Note every syncobject can only be used once. + * This function creates a new sync object on ever call + * and deletes the previous one + * + * @return no return. + */ + virtual void Sync(); + + /** + * @brief Wait for a sync to be signaled + * Note this blocks until the sync is signaled + * + * @return no return. + */ + virtual void Wait(); + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendSyncObject GetSyncHandle() const + { + return m_SyncHandle; + } + + /* + * @brief static creation function + * + * @return a sync object on success + */ + static NVRenderSync *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp new file mode 100644 index 00000000..7a0fd897 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderTessellationShader.h" + +namespace qt3ds { +namespace render { + + NVRenderTessControlShader::NVRenderTessControlShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, + bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateTessControlShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderTessControlShader::~NVRenderTessControlShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseTessControlShader(m_ShaderHandle); + } + } + + NVRenderTessEvaluationShader::NVRenderTessEvaluationShader(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, + bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = + m_Backend->CreateTessEvaluationShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderTessEvaluationShader::~NVRenderTessEvaluationShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseTessEvaluationShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h new file mode 100644 index 00000000..b69e56b1 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TESSELLATION_SHADER_H +#define QT3DS_RENDER_TESSELLATION_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a tessellation control shader + class NVRenderTessControlShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderTessControlShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram); + + /// @brief destructor + ~NVRenderTessControlShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTessControlShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendTessControlShaderObject + m_ShaderHandle; ///< opaque backend handle + }; + + ///< This class represents a tessellation evaluation shader + class NVRenderTessEvaluationShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderTessEvaluationShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram); + + /// @brief destructor + ~NVRenderTessEvaluationShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTessEvaluationShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendTessEvaluationShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp b/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp new file mode 100644 index 00000000..c5ea4750 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTexture2D::NVRenderTexture2D(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : NVRenderTextureBase(context, fnd, texTarget) + , m_Width(0) + , m_Height(0) + { + } + + NVRenderTexture2D::~NVRenderTexture2D() { m_Context.TextureDestroyed(*this); } + + STextureDetails NVRenderTexture2D::GetTextureDetails() const + { + return STextureDetails(m_Width, m_Height, 0, m_SampleCount, m_Format); + } + + void NVRenderTexture2D::SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, + QT3DSU32 height, NVRenderTextureFormats::Enum format, + NVRenderTextureFormats::Enum formatDest) + { + QT3DS_ASSERT(m_TextureHandle); + + // check if we should compress this texture + + if (inMipLevel == 0) { + m_Width = width; + m_Height = height; + m_Format = format; + + // We re-use textures and this might have been a MSAA texture before + // for resue we must completely destroy the texture object and create a new one + // The same is true for immutable textures + if (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS || m_Immutable) { + m_Backend->ReleaseTexture(m_TextureHandle); + m_TexTarget = NVRenderTextureTargetType::Texture2D; + m_SampleCount = 1; + m_TextureHandle = m_Backend->CreateTexture(); + } + + if (NVRenderTextureFormats::isCompressedTextureFormat(formatDest)) { + bool compress = NVRenderTextureFormats::isUncompressedTextureFormat(format); + bool appropriateSizes = ((width % 4) || (height % 4)) == false; + + // we only compress multiple of 4 textures + if (compress && !appropriateSizes) + compress = false; + + if (compress) { + // This seems like a very dubious line here. If we are compressing then the + // image + // is really 1/4 the width and height? - CN + m_Width = width / 4; + m_Height = height / 4; + m_Format = formatDest; + } + } else if (NVRenderTextureFormats::isUncompressedTextureFormat(formatDest)) { + m_Format = formatDest; + } + } + + if (m_MaxMipLevel < inMipLevel) { + m_MaxMipLevel = inMipLevel; + } + + // get max size and check value + QT3DSU32 maxWidth, maxHeight; + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (width > maxWidth || height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + } + if (NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Backend->SetTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width, + height, 0, format, newBuffer.begin()); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) { + m_Backend->SetCompressedTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, format, + width, height, 0, newBuffer.size(), + newBuffer.begin()); + } + // Set our texture parameters to a default that will look the best + if (inMipLevel > 0) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + + void NVRenderTexture2D::SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum formaInternal, + NVRenderTextureFormats::Enum format, + NVDataRef<QT3DSU8> dataBuffer) + { + QT3DS_ASSERT(m_TextureHandle); + + if (!m_Context.IsShaderImageLoadStoreSupported()) { + qCCritical(INVALID_OPERATION, "The extension Shader_Image_Load_Store is not supported"); + return; + } + + m_Width = width; + m_Height = height; + m_Format = formaInternal; + if (format == NVRenderTextureFormats::Unknown) + format = formaInternal; + + // get max size and check value + QT3DSU32 maxWidth, maxHeight; + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (width > maxWidth || height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + } + + if (inLevels < 1) { + qCCritical(INVALID_PARAMETER, "inLevels is less than 1 (%d)", inLevels); + } + + m_MaxMipLevel = inLevels - 1; // we count from 0 + + // only uncompressed formats are supported and no depth + if (NVRenderTextureFormats::isUncompressedTextureFormat(formaInternal)) { + m_Backend->CreateTextureStorage2D(m_TextureHandle, m_TexTarget, inLevels, formaInternal, + width, height); + + m_Immutable = true; + m_TexTarget = NVRenderTextureTargetType::Texture2D; + + if (dataBuffer.size() > 0) + m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, 0, 0, 0, width, height, + format, dataBuffer.begin()); + + if (inLevels > 1) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + } + + void NVRenderTexture2D::SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + QT3DS_ASSERT(m_MaxMipLevel == 0); + + m_TexTarget = NVRenderTextureTargetType::Texture2D_MS; + + QT3DSU32 maxWidth, maxHeight; + m_Context.getMaxTextureSize(maxWidth, maxHeight); + if (width > maxWidth || height > maxHeight) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + maxWidth, maxHeight); + } + + QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)); + + m_Backend->SetMultisampledTextureData2D(m_TextureHandle, m_TexTarget, sampleCount, format, + width, height, true); + + m_Width = width; + m_Height = height; + m_SampleCount = sampleCount; + m_Format = format; + } + + void NVRenderTexture2D::SetTextureSubData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, + QT3DSU32 inXOffset, QT3DSU32 inYOffset, QT3DSU32 width, + QT3DSU32 height, NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + + if (!NVRenderTextureFormats::isUncompressedTextureFormat(format)) { + qCCritical(INVALID_PARAMETER, "Cannot set sub data for depth or compressed formats"); + QT3DS_ASSERT(false); + return; + } + QT3DSU32 subRectStride = width * NVRenderTextureFormats::getSizeofFormat(format); + if (newBuffer.size() < subRectStride * height) { + qCCritical(INVALID_PARAMETER, "Invalid sub rect buffer size"); + QT3DS_ASSERT(false); + return; + } + // nop + if (width == 0 || height == 0) + return; + + if (inXOffset + width > m_Width || inYOffset + height > m_Height) { + qCCritical(INVALID_PARAMETER, "Sub rect outside existing image bounds"); + QT3DS_ASSERT(false); + return; + } + + // not handled yet + QT3DS_ASSERT(!NVRenderTextureFormats::isDepthTextureFormat(format)); + + m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, inMipLevel, inXOffset, + inYOffset, width, height, format, newBuffer.begin()); + } + + void NVRenderTexture2D::GenerateMipmaps(NVRenderHint::Enum genType) + { + applyTexParams(); + m_Backend->GenerateMipMaps(m_TextureHandle, m_TexTarget, genType); + QT3DSU32 maxDim = (m_Width >= m_Height) ? m_Width : m_Height; + m_MaxMipLevel = static_cast<QT3DSU32>(logf((float)maxDim) / logf(2.0f)); + // we never create more level than m_MaxLevel + m_MaxMipLevel = qt3ds::NVMin(m_MaxMipLevel, (QT3DSU32)m_MaxLevel); + } + + void NVRenderTexture2D::Bind() + { + m_TextureUnit = m_Context.GetNextTextureUnit(); + + m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); + + applyTexParams(); + applyTexSwizzle(); + } + + NVRenderTexture2D *NVRenderTexture2D::Create(NVRenderContextImpl &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTexture2D)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2D.h b/src/Runtime/Source/render/Qt3DSRenderTexture2D.h new file mode 100644 index 00000000..29c7c1b4 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2D.h @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTextureBase.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + class NVRenderTexture2D : public NVRenderTextureBase, public NVRenderImplemented + { + + private: + QT3DSU32 m_Width; ///< texture width + QT3DSU32 m_Height; ///< texture height + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTexture2D( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D); + + virtual ~NVRenderTexture2D(); + + // Get the texture details for mipmap level 0 if it was set. + STextureDetails GetTextureDetails() const override; + + /** + * @brief Create GL texture object and upload data + * + * @param[in] newBuffer Texture data for level 0 + * @param[in] inMipLevel Texture level count + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] format Texture data format + * @param[in] formaInternal Texture internal format + * + * @return No return. + */ + virtual void SetTextureData( + NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format, + NVRenderTextureFormats::Enum formaInternal = NVRenderTextureFormats::Unknown); + + /** + * @brief Create memory storage for a texture object + * This create a texture storage which is immutable in size and format + * Use this for textures used within compute shaders + * + * @param[in] inLevels Texture level count + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] formaInternal Texture internal format + * @param[in] format Texture data format of dataBuffer + * @param[in] dataBuffer Texture data for level 0 + * + * @return No return. + */ + virtual void + SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum formaInternal, + NVRenderTextureFormats::Enum format = NVRenderTextureFormats::Unknown, + NVDataRef<QT3DSU8> dataBuffer = NVDataRef<QT3DSU8>()); + + virtual void SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format); + + bool IsMultisampleTexture() const override + { + return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS); + } + QT3DSU32 GetSampleCount() const override { return m_SampleCount; } + bool IsImmutableTexture() const override { return m_Immutable; } + + // Update a sub-rect of the image. newBuffer is expected to be a continguous subrect of the + // image. + virtual void SetTextureSubData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 inXOffset, + QT3DSU32 inYOffset, QT3DSU32 inSubImageWidth, + QT3DSU32 inSubImageHeight, NVRenderTextureFormats::Enum format); + // Generate a set of mipmaps from mipLevel( 0 ). Uses the graphis layer to do this if + // possible + // glGenerateMipmap + virtual void GenerateMipmaps(NVRenderHint::Enum genType = NVRenderHint::Nicest); + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + void Bind() override; + + QT3DSU32 GetNumMipmaps() override { return m_MaxMipLevel; } + + /** + * @brief Query if texture needs coordinate swizzle + * + * @return texture swizzle mode + */ + NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode() override + { + // if our backend supports hardware texture swizzle then there is no need for a shader + // swizzle + return (m_Backend->GetRenderBackendCap( + NVRenderBackend::NVRenderBackendCaps::TexSwizzle)) + ? NVRenderTextureSwizzleMode::NoSwizzle + : m_Backend->GetTextureSwizzleMode(m_Format); + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_TextureHandle); + } + + static NVRenderTexture2D *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp new file mode 100644 index 00000000..fc0dfa45 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "render/Qt3DSRenderTexture2DArray.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTexture2DArray::NVRenderTexture2DArray(NVRenderContextImpl &context, + NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : NVRenderTextureBase(context, fnd, texTarget) + , m_Width(0) + , m_Height(0) + , m_Slices(0) + { + } + + NVRenderTexture2DArray::~NVRenderTexture2DArray() { m_Context.TextureDestroyed(*this); } + + void NVRenderTexture2DArray::SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, + QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices, + NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + + if (inMipLevel == 0) { + m_Width = width; + m_Height = height; + m_Slices = slices; + m_Format = format; + m_MaxMipLevel = inMipLevel; + } + + if (m_MaxMipLevel < inMipLevel) { + m_MaxMipLevel = inMipLevel; + } + + // get max size and check value + QT3DSI32 theMaxLayerSize, theMaxSize; + m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, + &theMaxSize); + m_Backend->GetRenderBackendValue( + NVRenderBackend::NVRenderBackendQuery::MaxTextureArrayLayers, &theMaxLayerSize); + if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize + || slices > (QT3DSU32)theMaxLayerSize) { + qCCritical(INVALID_OPERATION, + "Width or height or Slices is greater than max texture size (%d, %d, %d)", + theMaxSize, theMaxSize, theMaxLayerSize); + } + + // currently we do not support compressed texture arrays + QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)); + + if (NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Backend->SetTextureData3D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width, + height, slices, 0, format, newBuffer.begin()); + } + + // Set our texture parameters to a default that will look the best + if (inMipLevel > 0) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + + STextureDetails NVRenderTexture2DArray::GetTextureDetails() const + { + return STextureDetails(m_Width, m_Height, m_Slices, m_SampleCount, m_Format); + } + + void NVRenderTexture2DArray::Bind() + { + m_TextureUnit = m_Context.GetNextTextureUnit(); + + m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); + + applyTexParams(); + applyTexSwizzle(); + } + + NVRenderTexture2DArray *NVRenderTexture2DArray::Create(NVRenderContextImpl &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTexture2DArray)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h new file mode 100644 index 00000000..30ed6dbb --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTextureBase.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + class QT3DS_AUTOTEST_EXPORT NVRenderTexture2DArray : public NVRenderTextureBase + { + private: + QT3DSU32 m_Width; ///< texture width + QT3DSU32 m_Height; ///< texture height + QT3DSU32 m_Slices; ///< texture slices + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTexture2DArray( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D_Array); + + virtual ~NVRenderTexture2DArray(); + + /** + * @brief constructor + * + * @param[in] newBuffer Pointer to pixel buffer + * @param[in] inMipLevel Pointer to foundation + * @param[in] width Texture target + * @param[in] height Texture target + * @param[in] slices Texture target + * @param[in] format Texture target + * + * @return No return. + */ + void SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height, + QT3DSU32 slices, NVRenderTextureFormats::Enum format); + + // Get the texture details for mipmap level 0 if it was set. + STextureDetails GetTextureDetails() const override; + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + void Bind() override; + + /** + * @brief create a texture array object + * + * + * @ return a texture array object + */ + static NVRenderTexture2DArray *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp b/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp new file mode 100644 index 00000000..d055d72c --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "render/Qt3DSRenderTextureBase.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTextureBase::NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : m_Context(context) + , m_Foundation(fnd) + , mRefCount(0) + , m_Backend(context.GetBackend()) + , m_TextureHandle(NULL) + , m_TextureUnit(QT3DS_MAX_U32) + , m_SamplerParamsDirty(true) + , m_TexStateDirty(false) + , m_SampleCount(1) + , m_Format(NVRenderTextureFormats::Unknown) + , m_TexTarget(texTarget) + , m_BaseLevel(0) + , m_MaxLevel(1000) + , m_MaxMipLevel(0) + , m_Immutable(false) + { + m_TextureHandle = m_Backend->CreateTexture(); + m_Sampler = QT3DS_NEW(m_Context.GetFoundation().getAllocator(), + NVRenderTextureSampler)(context, context.GetFoundation()); + } + + NVRenderTextureBase::~NVRenderTextureBase() + { + if (m_Sampler) + QT3DS_FREE(m_Context.GetFoundation().getAllocator(), m_Sampler); + if (m_TextureHandle) + m_Backend->ReleaseTexture(m_TextureHandle); + } + + void NVRenderTextureBase::SetBaseLevel(QT3DSI32 value) + { + if (m_BaseLevel != value) { + m_BaseLevel = value; + m_TexStateDirty = true; + } + } + + void NVRenderTextureBase::SetMaxLevel(QT3DSI32 value) + { + if (m_MaxLevel != value) { + m_MaxLevel = value; + m_TexStateDirty = true; + } + } + + void NVRenderTextureBase::SetMinFilter(NVRenderTextureMinifyingOp::Enum value) + { + if (m_Sampler->m_MinFilter != value) { + m_Sampler->m_MinFilter = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetMagFilter(NVRenderTextureMagnifyingOp::Enum value) + { + if (m_Sampler->m_MagFilter != value) { + m_Sampler->m_MagFilter = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureWrapS(NVRenderTextureCoordOp::Enum value) + { + if (m_Sampler->m_WrapS != value) { + m_Sampler->m_WrapS = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureWrapT(NVRenderTextureCoordOp::Enum value) + { + if (m_Sampler->m_WrapT != value) { + m_Sampler->m_WrapT = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureCompareMode(NVRenderTextureCompareMode::Enum value) + { + if (m_Sampler->m_CompareMode != value) { + m_Sampler->m_CompareMode = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value) + { + if (m_Sampler->m_CompareOp != value) { + m_Sampler->m_CompareOp = value; + m_SamplerParamsDirty = true; + } + } + + void NVRenderTextureBase::applyTexParams() + { + if (m_SamplerParamsDirty) { + m_Backend->UpdateSampler(m_Sampler->GetSamplerHandle(), m_TexTarget, + m_Sampler->m_MinFilter, m_Sampler->m_MagFilter, + m_Sampler->m_WrapS, m_Sampler->m_WrapT, m_Sampler->m_WrapR, + m_Sampler->m_MinLod, m_Sampler->m_MaxLod, m_Sampler->m_LodBias, + m_Sampler->m_CompareMode, m_Sampler->m_CompareOp); + + m_SamplerParamsDirty = false; + } + + if (m_TexStateDirty) { + m_Backend->UpdateTextureObject(m_TextureHandle, m_TexTarget, m_BaseLevel, m_MaxLevel); + m_TexStateDirty = false; + } + } + + void NVRenderTextureBase::applyTexSwizzle() + { + NVRenderTextureSwizzleMode::Enum theSwizzleMode = + m_Backend->GetTextureSwizzleMode(m_Format); + if (theSwizzleMode != m_Sampler->m_SwizzleMode) { + m_Sampler->m_SwizzleMode = theSwizzleMode; + m_Backend->UpdateTextureSwizzle(m_TextureHandle, m_TexTarget, theSwizzleMode); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureBase.h b/src/Runtime/Source/render/Qt3DSRenderTextureBase.h new file mode 100644 index 00000000..872a634e --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureBase.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + struct STextureDetails + { + QT3DSU32 m_Width; + QT3DSU32 m_Height; + QT3DSU32 m_Depth; + QT3DSU32 m_SampleCount; + NVRenderTextureFormats::Enum m_Format; + + STextureDetails(QT3DSU32 w, QT3DSU32 h, QT3DSU32 d, QT3DSU32 samples, NVRenderTextureFormats::Enum f) + : m_Width(w) + , m_Height(h) + , m_Depth(d) + , m_SampleCount(samples) + , m_Format(f) + { + } + STextureDetails() + : m_Width(0) + , m_Height(0) + , m_Depth(0) + , m_SampleCount(1) + , m_Format(NVRenderTextureFormats::Unknown) + { + } + }; + + class NVRenderTextureBase : public NVRefCounted + { + + protected: + NVRenderContextImpl &m_Context; ///< pointer to context + NVFoundationBase &m_Foundation; ///< pointer to foundation + volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation + NVRenderBackend *m_Backend; ///< pointer to backend + NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; ///< opaque backend handle + QT3DSU32 m_TextureUnit; ///< texture unit this texture should use + bool m_SamplerParamsDirty; ///< true if sampler state is dirty + bool m_TexStateDirty; ///< true if texture object state is dirty + QT3DSU32 m_SampleCount; ///< texture height + NVRenderTextureFormats::Enum m_Format; ///< texture format + NVRenderTextureTargetType::Enum m_TexTarget; ///< texture target + NVRenderTextureSampler *m_Sampler; ///< current texture sampler state + QT3DSI32 m_BaseLevel; ///< minimum lod specified + QT3DSI32 m_MaxLevel; ///< maximum lod specified + QT3DSU32 m_MaxMipLevel; ///< highest mip level + bool m_Immutable; ///< true if this is a immutable texture ( size and format ) + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget); + + virtual ~NVRenderTextureBase(); + + // define refcount functions + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation) + + virtual void SetMinFilter(NVRenderTextureMinifyingOp::Enum value); + virtual void SetMagFilter(NVRenderTextureMagnifyingOp::Enum value); + + virtual void SetBaseLevel(QT3DSI32 value); + virtual void SetMaxLevel(QT3DSI32 value); + + virtual void SetTextureWrapS(NVRenderTextureCoordOp::Enum value); + virtual void SetTextureWrapT(NVRenderTextureCoordOp::Enum value); + + virtual void SetTextureCompareMode(NVRenderTextureCompareMode::Enum value); + virtual void SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value); + + virtual void SetTextureUnit(QT3DSU32 unit) { m_TextureUnit = unit; } + virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; } + + // Get the texture details for mipmap level 0 if it was set. + virtual STextureDetails GetTextureDetails() const = 0; + + virtual bool IsMultisampleTexture() const + { + return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS); + } + virtual QT3DSU32 GetSampleCount() const { return m_SampleCount; } + virtual bool IsImmutableTexture() const { return m_Immutable; } + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + virtual void Bind() = 0; + + virtual QT3DSU32 GetNumMipmaps() { return m_MaxMipLevel; } + + /** + * @brief Query if texture needs coordinate swizzle + * + * @return texture swizzle mode + */ + virtual NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode() + { + // if our backend supports hardware texture swizzle then there is no need for a shader + // swizzle + return (m_Backend->GetRenderBackendCap( + NVRenderBackend::NVRenderBackendCaps::TexSwizzle)) + ? NVRenderTextureSwizzleMode::NoSwizzle + : m_Backend->GetTextureSwizzleMode(m_Format); + } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle() + { + return m_TextureHandle; + } + + protected: + void applyTexParams(); + void applyTexSwizzle(); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp b/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp new file mode 100644 index 00000000..0919daf3 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 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$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "EASTL/vector.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderSampler.h" +#include "render/Qt3DSRenderTextureCube.h" +#include "foundation/Qt3DSDataRef.h" + +namespace qt3ds { +namespace render { + + NVRenderTextureCube::NVRenderTextureCube(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget) + : NVRenderTextureBase(context, fnd, texTarget) + , m_Width(0) + , m_Height(0) + { + } + + NVRenderTextureCube::~NVRenderTextureCube() { m_Context.TextureDestroyed(*this); } + + void NVRenderTextureCube::SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, + NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width, + QT3DSU32 height, NVRenderTextureFormats::Enum format) + { + QT3DS_ASSERT(m_TextureHandle); + QT3DS_ASSERT(inFace != NVRenderTextureCubeFaces::InvalidFace); + + if (inMipLevel == 0) { + m_Width = width; + m_Height = height; + m_Format = format; + m_MaxMipLevel = inMipLevel; + } + + if (m_MaxMipLevel < inMipLevel) { + m_MaxMipLevel = inMipLevel; + } + + // get max size and check value + QT3DSI32 theMaxSize; + m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, + &theMaxSize); + if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize) { + qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)", + theMaxSize, theMaxSize); + } + + NVRenderTextureTargetType::Enum outTarget = + static_cast<NVRenderTextureTargetType::Enum>((int)m_TexTarget + (int)inFace); + if (NVRenderTextureFormats::isUncompressedTextureFormat(format) + || NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Backend->SetTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel, format, width, + height, 0, format, newBuffer.begin()); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) { + m_Backend->SetCompressedTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel, + format, width, height, 0, newBuffer.size(), + newBuffer.begin()); + } + + // Set our texture parameters to a default that will look the best + if (inMipLevel > 0) + SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); + } + + STextureDetails NVRenderTextureCube::GetTextureDetails() const + { + return STextureDetails(m_Width, m_Height, 6, m_SampleCount, m_Format); + } + + void NVRenderTextureCube::Bind() + { + m_TextureUnit = m_Context.GetNextTextureUnit(); + + m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit); + + applyTexParams(); + applyTexSwizzle(); + } + + NVRenderTextureCube *NVRenderTextureCube::Create(NVRenderContextImpl &context) + { + return QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTextureCube)(context, context.GetFoundation()); + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureCube.h b/src/Runtime/Source/render/Qt3DSRenderTextureCube.h new file mode 100644 index 00000000..7310d44d --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTextureCube.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 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$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H +#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSRefCounted.h" +#include "foundation/Qt3DSOption.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/Qt3DSRenderTextureBase.h" + +namespace qt3ds { +namespace render { + + class NVRenderContextImpl; + class NVRenderTextureSampler; + + class NVRenderTextureCube : public NVRenderTextureBase + { + private: + QT3DSU32 m_Width; ///< texture width (per face) + QT3DSU32 m_Height; ///< texture height (per face) + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * @param[in] texTarget Texture target + * + * @return No return. + */ + NVRenderTextureCube( + NVRenderContextImpl &context, NVFoundationBase &fnd, + NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::TextureCube); + + virtual ~NVRenderTextureCube(); + + /** + * @brief constructor + * + * @param[in] newBuffer Pointer to pixel buffer + * @param[in] inMipLevel Pointer to foundation + * @param[in] width Texture target + * @param[in] height Texture target + * @param[in] slices Texture target + * @param[in] format Texture target + * + * @return No return. + */ + void SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, + NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width, QT3DSU32 height, + NVRenderTextureFormats::Enum format); + + // Get the texture details for mipmap level 0 if it was set. + STextureDetails GetTextureDetails() const override; + + /** + * @brief Bind a texture for shader access + * + * + * @return No return. + */ + void Bind() override; + + /** + * @brief create a texture array object + * + * + * @ return a texture array object + */ + static NVRenderTextureCube *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp new file mode 100644 index 00000000..4184436a --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderTimerQuery.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/StringTable.h" + +namespace qt3ds { +namespace render { + + NVRenderTimerQuery::NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd) + : NVRenderQueryBase(context, fnd) + { + } + + NVRenderTimerQuery::~NVRenderTimerQuery() {} + + void NVRenderTimerQuery::Begin() + { + m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Timer); + } + + void NVRenderTimerQuery::End() { m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Timer); } + + void NVRenderTimerQuery::GetResult(QT3DSU32 *params) + { + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); + } + + void NVRenderTimerQuery::GetResult(QT3DSU64 *params) + { + m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params); + } + + void NVRenderTimerQuery::SetTimerQuery() { m_Backend->SetQueryTimer(m_QueryHandle); } + + NVRenderTimerQuery *NVRenderTimerQuery::Create(NVRenderContextImpl &context) + { + if (!context.IsTimerQuerySupported()) + return NULL; + + NVRenderTimerQuery *retval = QT3DS_NEW(context.GetFoundation().getAllocator(), + NVRenderTimerQuery)(context, context.GetFoundation()); + + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h new file mode 100644 index 00000000..f909f374 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_TIMER_QUERY_H +#define QT3DS_RENDER_TIMER_QUERY_H + +#include "render/Qt3DSRenderQueryBase.h" + +namespace qt3ds { +class NVFoundationBase; +} + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + class NVRenderTimerQuery : public NVRenderQueryBase + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] fnd Pointer to foundation + * + * @return No return. + */ + NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd); + + ///< destructor + ~NVRenderTimerQuery(); + + /** + * @brief Get query type + * + * @return Return query type + */ + NVRenderQueryType::Enum GetQueryType() const override + { + return NVRenderQueryType::Timer; + } + + /** + * @brief Get a pointer to the foundation + * + * @return pointer to foundation + */ + NVFoundationBase &GetFoundation() { return m_Foundation; } + + /** + * @brief begin a query + * + * @return no return. + */ + void Begin() override; + + /** + * @brief end a query + * + * @return no return. + */ + void End() override; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + void GetResult(QT3DSU32 *params) override; + + /** + * @brief Get the result of a query + * + * @param[out] params Contains result of query regarding query type + * + * @return no return. + */ + virtual void GetResult(QT3DSU64 *params); + + /** + * @brief Places an absolute timer query into the render queue + * The result can be queried with GetResult + * + * @return no return. + */ + virtual void SetTimerQuery(); + + /* + * @brief static creation function + * + * * @return a timer query object on success + */ + static NVRenderTimerQuery *Create(NVRenderContextImpl &context); + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp new file mode 100644 index 00000000..89d6204e --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderContext.h" + +namespace qt3ds { +namespace render { + + NVRenderVertexBuffer::NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size, + QT3DSU32 stride, NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, + NVDataRef<QT3DSU8> data) + : NVRenderDataBuffer(context, context.GetFoundation(), size, bindFlags, usageType, data) + , m_Stride(stride) + { + QT3DS_ASSERT(m_Stride); + } + + NVRenderVertexBuffer::~NVRenderVertexBuffer() { m_Context.BufferDestroyed(*this); } + + void NVRenderVertexBuffer::Bind() + { + if (m_Mapped) { + qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer"); + QT3DS_ASSERT(false); + } + + m_Backend->BindBuffer(m_BufferHandle, m_BindFlags); + } + + NVRenderVertexBuffer *NVRenderVertexBuffer::Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, + size_t size, QT3DSU32 stride, + NVConstDataRef<QT3DSU8> bufferData) + { + NVFoundationBase &fnd(context.GetFoundation()); + + QT3DSU32 vbufSize = sizeof(NVRenderVertexBuffer); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), vbufSize, "VertexBuffer"); + NVRenderVertexBuffer *retval = new (newMem) NVRenderVertexBuffer( + context, size, stride, NVRenderBufferBindValues::Vertex, usageType, + toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size())); + return retval; + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h new file mode 100644 index 00000000..914afe27 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H +#define QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H +#include "foundation/Qt3DSOption.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderDrawable.h" +#include "render/Qt3DSRenderDataBuffer.h" + +namespace qt3ds { +namespace render { + + // forward declaration + class NVRenderContextImpl; + + ///< Vertex buffer representation + class NVRenderVertexBuffer : public NVRenderDataBuffer + { + public: + /** + * @brief constructor + * + * @param[in] context Pointer to context + * @param[in] entries Vertex buffer attribute layout entries + * @param[in] size Size of the buffer + * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return No return. + */ + NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size, QT3DSU32 stride, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data); + + ///< destructor + virtual ~NVRenderVertexBuffer(); + + /** + * @brief return vertex data stride + * + * @return data stride. + */ + virtual QT3DSU32 GetStride() const { return m_Stride; } + + /** + * @brief get vertex count + * + * @return vertex count + */ + virtual QT3DSU32 GetNumVertexes() const + { + QT3DS_ASSERT((m_BufferCapacity % m_Stride) == 0); + return m_BufferCapacity / m_Stride; + } + + /** + * @brief bind the buffer bypasses the context state + * + * @return no return. + */ + void Bind() override; + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override + { + return m_BufferHandle; + } + + // this will be obsolete + const void *GetImplementationHandle() const override + { + return reinterpret_cast<void *>(m_BufferHandle); + } + + // No stride means that stride is calculated from the size of last entry found via entry + // offset + // Leaves this buffer temporarily bound. + static NVRenderVertexBuffer *Create(NVRenderContextImpl &context, + NVRenderBufferUsageType::Enum usageType, size_t size, + QT3DSU32 stride, NVConstDataRef<QT3DSU8> bufferData); + + private: + QT3DSU32 m_Stride; ///< veretex data stride + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp b/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp new file mode 100644 index 00000000..3a53ad50 --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "render/Qt3DSRenderVertexShader.h" + +namespace qt3ds { +namespace render { + + NVRenderVertexShader::NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram) + : NVRenderShader(context, fnd, source, binaryProgram) + , m_ShaderHandle(NULL) + { + m_ShaderHandle = m_Backend->CreateVertexShader(source, m_ErrorMessage, binaryProgram); + } + + NVRenderVertexShader::~NVRenderVertexShader() + { + if (m_ShaderHandle) { + m_Backend->ReleaseVertexShader(m_ShaderHandle); + } + } +} +} diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexShader.h b/src/Runtime/Source/render/Qt3DSRenderVertexShader.h new file mode 100644 index 00000000..0a96045b --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderVertexShader.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_VERTEX_SHADER_H +#define QT3DS_RENDER_VERTEX_SHADER_H + +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" +#include "render/Qt3DSRenderShader.h" + +namespace qt3ds { +namespace render { + using namespace foundation; + + class NVRenderContextImpl; + + ///< This class represents a vertex shader + class NVRenderVertexShader : public NVRenderShader + { + + public: + /** + * @brief constructor + * + * @param[in] context Pointer to render context + * @param[in] fnd Pointer to foundation + * @param[in] source Pointer to shader source code + * @param[in] binaryProgram true if this is a binary program + * + * @return No return. + */ + NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd, + NVConstDataRef<QT3DSI8> source, bool binaryProgram); + + /// @brief destructor + ~NVRenderVertexShader(); + + /** + * @brief Query if shader compiled succesfuly + * + * @return True if shader is valid. + */ + bool IsValid() override { return (m_ShaderHandle != NULL); } + + /** + * @brief get the backend object handle + * + * @return the backend object handle. + */ + virtual NVRenderBackend::NVRenderBackendVertexShaderObject GetShaderHandle() + { + return m_ShaderHandle; + } + + private: + NVRenderBackend::NVRenderBackendVertexShaderObject + m_ShaderHandle; ///< opaque backend handle + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h b/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h new file mode 100644 index 00000000..12de5d88 --- /dev/null +++ b/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h @@ -0,0 +1,2245 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_H +#define QT3DS_RENDER_BACKEND_H + +/// @file Qt3DSRenderBackend.h +/// NVRender backend definition. + +#include "foundation/Qt3DSAllocator.h" +#include "foundation/Qt3DSNoCopy.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSRefCounted.h" +#include "render/Qt3DSRenderBaseTypes.h" +#include "foundation/Qt3DSBounds3.h" +#include <EASTL/string.h> + +#include <QtGui/qsurfaceformat.h> + +namespace qt3ds { +namespace render { + +#define HandleToID_cast(staticType, dynamicType, handle) \ + static_cast<staticType>(reinterpret_cast<dynamicType>(handle)) + + class NVRenderBackend : public NVRefCounted, public NoCopy + { + + public: + /// opaque buffer object handle + typedef struct _NVRenderBackendBufferObject *NVRenderBackendBufferObject; + /// opaque attribute layout object handle + typedef struct _NVRenderBackendAttribLayoutObject *NVRenderBackendAttribLayoutObject; + /// opaque input assembler object handle + typedef struct _NVRenderBackendInputAssemblerObject *NVRenderBackendInputAssemblerObject; + /// opaque texture object handle + typedef struct _NVRenderBackendTextureObject *NVRenderBackendTextureObject; + /// opaque sampler object handle + typedef struct _NVRenderBackendSamplerObject *NVRenderBackendSamplerObject; + /// opaque renderbuffer object handle + typedef struct _NVRenderBackendRenderbufferObject *NVRenderBackendRenderbufferObject; + /// opaque framebuffer object handle + typedef struct _NVRenderBackendRenderTargetObject *NVRenderBackendRenderTargetObject; + /// opaque vertex shader object handle + typedef struct _NVRenderBackendVertexShaderObject *NVRenderBackendVertexShaderObject; + /// opaque fragment shader object handle + typedef struct _NVRenderBackendFragmentShaderObject *NVRenderBackendFragmentShaderObject; + /// opaque tesselation control shader object handle + typedef struct _NVRenderBackendTessControlShaderObject + *NVRenderBackendTessControlShaderObject; + /// opaque tesselation evaluation shader object handle + typedef struct _NVRenderBackendTessEvaluationShaderObject + *NVRenderBackendTessEvaluationShaderObject; + /// opaque geometry shader object handle + typedef struct _NVRenderBackendGeometryShaderObject *NVRenderBackendGeometryShaderObject; + /// opaque compute shader object handle + typedef struct _NVRenderBackendComputeShaderObject *NVRenderBackendComputeShaderObject; + /// opaque shader program object handle + typedef struct _NVRenderBackendShaderProgramObject *NVRenderBackendShaderProgramObject; + /// opaque depth stencil state object handle + typedef struct _NVRenderBackendDepthStencilStateObject + *NVRenderBackendDepthStencilStateObject; + /// opaque rasterizer state object handle + typedef struct _NVRenderBackendRasterizerStateObject *NVRenderBackendRasterizerStateObject; + /// opaque query object handle + typedef struct _NVRenderBackendQueryObject *NVRenderBackendQueryObject; + /// opaque sync object handle + typedef struct _NVRenderBackendSyncObject *NVRenderBackendSyncObject; + /// opaque sync object handle + typedef struct _NVRenderBackendProgramPipeline *NVRenderBackendProgramPipeline; + /// opaque sync object handle + typedef struct _NVRenderBackendPathObject *NVRenderBackendPathObject; + + // backend capability caps + typedef struct + { + enum Enum { + ConstantBuffer, ///< Constant buffer support query + DepthStencilTexture, ///< depth stencil texture format suport query + DxtImages, ///< DXT image support query + FpRenderTarget, ///< render to floating point target support query + MsTexture, ///< Multisample texture support query + TexSwizzle, ///< Texture swizzle support query + FastBlits, ///< Hardware supports fast blits + Tessellation, ///< Hardware supports tessellation + Compute, ///< Hardware supports compute shader + Geometry, ///< Hardware supports geometry shader + SampleQuery, ///< Hardware supports query calls of type samples + TimerQuery, ///< Hardware supports query calls of type timer + CommandSync, ///< Hardware supports command sync object + TextureArray, ///< Hardware supports texture arrays + StorageBuffer, ///< Hardware supports shader storage buffers + AtomicCounterBuffer, ///< Hardware supports atomic counter buffers + ShaderImageLoadStore, ///< Hardware supports shader image load store operations + ProgramPipeline, ///< Driver supports separate programs + PathRendering, ///< Driver support path rendering + AdvancedBlend, ///< Driver supports advanced blend modes + BlendCoherency, ///< Hardware supports blend coherency + gpuShader5, // for high precision sampling + AdvancedBlendKHR, ///< Driver supports advanced blend modes + VertexArrayObject, + StandardDerivatives, + TextureLod + }; + } NVRenderBackendCaps; + + // backend queries + typedef struct + { + enum Enum { + MaxTextureSize, ///< Return max supported texture size + MaxTextureArrayLayers, ///< Return max supported layer count for texture arrays + MaxConstantBufferSlots, ///< Return max supported constant buffe slots for a single + ///shader stage + MaxConstantBufferBlockSize ///< Return max supported size for a single constant + ///buffer block + }; + } NVRenderBackendQuery; + + /// backend interface + + /** + * @brief get the backend type + * + * @return true backend type + */ + virtual NVRenderContextType GetRenderContextType() const = 0; + + /** + * @brief get the version of the shading language + * @return version string, must be copied by clients to be retained. + */ + virtual const char *GetShadingLanguageVersion() = 0; + + /** + * @brief get maximum supported texture image units that + * can be used to access texture maps from the vertex shader and the fragment processor + *combined. + * + * @return max texture size + */ + virtual QT3DSU32 GetMaxCombinedTextureUnits() = 0; + + /** + * @brief query Backend capabilities + * + * @param[in] inCap CAPS flag to query + * @ConstantBuffer, @DepthStencilTexture, ... + * + * @return true if supported + */ + virtual bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const = 0; + + /** + * @brief query Backend values + * + * @param[in] inQuery Query flag to get value for + * @MaxTextureSize, @MaxTextureArrayLayers, + *... + * @param[in/out] params the query result is stored here + * + * @return no return + */ + virtual void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, + QT3DSI32 *params) const = 0; + + /** + * @brief query for bit depth of the depth buffer + * + * @return depth buffer bitplanes + */ + virtual QT3DSU32 GetDepthBits() const = 0; + + /** + * @brief query for bit depth of the stencil buffer + * + * @return stencil buffer bitplanes + */ + virtual QT3DSU32 GetStencilBits() const = 0; + + /* + * @brief set a backend rende state + * + * @param[in] bEnable enable/disable state + * @param[in] value type of state + * + * @return no return + */ + virtual void SetRenderState(bool bEnable, const NVRenderState::Enum value) = 0; + + /** + * @brief get a backend rende state + * + * @param[in] value type of state + * + * @return true if state enabled otherwise false + */ + virtual bool GetRenderState(const NVRenderState::Enum value) = 0; + + /** + * @brief get current depth function + * + * @return active depth function + */ + virtual NVRenderBoolOp::Enum GetDepthFunc() = 0; + + /** + * @brief create a depth stencil state object + * + * @param[in] enableDepth enable depth test + * @param[in] depthMask enable depth writes + * @param[in] depthFunc depth compare function + * @param[in] enableStencil enable stencil test + * @param[in] stencilFuncFront stencil setup front faces + * @param[in] stencilFuncBack stencil setup back faces + * @param[in] depthStencilOpFront depth/stencil operations front faces + * @param[in] depthStencilOpBack depth/stencil operations back faces + * + * @return opaque handle to state object + */ + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) = 0; + + /** + * @brief release a depth stencil state object + * + * @param[in] depthStencilState pointer to state object + * + * @return none + */ + virtual void + ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; + + /** + * @brief create a rasterizer state object + * + * @param[in] depthBias any othe value than 0 enables depth bias + * @param[in] depthScale any othe value than 0 enables depth scale + * @param[in] cullFace select face to cull front or back + * + * @return opaque handle to state object + */ + virtual NVRenderBackendRasterizerStateObject + CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) = 0; + + /** + * @brief release a rasterizer state object + * + * @param[in] rasterizerState pointer to state object + * + * @return none + */ + virtual void + ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; + + /** + * @brief set depth stencil state + * + * @param[in] depthStencilState pointer to state object + * + * @return none + */ + virtual void + SetDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0; + + /** + * @brief set rasterizer state + * + * @param[in] rasterizerState pointer to state object + * + * @return none + */ + virtual void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0; + + /** + * @brief set current depth function + * + * @param[in] func type of function + * + * @return no return + */ + virtual void SetDepthFunc(const NVRenderBoolOp::Enum func) = 0; + + /** + * @brief query if depth write is enabled + * + * @return true if enabled + */ + virtual bool GetDepthWrite() = 0; + + /** + * @brief enable / disable depth writes + * + * @param[in] bEnable true for enable + * + * @return no return + */ + virtual void SetDepthWrite(bool bEnable) = 0; + + /** + * @brief enable / disable color channel writes + * + * @param[in] bRed true for enable red channel + * @param[in] bGreen true for enable green channel + * @param[in] bBlue true for enable blue channel + * @param[in] bAlpha true for enable alpha channel + * + * @return no return + */ + virtual void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; + + /** + * @brief enable / disable multisample rendering + * + * @param[in] bEnable true for enable + * + * @return no return + */ + virtual void SetMultisample(bool bEnable) = 0; + + /** + * @brief query blend functions + * + * @param[out] pBlendFuncArg blending functions + * + * @return no return + */ + virtual void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) = 0; + + /** + * @brief set blend functions + * + * @param[in] pBlendFuncArg blending functions + * + * @return no return + */ + virtual void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) = 0; + + /** + * @brief set blend equation + * + * @param[in] pBlendEquArg blending equation + * + * @return no return + */ + virtual void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) = 0; + + /** + * @brief guarantee blend coherency + * + * + * @return no return + */ + virtual void SetBlendBarrier(void) = 0; + + /** + * @brief query scissor rectangle + * + * @param[out] pRect contains scissor rect + * + * @return no return + */ + virtual void GetScissorRect(NVRenderRect *pRect) = 0; + + /** + * @brief set scissor rectangle + * + * @param[out] pRect contains scissor rect + * + * @return no return + */ + virtual void SetScissorRect(const NVRenderRect &rect) = 0; + + /** + * @brief query viewport rectangle + * + * @param[out] pRect contains viewport rect + * + * @return no return + */ + virtual void GetViewportRect(NVRenderRect *pRect) = 0; + + /** + * @brief set viewport rectangle + * + * @param[out] pRect contains viewport rect + * + * @return no return + */ + virtual void SetViewportRect(const NVRenderRect &rect) = 0; + + /** + * @brief query viewport rectangle + * + * @param[in] clearColor clear color + * + * @return no return + */ + virtual void SetClearColor(const QT3DSVec4 *pClearColor) = 0; + + /** + * @brief query viewport rectangle + * + * @param[in] flags clear flags + * + * @return no return + */ + virtual void Clear(NVRenderClearFlags flags) = 0; + + /** + * @brief create a buffer object + * + * @param[in] size Size of the buffer + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + *application. + * + * @return The created buffer object or NULL if the creation failed. + */ + virtual NVRenderBackendBufferObject CreateBuffer(size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, + const void *hostPtr = NULL) = 0; + + /** + * @brief bind a buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * + * @return no return. + */ + virtual void BindBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) = 0; + + /** + * @brief Release a single buffer object + * + * @param[in] bo Pointer to buffer object + * + * @return no return. + */ + virtual void ReleaseBuffer(NVRenderBackendBufferObject bo) = 0; + + /** + * @brief update a whole buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] size Size of the data buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return no return. + */ + virtual void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t size, NVRenderBufferUsageType::Enum usage, + const void *data) = 0; + + /** + * @brief update a range of a buffer object + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] size Size of the data buffer + * @param[in] usage Usage of the buffer (e.g. static, dynamic...) + * @param[in] data A pointer to the buffer data that is allocated by the + *application. + * + * @return no return. + */ + virtual void UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) = 0; + + /** + * @brief Get a pointer to the buffer data ( GL(ES) >= 3 only ) + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * @param[in] offset Byte offset into the data buffer + * @param[in] length Byte length of mapping size + * @param[in] access Access of the buffer (e.g. read, write, ...) + * + * @return pointer to mapped data or null. + */ + virtual void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) = 0; + + /** + * @brief Unmap a previously mapped buffer ( GL(ES) >= 3 only ) + * This functions transfers the content to the hardware buffer + * + * @param[in] bo Pointer to buffer object + * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...) + * For OpenGL this should be a single + *value + * + * @return true if successful + */ + virtual bool UnmapBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) = 0; + + /** + * @brief Set a memory barrier + * + * @param[in] barriers Flags for barriers + * + * @return no return. + */ + virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0; + + /** + * @brief create a query object + * + * @return The created query object or NULL if the creation failed. + */ + virtual NVRenderBackendQueryObject CreateQuery() = 0; + + /** + * @brief delete query objects + * + * @param[in] qo Handle to query object + * + * @return no return + */ + virtual void ReleaseQuery(NVRenderBackendQueryObject qo) = 0; + + /** + * @brief Start query recording + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * + * @return no return + */ + virtual void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; + + /** + * @brief End query recording + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * + * @return no return + */ + virtual void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0; + + /** + * @brief Get a query result + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * @param[out] params Contains result of query regarding query type + * + * @return no return + */ + virtual void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) = 0; + + /** + * @brief Get a query result + * + * @param[in] qo Handle to query object + * @param[in] type Type of query + * @param[out] params Contains result of query regarding query type 64 bit returns + * + * @return no return + */ + virtual void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) = 0; + + /** + * @brief Record the GPU time using the query object + * + * @param[in] qo Handle to query object + * + * @return no return + */ + virtual void SetQueryTimer(NVRenderBackendQueryObject qo) = 0; + + /** + * @brief create a sync object and place it in the command queue + * + * @param[in] tpye Type to sync + * @param[in] syncFlags Currently unused + * + * @return The created sync object or NULL if the creation failed. + */ + virtual NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) = 0; + + /** + * @brief delete sync object + * + * @param[in] so Handle to sync object + * + * @return no return + */ + virtual void ReleaseSync(NVRenderBackendSyncObject so) = 0; + + /** + * @brief wait for sync object to be signaled + * + * @param[in] so Handle to sync object + * @param[in] syncFlags Currently unused + * @param[in] timeout Currently ignored + * + * @return no return + */ + virtual void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) = 0; + + /** + * @brief create a render target object + * + * + * @return The created render target object or NULL if the creation failed. + */ + virtual NVRenderBackendRenderTargetObject CreateRenderTarget() = 0; + + /** + * @brief Release a single render target object + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Attach a renderbuffer object to the framebuffer + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] rbo Pointer to renderbuffer object + * + * @return no return. + */ + virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) = 0; + + /** + * @brief Attach a texture object to the render target + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] to Pointer to texture object + * @param[in] target Attachment texture target + * + * @return no return. + */ + virtual void RenderTargetAttach( + NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) = 0; + + /** + * @brief Attach a texture object to the render target + * + * @param[in] rto Pointer to render target object + * @param[in] attachment Attachment point (e.g COLOR0, DEPTH) + * @param[in] to Pointer to texture object + * @param[in] level Texture mip level + * @param[in] layer Texture layer or slice + * + * @return no return. + */ + virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) = 0; + + /** + * @brief Make a render target active + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void SetRenderTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Check if a render target is ready for render + * + * @param[in] rto Pointer to render target object + * + * @return true if usable. + */ + virtual bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Make a render target active for reading + * + * @param[in] rto Pointer to render target object + * + * @return no return. + */ + virtual void SetReadTarget(NVRenderBackendRenderTargetObject rto) = 0; + + /** + * @brief Set active buffers for drawing + * + * @param[in] rto Pointer to render target object + * @param[in] inDrawBufferSet Pointer to array of enabled render targets + * + * @return no return. + */ + virtual void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef<QT3DSI32> inDrawBufferSet) = 0; + + /** + * @brief Set active buffer for reading + * + * @param[in] rto Pointer to render target object + * @param[in] inReadFace Buffer to read from + * + * @return no return. + */ + virtual void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) = 0; + + /** + * @brief Copy framebuffer attachments. Source is set with SetReadTarget dest with + * SetRenderTarget + * + * @param[in] srcX0 Lower left X coord of source rectangle + * @param[in] srcY0 Lower left Y coord of source rectangle + * @param[in] srcX1 Upper right X coord of source rectangle + * @param[in] srcY1 Upper right Y coord of source rectangle + * @param[in] dstX0 Lower left X coord of dest rectangle + * @param[in] dstY0 Lower left Y coord of dest rectangle + * @param[in] dstX1 Upper right X coord of dest rectangle + * @param[in] dstY1 Upper right Y coord of dest rectangle + * @param[in] inDrawBufferSet pointer to array of enabled render targets + * @param[in] filter Copy filter method (NEAREST or LINEAR) + * + * @return no return. + */ + virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) = 0; + + /** + * @brief create a render buffer object + * + * @param[in] storageFormat Format of the buffer + * @param[in] width Buffer with + * @param[in] height Buffer height + * + * @return The created render buffer object or NULL if the creation failed. + */ + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) = 0; + + /** + * @brief Release a single renderbuffer object + * + * @param[in] bo Pointer to renderbuffer object + * + * @return no return. + */ + virtual void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) = 0; + + /** + * @brief resize a render buffer object + * + * @param[in] storageFormat Format of the buffer + * @param[in] width Buffer with + * @param[in] height Buffer height + * + * @return True on success + */ + virtual bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) = 0; + + /** + * @brief create a texture object + * + * @return The created texture object or NULL if the creation failed.. + */ + virtual NVRenderBackendTextureObject CreateTexture() = 0; + + /** + * @brief set texture data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief set texture data for the face of a Cube map + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target face + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief create a storage for a 2D texture including mip levels + * Note that this makes texture immutable in size and format + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] levels Texture mip level count + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * + * @return No return + */ + virtual void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) = 0; + + /** + * @brief set texture sub data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] xOffset Texture x offset + * @param[in] yOffset Texture y offset + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] border border + * @param[in] format format of texture + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture data for a Cubemap face + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] border border + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief set compressed texture sub data for a 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] xOffset Texture x offset + * @param[in] yOffset Texture y offset + * @param[in] width texture width + * @param[in] height texture height + * @param[in] format format of provided pixel data + * @param[in] imageSize image size in bytes located at hostPtr + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetCompressedTextureSubData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr = NULL) = 0; + + /** + * @brief establish a multisampled 2D texture + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D MS + * @param[in] samples Textures sample count + * @param[in] internalFormat Format of the texture + * @param[in] width Texture width + * @param[in] height Texture height + * @param[in] bool Fixed sample locations + * + * @return No return + */ + virtual void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) = 0; + + /** + * @brief set texture data for a 3D texture or 2D texture array + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] level Texture mip level + * @param[in] internalFormat format of the texture + * @param[in] width texture width + * @param[in] height texture height + * @param[in] depth texture depth or slice count + * @param[in] border border + * @param[in] format format of provided pixel data + * @param[in] hostPtr A pointer to the buffer data that is allocated by the + * application. + * + * @return No return + */ + virtual void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) = 0; + + /** + * @brief generate mipmap levels + * + * @param[in] to Pointer to texture object + * @param[in] target Texture target 2D,... + * @param[in] hint How to generate mips (Nicest) + * + * @return No return + */ + virtual void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) = 0; + + /** + * @brief bind a texture object + * + * @param[in] to Pointer to texture object + * @param[in] target Where to bind this texture (e.g. 2D, 3D, ...) + * @param[in] unit Which unit to bind this texture + * + * @return no return. + */ + virtual void BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) = 0; + + /** + * @brief bind a image/texture object + * + * @param[in] to Pointer to texture object + * @param[in] unit Which unit to bind this texture + * @param[in] level Which level to bind + * @param[in] layered Bind layered texture (cube map, array,... ) + * @param[in] level Specify layer. Only valid of layered=false. + * @param[in] access Access mode ( read, write, read-write ) + * @param[in] format Texture format must be compatible with Image format + * + * @return no return. + */ + virtual void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum accessFlags, + NVRenderTextureFormats::Enum format) = 0; + + /** + * @brief Release a single texture object + * + * @param[in] to Pointer to buffer object + * + * @return no return. + */ + virtual void ReleaseTexture(NVRenderBackendTextureObject to) = 0; + + /** + * @brief query texture swizzle mode + * This is mainly for luminance, alpha replacement with R8 formats + * + * @param[in] inFormat input texture format to check + * + * @return texture swizzle mode + */ + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const = 0; + + /** + * @ brief create a sampler + * + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail example + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] + * + * @return The created sampler object or NULL if the creation failed. + */ + virtual NVRenderBackendSamplerObject CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; + + /** + * @ brief update a sampler + * + * @param[in] so Pointer to sampler object + * @param[in] target Texture target 2D, 3D + * @param[in] minFilter Texture min filter + * @param[in] magFilter Texture mag filter + * @param[in] wrapS Texture coord generation for S + * @param[in] wrapT Texture coord generation for T + * @param[in] wrapR Texture coord generation for R + * @param[in] minLod Texture min level of detail + * @param[in] maxLod Texture max level of detail + * @param[in] lodBias Texture level of detail bias (unused) + * @param[in] compareMode Texture compare mode + * @param[in] compareFunc Texture compare function + * @param[in] anisoFilter Aniso filter value [1.0, 16.0] + * @param[in] borderColor Texture border color float[4] (unused) + * + * @return No return + */ + virtual void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0; + + /** + * @ brief Update a textures swizzle mode + * + * @param[in] so Pointer to texture object + * @param[in] target Texture target 2D, 3D + * @param[in] swizzleMode Texture swizzle mode + * + * @return No return + */ + virtual void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) = 0; + + /** + * @ brief Update state belonging to a texture object + * + * @param[in] so Pointer to texture object + * @param[in] target Texture target 2D, 3D, Cube + * @param[in] baseLevel Texture base level + * @param[in] maxLevel Texture max level + * + * @return No return + */ + virtual void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) = 0; + + /** + * @brief Release a single sampler object + * + * @param[in] so Pointer to sampler object + * + * @return no return. + */ + virtual void ReleaseSampler(NVRenderBackendSamplerObject so) = 0; + + /** + * @brief create a attribute layout object + * + * @param[in] attribs Array off vertex attributes. + * + * @return The created attribute layout object or NULL if the creation failed. + */ + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) = 0; + + /** + * @brief Release a attribute layoutr object + * + * @param[in] ao Pointer to attribute layout object + * + * @return no return. + */ + virtual void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) = 0; + + /** + * @brief create a input assembler object + * + * @param[in] attribLayout Pointer to NVRenderBackendAttribLayoutObject object + * @param[in] buffers list of vertex buffers + * @param[in] indexBuffer index buffer object + * @param[in] strides list of strides of the buffer + * @param[in] offsets list of offsets into the buffer + * @param[in] patchVertexCount vertext count for a patch. Only valid for patch primitives + * + * @return The created input assembler object or NULL if the creation failed. + */ + virtual NVRenderBackendInputAssemblerObject + CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef<NVRenderBackendBufferObject> buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets, + QT3DSU32 patchVertexCount) = 0; + + /** + * @brief Release a input assembler object + * + * @param[in] iao Pointer to attribute layout object + * + * @return no return. + */ + virtual void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) = 0; + + /** + * @brief Set a input assembler object. + * This setup the render engine vertex assmebly + * + * @param[in] iao Pointer to attribute layout object + * @param[in] po Pointer program object + * + * @return false if it fails. + */ + virtual bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Set the per patch vertex count + * + * @param[in] iao Pointer to attribute layout object + * @param[in] count Count of vertices per patch + * + * @return false if it fails. + */ + virtual void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) = 0; + + /** + * @brief create a vertex shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created vertex shader object or NULL if the creation failed. + */ + virtual NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a vertex shader object + * + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief create a fragment shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created vertex shader object or NULL if the creation failed. + */ + virtual NVRenderBackendFragmentShaderObject + CreateFragmentShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a fragment shader object + * + * @param[in] vso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief create a tessellation control shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created tessellation control shader object or NULL if the creation failed. + */ + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a tessellation control shader object + * + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief create a tessellation evaluation shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created tessellation evaluation shader object or NULL if the creation failed. + */ + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a tessellation evaluation shader object + * + * @param[in] tcso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void + ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief create a geometry shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created geometry shader object or NULL if the creation failed. + */ + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a geometry shader object + * + * @param[in] tcso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief create a compute shader object + * + * @param[in] source Pointer to shader source + * @param[in/out] errorMessage Pointer to copy the error message + * @param[in] binary True if the source is actually a binary program + * + * @return The created compute shader object or NULL if the creation failed. + */ + virtual NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, + bool binary) = 0; + + /** + * @brief release a compute shader object + * + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief attach a vertex shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief detach a vertex shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] vso Pointer to vertex shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) = 0; + + /** + * @brief attach a fragment shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] fso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief detach a fragment shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] fso Pointer to fragment shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) = 0; + + /** + * @brief attach a tessellation control shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief detach a tessellation control shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] tcso Pointer to tessellation control shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) = 0; + + /** + * @brief attach a tessellation evaluation shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief detach a tessellation evaluation shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to tessellation evaluation shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) = 0; + + /** + * @brief attach a geometry shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief detach a geometry shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] teso Pointer to geometry shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) = 0; + + /** + * @brief attach a compute shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief detach a compute shader object to a program object + * + * @param[in] po Pointer to program object + * @param[in] cso Pointer to compute shader object + * + * @return No Return. + */ + virtual void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) = 0; + + /** + * @brief create a shader program object + * + * @param[in] isSeparable Tell the backend that this program is separable + * + * @return The created shader program object or NULL if the creation failed. + */ + virtual NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) = 0; + + /** + * @brief release a shader program object + * + * @param[in] po Pointer to shader program object + * + * @return No Return. + */ + virtual void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief link a shader program object + * + * @param[in] po Pointer to shader program object + * @param[in/out] errorMessage Pointer to copy the error message + * + * @return True if program is succesful linked. + */ + virtual bool LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) = 0; + + /** + * @brief Make a program current + * + * @param[in] po Pointer to shader program object + * + * @return No return + */ + virtual void SetActiveProgram(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief create a program pipeline object + * + * + * @return The created program pipeline object or NULL if the creation failed. + */ + virtual NVRenderBackendProgramPipeline CreateProgramPipeline() = 0; + + /** + * @brief release a program pipeline object + * + * @param[in] ppo Pointer to program pipeline object + * + * @return No Return. + */ + virtual void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; + + /** + * @brief Make a program pipeline current + * + * @param[in] ppo Pointer to program pipeline object + * + * @return No return + */ + virtual void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0; + + /** + * @brief Make a program stage active for this pipeline + * + * @param[in] ppo Pointer to program pipeline object + * @param[in] flags Shader stage flags to which this po is bound to + * @param[in] po Pointer to shader program object + * + * @return No return + */ + virtual void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Runs a compute program + * + * @param[in] po Pointer to shader program object + * @param[in] numGroupsX The number of work groups to be launched in the X + * dimension + * @param[in] numGroupsY The number of work groups to be launched in the Y + * dimension + * @param[in] numGroupsZ The number of work groups to be launched in the Z + * dimension + * + * @return No return + */ + virtual void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0; + + /** + * @brief Query constant count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active constant count + */ + virtual QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query constant buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active constant buffer count + */ + virtual QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query constant information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant ID + * @param[in] bufSize Max char for nameBuf + * @param[out] numElem Usually one unless for arrays + * @param[out] type Constant data type (QT3DSVec4, QT3DSVec3,...) + * @param[out] binding Unit binding point for samplers and images + * @param[out] nameBuf Name of the constant + * + * @return Return current constant location or -1 if not found + */ + virtual QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) = 0; + + /** + * @brief Query constant buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count ot parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current constant buffer location or -1 if not found + */ + virtual QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) = 0; + + /** + * @brief Query constant buffer param indices + * + * @param[in] po Pointer to shader program object + * @param[in] id Constant buffer ID + * @param[out] indices Receives the indices of the uniforms within the + * constant buffer + * + * @return no return value + */ + virtual void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) = 0; + + /** + * @brief Query constant buffer param info by indices + * + * @param[in] po Pointer to shader program object + * @param[in] count Number of indices + * @param[in] indices The indices of the uniforms within the constant + * buffer + * @param[out] type Array of param types ( float ,int, ...) + * @param[out] size Array of param size + * @param[out] offset Array of param offsets within the constant buffer + * + * @return no return value + */ + virtual void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) = 0; + + /** + * @brief Bind program constant block + * + * @param[in] po Pointer to shader program object + * @param[in] blockIndex Constant block index returned by + * GetConstantBufferInfoByID + * @param[in] binding Block binding location which should be the same as index + * in ProgramSetConstantBlock + * + * @return No return + */ + virtual void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) = 0; + + /** + * @brief Bind constant buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to constant buffer object + * + * @return No return + */ + virtual void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Query storage buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active storage buffer count + */ + virtual QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query storage buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Storage buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count of parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current storage buffer binding or -1 if not found + */ + virtual QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) = 0; + + /** + * @brief Bind a storage buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to storage buffer object + * + * @return No return + */ + virtual void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Query atomic counter buffer count for a program object + * + * @param[in] po Pointer to shader program object + * + * @return Return active atomic buffer count + */ + virtual QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) = 0; + + /** + * @brief Query atomic counter buffer information by ID + * + * @param[in] po Pointer to shader program object + * @param[in] id Storage buffer ID + * @param[in] nameBufSize Size of nameBuf + * @param[out] paramCount Count of parameter contained in the buffer + * @param[out] bufferSize Data size of the constant buffer + * @param[out] length Actual characters written + * @param[out] nameBuf Receives the name of the buffer + * + * @return Return current storage buffer binding or -1 if not found + */ + virtual QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) = 0; + + /** + * @brief Bind a atomic counter buffer for usage in the current active shader program + * + * @param[in] index Constant ID + * @param[in] bo Pointer to atomic counter buffer object + * + * @return No return + */ + virtual void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0; + + /** + * @brief Set constant value + * + * @param[in] po Pointer program object + * @param[in] id Constant ID + * @param[in] type Constant data type (QT3DSVec4, QT3DSVec3,...) + * @param[in] count Element count + * @param[in] value Pointer to constant value + * @param[in] transpose Transpose a matrix + * + * @return No return + */ + virtual void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose = false) = 0; + + /** + * @brief Draw the current active vertex buffer + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] start Start vertex + * @param[in] count Vertex count + * + * @return no return. + */ + virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) = 0; + + /** + * @brief Draw the current active vertex buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] indirect Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) = 0; + + /** + * @brief Draw the current active index buffer + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] count Index count + * @param[in] type Index type (QT3DSU16, QT3DSU8) + * @param[in] indices Pointer to index buffer. In the case of buffer objects + * this is an offset into the active index buffer + *object. + * + * @return no return. + */ + virtual void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) = 0; + + /** + * @brief Draw the current active index buffer using an indirect buffer + * This means the setup of the draw call is stored in a buffer bound to + * NVRenderBufferBindValues::Draw_Indirect + * + * @param[in] drawMode Draw mode (Triangles, ....) + * @param[in] type Index type (QT3DSU16, QT3DSU8) + * @param[in] indices Offset into a indirect drawing setup buffer + * + * @return no return. + */ + virtual void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) = 0; + + /** + * @brief Read a pixel rectangle from render target (from bottom left) + * + * @param[in] rto Pointer to render target object + * @param[in] x Windows X start coord + * @param[in] y Windows Y start coord + * @param[in] width Read width dim + * @param[in] height Read height dim + * @param[out] pixels Returned pixel data + * + * @return No return + */ + virtual void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, + QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, + void *pixels) = 0; + + /** + * @brief Create a NV path render object + * + * @param[in] range Number of internal objects + * + * @return return path object on success or NULL + */ + virtual NVRenderBackendPathObject CreatePathNVObject(size_t range) = 0; + + /** + * @brief Relase a NV path render object + * + * @param[in] po Created path object + * @param[in] range Number of internal objects + * + * @return return path object on success or NULL + */ + virtual void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) = 0; + + /** + * @brief Set the path commands and data. + * + * @param[in] inPathObject Pointer to NV path object + * @param[in] inPathCommands vector of path commands ( moveTo,... ) + * @param[in] inPathCoords vector of path coords + * + * @return No return + */ + virtual void SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef<QT3DSU8> inPathCommands, + NVConstDataRef<QT3DSF32> inPathCoords) = 0; + + /** + * @brief Get Bounds of the path object + * + * @param[in] inPathObject Pointer to NV path object + * + * @return return bounds + */ + virtual NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) = 0; + virtual NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) = 0; + virtual NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) = 0; + + /** + * @brief Set stroke width. Defaults to 0 if unset. + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void SetStrokeWidth(NVRenderBackendPathObject inPathObject, + QT3DSF32 inStrokeWidth) = 0; + + /** + * @brief Path transform commands + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0; + virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0; + + /** + * @brief Path stencil pass operations + * + * @param[in] inPathObject Pointer to NV path object + * + * @return No return + */ + virtual void StencilStrokePath(NVRenderBackendPathObject inPathObject) = 0; + virtual void StencilFillPath(NVRenderBackendPathObject inPathObject) = 0; + + /** + * @brief Does a instanced stencil fill pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] fillMode Fille mode + * @param[in] stencilMask Stencil mask + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced stencil stroke pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] stencilRef Stencil reference + * @param[in] stencilMask Stencil mask + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, + QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced cover fill pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] coverMode Cover mode + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Does a instanced cover stroke pass + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] coverMode Cover mode + * @param[in] transformType Transforming glyphs + * @param[in] transformValues Pointer to array of transforms + * + * @return No return + */ + virtual void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) = 0; + + /** + * @brief Path stencil and depth offset + * + * @param[in] inSlope slope + * @param[in] inBias bias + * + * @return No return + */ + virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0; + + /** + * @brief Path cover function + * + * @param[in] inDepthFunction depth function + * + * @return No return + */ + virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) = 0; + + /** + * @brief Load glyphs + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] numGlyphs Glyph count + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] handleMissingGlyphs skip or use + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return No return + */ + virtual void LoadPathGlyphs(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, + NVRenderPathFormatType::Enum type, const void *charCodes, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) = 0; + + /** + * @brief Load indexed font set + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] firstGlyphIndex First glyph + * @param[in] numGlyphs Glyph count + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return return load status + */ + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) = 0; + + /** + * @brief Load indexed font set + * + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * @param[out] po contains glyph count + * + * @return returnr base path object + */ + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, + QT3DSU32 *count) = 0; + + /** + * @brief Load font set + * + * @param[in] po Base of path objects + * @param[in] fontTarget System font, or application font,... + * @param[in] fontName Name of font ( may include path ) + * @param[in] fontStyle Bold or italic + * @param[in] firstGlyph First glyph + * @param[in] numGlyphs Glyph count + * @param[in] handleMissingGlyphs skip or use + * @param[in] pathParameterTemplate template + * @param[in] emScale scale ( true type scale e.g. 2048 ) + * + * @return No return + */ + virtual void LoadPathGlyphRange(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) = 0; + + /** + * @brief Query font metrics + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] metricQueryMask Qeury bit mask + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] stride scale ( true type scale e.g. 2048 ) + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, const void *charCodes, + size_t stride, QT3DSF32 *metrics) = 0; + + /** + * @brief Query font metrics + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] metricQueryMask Qeury bit mask + * @param[in] stride scale ( true type scale e.g. 2048 ) + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) = 0; + + /** + * @brief Query path spacing + * + * @param[in] po Base of path objects + * @param[in] numPaths Number path objects + * @param[in] pathListMode How to compute spacing + * @param[in] type type ( byte, int,... ) + * @param[in] charCodes charachter string + * @param[in] advanceScale + * @param[in] kerningScale + * @param[in] transformType + * @param[out] metrics Filled with font metric values + * + * @return No return + */ + virtual void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, + QT3DSF32 advanceScale, QT3DSF32 kerningScale, + NVRenderPathTransformType::Enum transformType, + QT3DSF32 *spacing) = 0; + + virtual QSurfaceFormat format() const = 0; + + protected: + /// struct for what the backend supports + typedef struct NVRenderBackendSupport + { + union { + struct + { + bool bDXTImagesSupported : 1; ///< compressed images supported + bool bAnistropySupported : 1; ///< anistropic filtering supported + bool bTextureSwizzleSupported : 1; ///< texture swizzle supported + bool bDepthStencilSupported : 1; ///< depth stencil textures are supported + bool bFPRenderTargetsSupported : 1; ///< floating point render targets are + ///supported + bool bConstantBufferSupported : 1; ///< Constant (uniform) buffers are supported + bool bMsTextureSupported : 1; ///< Multisample textures are esupported + bool bFastBlitsSupported : 1; ///< The hardware supports fast memor blits + bool bTessellationSupported : 1; ///< Hardware supports tessellation + bool bComputeSupported : 1; ///< Hardware supports compute shader + bool bGeometrySupported : 1; ///< Hardware supports geometry shader + bool bTimerQuerySupported : 1; ///< Hardware supports timer queries + bool bProgramInterfaceSupported : 1; ///< API supports program interface queries + bool bStorageBufferSupported : 1; ///< Shader storage buffers are supported + bool bAtomicCounterBufferSupported : 1; ///< Atomic counter buffers are + /// supported + bool bShaderImageLoadStoreSupported : 1; ///< Shader image load / store + ///operations are supported + bool bProgramPipelineSupported : 1; ///< Driver supports separate programs + bool bNVPathRenderingSupported : 1; ///< Driver NV path rendering + bool bNVAdvancedBlendSupported : 1; ///< Advanced blend modes supported + bool bNVBlendCoherenceSupported : 1; ///< Advanced blend done coherently + ///supported + bool bGPUShader5ExtensionSupported : 1; + bool bKHRAdvancedBlendSupported : 1; ///< Advanced blend modes supported + bool bKHRBlendCoherenceSupported : 1; ///< Advanced blend done coherently + bool bVertexArrayObjectSupported : 1; + bool bStandardDerivativesSupported : 1; + bool bTextureLodSupported : 1; + } bits; + + QT3DSU32 u32Values; + } caps; + } NVRenderBackendSupportBits; + + NVRenderBackendSupportBits m_backendSupport; ///< holds the backend support bits + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp new file mode 100644 index 00000000..d38c330c --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp @@ -0,0 +1,887 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Q3DSRenderBackendGLES2.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_MULTISAMPLE_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTENSION_FUNCTION(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_TIMER_EXT(x) +#define GL_CALL_TESSELATION_EXT(x) +#define GL_CALL_MULTISAMPLE_EXT(x) +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTENSION_FUNCTION(x) +#endif + +#ifndef GL_DEPTH_STENCIL_OES +#define GL_DEPTH_STENCIL_OES 0x84F9 +#endif + +namespace qt3ds { +namespace render { + +/// constructor +NVRenderBackendGLES2Impl::NVRenderBackendGLES2Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGLBase(fnd, stringTable, format) +{ + QString exts3tc = QStringLiteral("GL_EXT_texture_compression_s3tc"); + QString extsdxt = QStringLiteral("GL_EXT_texture_compression_dxt1"); + QString extsAniso = QStringLiteral("GL_EXT_texture_filter_anisotropic"); + QString extsTexSwizzle = QStringLiteral("GL_ARB_texture_swizzle"); + QString extsFPRenderTarget = QStringLiteral("GL_EXT_color_buffer_float"); + QString extsTimerQuery = QStringLiteral("GL_EXT_timer_query"); + QString extsGpuShader5 = QStringLiteral("EXT_gpu_shader5"); + QString extDepthTexture = QStringLiteral("GL_OES_packed_depth_stencil"); + QString extvao = QStringLiteral("GL_OES_vertex_array_object"); + QString extStdDd = QStringLiteral("GL_OES_standard_derivatives"); + QString extTexLod = QStringLiteral("GL_EXT_shader_texture_lod"); + + const char *languageVersion = GetShadingLanguageVersion(); + qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + eastl::string apiVendor(getVendorString()); + qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); + + eastl::string apiRenderer(getRendererString()); + qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); + + // clear support bits + m_backendSupport.caps.u32Values = 0; + + const char *extensions = getExtensionString(); + m_extensions = QString::fromLocal8Bit(extensions).split(" "); + + // get extension count + GLint numExtensions = m_extensions.size(); + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + + const QString &extensionString = m_extensions.at(i); + + // search for extension + if (!m_backendSupport.caps.bits.bDXTImagesSupported + && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { + m_backendSupport.caps.bits.bDXTImagesSupported = true; + } else if (!m_backendSupport.caps.bits.bAnistropySupported + && extsAniso.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAnistropySupported = true; + } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported + && extsFPRenderTarget.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + } else if (!m_backendSupport.caps.bits.bTimerQuerySupported + && extsTimerQuery.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported + && extsGpuShader5.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; + } else if (!m_backendSupport.caps.bits.bTextureSwizzleSupported + && extsTexSwizzle.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTextureSwizzleSupported = true; + } else if (!m_backendSupport.caps.bits.bDepthStencilSupported + && extDepthTexture.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bDepthStencilSupported = true; + } else if (!m_backendSupport.caps.bits.bVertexArrayObjectSupported + && extvao.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; + } else if (!m_backendSupport.caps.bits.bStandardDerivativesSupported + && extStdDd.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bStandardDerivativesSupported = true; + } else if (!m_backendSupport.caps.bits.bTextureLodSupported + && extTexLod.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTextureLodSupported = true; + } + } + + qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensions); + + // constant buffers support is always not true + m_backendSupport.caps.bits.bConstantBufferSupported = false; + + // query hardware + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); + + // internal state tracker + m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); + + // finally setup caps based on device + setAndInspectHardwareCaps(); + + // Initialize extensions +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#endif +} +/// destructor +NVRenderBackendGLES2Impl::~NVRenderBackendGLES2Impl() +{ + if (m_pCurrentMiscState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + if (m_qt3dsExtensions) + delete m_qt3dsExtensions; +#endif +} + +void NVRenderBackendGLES2Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(samples); + NVRENDER_BACKEND_UNUSED(internalFormat); + NVRENDER_BACKEND_UNUSED(width); + NVRENDER_BACKEND_UNUSED(height); + NVRENDER_BACKEND_UNUSED(fixedsamplelocations); +} + +void NVRenderBackendGLES2Impl::SetTextureData3D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, + QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + } + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + } + + GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, + (GLsizei)height, (GLsizei)depth, border, glformat, + gltype, hostPtr)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLES2Impl::SetTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + glInternalFormat = glformat; + } + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) { + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + if (format == NVRenderTextureFormats::Depth24Stencil8) { + glformat = GL_DEPTH_STENCIL_OES; + gltype = GL_UNSIGNED_INT_24_8; + } + glInternalFormat = glformat; + } + + Q_ASSERT(glformat == glInternalFormat); + GL_CALL_EXTRA_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, + (GLsizei)height, border, glformat, gltype, hostPtr)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +void NVRenderBackendGLES2Impl::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) +{ + + // Satisfy the compiler + // These are not available in GLES 3 and we don't use them right now + QT3DS_ASSERT(lodBias == 0.0); + QT3DS_ASSERT(!borderColor); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(borderColor); + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + anisotropy)); + } +} + +void NVRenderBackendGLES2Impl::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) +{ + NVRENDER_BACKEND_UNUSED(to); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); +} + +void NVRenderBackendGLES2Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) +{ + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(swizzleMode); +#if defined(QT_OPENGL_ES) + if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { + GLint glSwizzle[4]; + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); + + // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); + + } +#endif +} + +QT3DSU32 +NVRenderBackendGLES2Impl::GetDepthBits() const +{ + QT3DSI32 depthBits; + GL_CALL_EXTRA_FUNCTION( + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); + + return depthBits; +} + +QT3DSU32 +NVRenderBackendGLES2Impl::GetStencilBits() const +{ + QT3DSI32 stencilBits; + GL_CALL_EXTRA_FUNCTION( + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilBits)); + + return stencilBits; +} + +void NVRenderBackendGLES2Impl::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum /*genType*/) +{ + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +} + +bool NVRenderBackendGLES2Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) +{ + if (iao == nullptr) { + // unbind and return; + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(0)); + return true; + } + + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + NVDataRef<NVRenderBackendShaderInputEntryGL> shaderAttribBuffer; + if (pProgram->m_shaderInput) + shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; + + if ((attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) + || (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot)) { + return false; + } + + if (inputAssembler->m_VaoID == 0) { + // generate vao + GL_CALL_EXTENSION_FUNCTION(glGenVertexArraysOES(1, &inputAssembler->m_VaoID)); + QT3DS_ASSERT(inputAssembler->m_VaoID); + } + + if (inputAssembler->m_cachedShaderHandle != programID) { + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); + inputAssembler->m_cachedShaderHandle = programID; + + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents) { + qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + return false; + } else { + entryData.m_AttribIndex = attrib.m_AttribLocation; + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + + // disable max possible used first + // this is currently sufficient since we always re-arrange input attributes from 0 + for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); + + // setup all attribs + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); + if (entry) { + const NVRenderBackendLayoutEntryGL &entryData(*entry); + GLuint id = HandleToID_cast( + GLuint, size_t, + inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); + GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); + GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; + GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; + GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( + entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, + stride, (const void *)(entryData.m_Offset + offset))); + + } else { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); + } + } + + // setup index buffer. + if (inputAssembler->m_IndexbufferHandle) { + GL_CALL_EXTRA_FUNCTION(glBindBuffer( + GL_ELEMENT_ARRAY_BUFFER, + HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); + } else { + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + } else { + GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID)); + } +#ifdef _DEBUG + if (inputAssembler->m_VaoID) { + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents + || entryData.m_AttribIndex != attrib.m_AttribLocation) { + qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + } +#endif // _DEBUG + + return true; +} + +void NVRenderBackendGLES2Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef<QT3DSI32> inDrawBufferSet) +{ + NVRENDER_BACKEND_UNUSED(rto); + + m_DrawBuffersArray.clear(); + + for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { + if (inDrawBufferSet[idx] < 0) + m_DrawBuffersArray.push_back(GL_NONE); + else + m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); + } + + GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), + m_DrawBuffersArray.data())); +} + +void NVRenderBackendGLES2Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) +{ + NVRENDER_BACKEND_UNUSED(rto); + NVRENDER_BACKEND_UNUSED(inReadFace); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) +{ + NVRENDER_BACKEND_UNUSED(attachment); + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(level); + NVRENDER_BACKEND_UNUSED(layer); + Q_ASSERT(false); +} + +void NVRenderBackendGLES2Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, + QT3DSI32 srcY1, QT3DSI32 dstX0, QT3DSI32 dstY0, + QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) +{ + GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, + dstY1, + m_Conversion.fromClearFlagsToGL(flags), + m_Conversion.fromTextureMagnifyingOpToGL(filter))); +} + + +NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLES2Impl::CreateRenderTarget() +{ + GLuint fboID = 0; + GL_CALL_EXTRA_FUNCTION(glGenFramebuffers(1, &fboID)); + return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; +} + +void NVRenderBackendGLES2Impl::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + if (fboID) + GL_CALL_EXTRA_FUNCTION(glDeleteFramebuffers(1, &fboID)); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) +{ + // rto must be the current render target + GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_EXTRA_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, + rbID)); +} + +void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target) +{ + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D + || m_backendSupport.caps.bits.bMsTextureSupported); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + if (attachment == NVRenderFrameBufferAttachments::DepthStencil) { + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + glTarget, texID, 0)); + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + glTarget, texID, 0)); + } else { + GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, + 0)); + } +} + +void NVRenderBackendGLES2Impl::SetRenderTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); +} + +void NVRenderBackendGLES2Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) +{ + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); +} + +bool NVRenderBackendGLES2Impl::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) +{ + GLenum completeStatus = GL_CALL_EXTRA_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); + switch (completeStatus) { +#define HANDLE_INCOMPLETE_STATUS(x) \ + case x: \ + qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ + return false; + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) + #undef HANDLE_INCOMPLETE_STATUS + } + return true; +} + +NVRenderBackend::NVRenderBackendRenderbufferObject +NVRenderBackendGLES2Impl::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + GLuint bufID = 0; + + GL_CALL_EXTRA_FUNCTION(glGenRenderbuffers(1, &bufID)); + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + bufID = 0; + } + + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; +} + +void NVRenderBackendGLES2Impl::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) +{ + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + if (bufID) + GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID)); +} + +bool NVRenderBackendGLES2Impl::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) +{ + bool success = true; + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + QT3DS_ASSERT(bufID); + + GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + success = false; + } + + return success; +} + +void *NVRenderBackendGLES2Impl::MapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t length, NVRenderBufferAccessFlags accessFlags) +{ + void *ret = nullptr; + ret = GL_CALL_EXTRA_FUNCTION( + glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, + length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); + + return ret; +} + +bool NVRenderBackendGLES2Impl::UnmapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags) +{ + GLboolean ret; + + ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); + + return (ret) ? true : false; +} + +QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) +{ + QT3DS_ASSERT(po); + GLint numUniformBuffers = 0; + if (GetRenderBackendCap(NVRenderBackendCaps::ConstantBuffer)) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, + &numUniformBuffers)); + } + return numUniformBuffers; +} + +QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferInfoByID( + NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + GLuint blockIndex = GL_INVALID_INDEX; + + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, + nameBuf)); + + if (*length > 0) { + blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); + if (blockIndex != GL_INVALID_INDEX) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); + } + } + + return blockIndex; +} + +void NVRenderBackendGLES2Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + if (indices) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + indices)); + } +} + +void NVRenderBackendGLES2Impl::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) +{ + QT3DS_ASSERT(po); + QT3DS_ASSERT(count); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + if (count && indices) { + if (type) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, + GL_UNIFORM_TYPE, type)); + // convert to UIC types + QT3DS_FOREACH(idx, count) + { + type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); + } + } + if (size) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, + GL_UNIFORM_SIZE, size)); + } + if (offset) { + GL_CALL_EXTRA_FUNCTION( + glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); + } + } +} + +void NVRenderBackendGLES2Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) +{ + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); +} + +void NVRenderBackendGLES2Impl::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) +{ + QT3DS_ASSERT(bo); + + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); +} + +NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLES2Impl::CreateQuery() +{ + QT3DSU32 glQueryID = 0; + + return (NVRenderBackendQueryObject)glQueryID; +} + +void NVRenderBackendGLES2Impl::ReleaseQuery(NVRenderBackendQueryObject) +{ + +} + +void NVRenderBackendGLES2Impl::BeginQuery(NVRenderBackendQueryObject, + NVRenderQueryType::Enum) +{ + +} + +void NVRenderBackendGLES2Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) +{ + +} + +void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, + QT3DSU32 *) +{ + +} + +void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, + QT3DSU64 *) +{ + +} + +void NVRenderBackendGLES2Impl::SetQueryTimer(NVRenderBackendQueryObject) +{ + +} + +NVRenderBackend::NVRenderBackendSyncObject +NVRenderBackendGLES2Impl::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) +{ + GLsync syncID = 0; + return NVRenderBackendSyncObject(syncID); +} + +void NVRenderBackendGLES2Impl::ReleaseSync(NVRenderBackendSyncObject) +{ + +} + +void NVRenderBackendGLES2Impl::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, + QT3DSU64) +{ + +} +} +} diff --git a/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h new file mode 100644 index 00000000..4890de0e --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_BACKEND_GLES2_H +#define QT3DS_RENDER_BACKEND_GLES2_H + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +#include <QtGui/qopenglextrafunctions.h> +#include <QtOpenGLExtensions/QtOpenGLExtensions> + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendMiscStateGL; + + using namespace foundation; + + class NVRenderBackendGLES2Impl : public NVRenderBackendGLBase + { + public: + /// constructor + NVRenderBackendGLES2Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGLES2Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = nullptr) override; + + void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = nullptr) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0f, QT3DSF32 maxLod = 1000.0f, QT3DSF32 lodBias = 0.0f, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0f, QT3DSF32 *borderColor = nullptr) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override; + + void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef<QT3DSI32> inDrawBufferSet) override; + void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) override; + + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + + NVRenderBackendRenderTargetObject CreateRenderTarget() override; + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target + = NVRenderTextureTargetType::Texture2D) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) override; + void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; + + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) override; + void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) override; + + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, + QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + protected: + NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; +#endif + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp new file mode 100644 index 00000000..564ecd5a --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +Qt3DSOpenGLExtensions::Qt3DSOpenGLExtensions() + : QAbstractOpenGLExtension(*(new Qt3DSOpenGLExtensionsPrivate)) +{ +} + +bool Qt3DSOpenGLExtensions::initializeOpenGLFunctions() +{ + if (isInitialized()) + return true; + + QT_PREPEND_NAMESPACE(QOpenGLContext) *context = + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); + if (!context) { + qWarning("A current OpenGL context is required to resolve functions"); + return false; + } + + Q_D(Qt3DSOpenGLExtensions); + + d->BlendBarrierNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)()>( + context->getProcAddress("glBlendBarrierNV")); + d->PathGlyphIndexArrayNV = reinterpret_cast<GLenum (QOPENGLF_APIENTRYP)( + GLuint, GLenum, const void*, GLbitfield, GLuint, GLsizei, GLuint, + GLfloat)>( + context->getProcAddress("glPathGlyphIndexArrayNV")); + d->PathGlyphIndexRangeNV = reinterpret_cast<GLenum (QOPENGLF_APIENTRYP)( + GLenum, const void*, GLbitfield, GLuint, GLfloat, GLuint[2])>( + context->getProcAddress("glPathGlyphIndexRangeNV")); + QAbstractOpenGLExtension::initializeOpenGLFunctions(); + return true; +} + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +Qt3DSOpenGLES2Extensions::Qt3DSOpenGLES2Extensions() +{ +} + +bool Qt3DSOpenGLES2Extensions::initializeOpenGLFunctions() +{ + if (isInitialized()) + return true; + + QT_PREPEND_NAMESPACE(QOpenGLContext) *context = + QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(); + if (!context) { + qWarning("A current OpenGL context is required to resolve functions"); + return false; + } + + Q_D(Qt3DSOpenGLExtensions); + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + d->PatchParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLenum, GLint)>( + context->getProcAddress("glPatchParameteriEXT")); + d->QueryCounterEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLenum)>( + context->getProcAddress("glQueryCounterEXT")); + d->GetQueryObjectui64vEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLenum, GLuint64 *)>( + context->getProcAddress("glGetQueryObjectui64vEXT")); + d->GenPathsNV = reinterpret_cast<GLuint (QOPENGLF_APIENTRYP)( + GLsizei)>( + context->getProcAddress("glGenPathsNV")); + d->DeletePathsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLsizei)>( + context->getProcAddress("glDeletePathsNV")); + d->PathCommandsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLsizei, const GLubyte *, GLsizei, GLenum, const void *)>( + context->getProcAddress("glPathCommandsNV")); + d->PathGlyphsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLenum, const void *, GLbitfield, GLsizei, GLenum, const void *, + GLenum, GLuint, GLfloat)>( + context->getProcAddress("glPathGlyphsNV")); + d->PathGlyphRangeNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLenum, const void *, GLbitfield, GLuint, GLsizei, GLenum, + GLuint, GLfloat)>( + context->getProcAddress("glPathGlyphRangeNV")); + d->PathParameterfNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLenum, GLfloat)>( + context->getProcAddress("glPathParameterfNV")); + d->PathStencilDepthOffsetNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLfloat, GLfloat)>( + context->getProcAddress("glPathStencilDepthOffsetNV")); + d->StencilFillPathNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLenum, GLuint)>( + context->getProcAddress("glStencilFillPathNV")); + d->StencilStrokePathNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLint, GLuint)>( + context->getProcAddress("glStencilStrokePathNV")); + d->StencilFillPathInstancedNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLsizei, GLenum, const void *, GLuint, GLenum, GLuint, GLenum, + const GLfloat *)>( + context->getProcAddress("glStencilFillPathInstancedNV")); + d->StencilStrokePathInstancedNV + = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei, GLenum, + const void *, GLuint, GLint, GLuint, GLenum, const GLfloat *)>( + context->getProcAddress("glStencilStrokePathInstancedNV")); + d->PathCoverDepthFuncNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLenum func)>( + context->getProcAddress("glPathCoverDepthFuncNV")); + d->CoverFillPathInstancedNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLsizei, GLenum, const void *, GLuint, GLenum, GLenum, + const GLfloat *)>( + context->getProcAddress("glCoverFillPathInstancedNV")); + d->CoverStrokePathInstancedNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLsizei, GLenum, const void *, GLuint, GLenum, GLenum, + const GLfloat *)>( + context->getProcAddress("glCoverStrokePathInstancedNV")); + d->GetPathParameterfvNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLuint, GLenum, GLfloat *)>( + context->getProcAddress("glGetPathParameterfvNV")); + d->GetPathMetricsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLbitfield, GLsizei, GLenum, const void *, GLuint, GLsizei, GLfloat *)>( + context->getProcAddress("glGetPathMetricsNV")); + d->GetPathMetricRangeNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLbitfield, GLuint, GLsizei, GLsizei, GLfloat *)>( + context->getProcAddress("glGetPathMetricRangeNV")); + d->GetPathSpacingNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)( + GLenum, GLsizei, GLenum, const void *, GLuint, GLfloat, GLfloat, GLenum, + GLfloat *)>( + context->getProcAddress("glGetPathSpacingNV")); + d->BindVertexArrayOES = reinterpret_cast<void (QOPENGLF_APIENTRYP) + (GLuint)>( + context->getProcAddress("glBindVertexArrayOES")); + d->DeleteVertexArraysOES = reinterpret_cast<void (QOPENGLF_APIENTRYP) + (GLsizei, const GLuint *)>( + context->getProcAddress("glDeleteVertexArraysOES")); + d->GenVertexArraysOES = reinterpret_cast<void (QOPENGLF_APIENTRYP) + (GLsizei, GLuint *)>( + context->getProcAddress("glGenVertexArraysOES")); + d->IsVertexArrayOES = reinterpret_cast<GLboolean (QOPENGLF_APIENTRYP) + (GLuint)>( + context->getProcAddress("glIsVertexArrayOES")); +#endif + Qt3DSOpenGLExtensions::initializeOpenGLFunctions(); + return true; +} +#endif // QT_OPENGL_ES diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h new file mode 100644 index 00000000..c9ba76a6 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h @@ -0,0 +1,392 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLEXTENSIONS_H +#define QT3DSOPENGLEXTENSIONS_H + +#include <QtOpenGLExtensions/QtOpenGLExtensions> + +/* Some OpenGL extensions that are not (yet) found in Qt's OpenGL extensions. + * These should be auto-generated and added to QtOpenGLExtensions module */ +class Qt3DSOpenGLExtensionsPrivate : public QAbstractOpenGLExtensionPrivate +{ +public: + void (QOPENGLF_APIENTRYP BlendBarrierNV)(); + GLenum (QOPENGLF_APIENTRYP PathGlyphIndexArrayNV)( + GLuint, GLenum, const void*, GLbitfield, GLuint, GLsizei, GLuint, + GLfloat); + GLenum (QOPENGLF_APIENTRYP PathGlyphIndexRangeNV)( + GLenum, const void*, GLbitfield, GLuint, GLfloat, GLuint[2]); + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) + void (QOPENGLF_APIENTRYP PatchParameteriEXT)(GLenum, GLint); + void (QOPENGLF_APIENTRYP QueryCounterEXT)(GLuint, GLenum); + void (QOPENGLF_APIENTRYP GetQueryObjectui64vEXT)(GLuint, GLenum, + GLuint64 *); + GLuint (QOPENGLF_APIENTRYP GenPathsNV)(GLsizei); + void (QOPENGLF_APIENTRYP DeletePathsNV)(GLuint, GLsizei); + void (QOPENGLF_APIENTRYP PathCommandsNV)(GLuint, GLsizei, const GLubyte *, + GLsizei, GLenum, const void *); + void (QOPENGLF_APIENTRYP PathGlyphsNV)(GLuint, GLenum, const void *, + GLbitfield, GLsizei, GLenum, const void *, GLenum, GLuint, GLfloat); + void (QOPENGLF_APIENTRYP PathGlyphRangeNV)(GLuint, GLenum, const void *, + GLbitfield, GLuint, GLsizei, GLenum, GLuint, GLfloat); + void (QOPENGLF_APIENTRYP PathParameterfNV)(GLuint, GLenum, GLfloat); + void (QOPENGLF_APIENTRYP PathStencilDepthOffsetNV)(GLfloat, GLfloat); + void (QOPENGLF_APIENTRYP StencilFillPathNV)(GLuint, GLenum, GLuint); + void (QOPENGLF_APIENTRYP StencilStrokePathNV)(GLuint, GLint, GLuint); + void (QOPENGLF_APIENTRYP StencilFillPathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLuint, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP StencilStrokePathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLint, GLuint, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP PathCoverDepthFuncNV)(GLenum); + void (QOPENGLF_APIENTRYP CoverFillPathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP CoverStrokePathInstancedNV)(GLsizei, GLenum, + const void *, GLuint, GLenum, GLenum, const GLfloat *); + void (QOPENGLF_APIENTRYP GetPathParameterfvNV)(GLuint, GLenum, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathMetricsNV)(GLbitfield, GLsizei, GLenum, + const void *, GLuint, GLsizei, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathMetricRangeNV)(GLbitfield, GLuint, GLsizei, + GLsizei, GLfloat *); + void (QOPENGLF_APIENTRYP GetPathSpacingNV)(GLenum, GLsizei, GLenum, + const void *, GLuint, GLfloat, GLfloat, GLenum, GLfloat *); + void (QOPENGLF_APIENTRYP BindVertexArrayOES) (GLuint array); + void (QOPENGLF_APIENTRYP DeleteVertexArraysOES) (GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP GenVertexArraysOES) (GLsizei n, GLuint *arrays); + GLboolean (QOPENGLF_APIENTRYP IsVertexArrayOES) (GLuint array); +#endif +}; + +class Qt3DSOpenGLExtensions : public QAbstractOpenGLExtension +{ +public: + Qt3DSOpenGLExtensions(); + + bool initializeOpenGLFunctions() override; + + void glBlendBarrierNV(); + GLenum glPathGlyphIndexArrayNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, + GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); + GLenum glPathGlyphIndexRangeNV(GLenum fontTarget, const void *fontName, + GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, + GLuint baseAndCount[2]); + +protected: + Q_DECLARE_PRIVATE(Qt3DSOpenGLExtensions) +}; + +inline void Qt3DSOpenGLExtensions::glBlendBarrierNV() +{ + Q_D(Qt3DSOpenGLExtensions); + d->BlendBarrierNV(); +} + +inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexArrayNV( + GLuint firstPathName, GLenum fontTarget, const void *fontName, + GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, + GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->PathGlyphIndexArrayNV(firstPathName, fontTarget, fontName, + fontStyle, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale); +} + +inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexRangeNV(GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, + GLfloat emScale, GLuint baseAndCount[2]) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->PathGlyphIndexRangeNV(fontTarget, fontName, fontStyle, + pathParameterTemplate, emScale, baseAndCount); +} + +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE) +class Qt3DSOpenGLES2Extensions : public Qt3DSOpenGLExtensions +{ +public: + Qt3DSOpenGLES2Extensions(); + + // tesselation shader + void glPatchParameteriEXT(GLenum pname, GLint value); + + // timer + void glQueryCounterEXT(GLuint id, GLenum target); + void glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params); + + // nv paths + + GLuint glGenPathsNV(GLsizei range); + void glDeletePathsNV(GLuint path, GLsizei range); + void glPathCommandsNV(GLuint path, GLsizei numCommands, + const GLubyte *commands, GLsizei numCoords, GLenum coordType, + const void *coords); + void glPathGlyphsNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, + GLenum type, const void *charcodes, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale); + void glPathGlyphRangeNV(GLuint firstPathName, GLenum fontTarget, + const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, + GLsizei numGlyphs, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale); + void glPathParameterfNV(GLuint path, GLenum pname, GLfloat value); + void glPathStencilDepthOffsetNV(GLfloat factor, GLfloat units); + void glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask); + void glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask); + void glStencilFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, + GLenum transformType, const GLfloat *transformValues); + void glStencilStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLint reference, GLuint mask, + GLenum transformType, const GLfloat *transformValues); + void glPathCoverDepthFuncNV(GLenum func); + void glCoverFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum coverMode, + GLenum transformType, const GLfloat *transformValues); + void glCoverStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLenum coverMode, + GLenum transformType, const GLfloat *transformValues); + void glGetPathParameterfvNV(GLuint path, GLenum pname, GLfloat *value); + void glGetPathMetricsNV(GLbitfield metricQueryMask, GLsizei numPaths, + GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, + GLfloat *metrics); + void glGetPathMetricRangeNV(GLbitfield metricQueryMask, + GLuint firstPathName, GLsizei numPaths, GLsizei stride, + GLfloat *metrics); + void glGetPathSpacingNV(GLenum pathListMode, GLsizei numPaths, + GLenum pathNameType, const void *paths, GLuint pathBase, + GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, + GLfloat *returnedSpacing); + void glBindVertexArrayOES(GLuint array); + void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays); + void glGenVertexArraysOES(GLsizei n, GLuint *arrays); + GLboolean glIsVertexArrayOES(GLuint array); + + bool initializeOpenGLFunctions() Q_DECL_FINAL; +}; + +inline void Qt3DSOpenGLES2Extensions::glPatchParameteriEXT(GLenum pname, + GLint value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PatchParameteriEXT(pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glQueryCounterEXT(GLuint id, + GLenum target) +{ + Q_D(Qt3DSOpenGLExtensions); + d->QueryCounterEXT(id, target); +} + +inline void Qt3DSOpenGLES2Extensions::glGetQueryObjectui64vEXT(GLuint id, + GLenum pname, GLuint64 *params) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetQueryObjectui64vEXT(id, pname, params); +} + +inline GLuint Qt3DSOpenGLES2Extensions::glGenPathsNV(GLsizei range) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->GenPathsNV(range); +} + +inline void Qt3DSOpenGLES2Extensions::glDeletePathsNV(GLuint path, + GLsizei range) +{ + Q_D(Qt3DSOpenGLExtensions); + d->DeletePathsNV(path, range); +} + +inline void Qt3DSOpenGLES2Extensions::glPathCommandsNV(GLuint path, + GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, + GLenum coordType, const void *coords) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathCommandsNV(path, numCommands, commands, numCoords, coordType, + coords); +} + +inline void Qt3DSOpenGLES2Extensions::glPathGlyphsNV(GLuint firstPathName, + GLenum fontTarget, const void *fontName, GLbitfield fontStyle, + GLsizei numGlyphs, GLenum type, const void *charcodes, + GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathGlyphsNV(firstPathName, fontTarget, fontName, fontStyle, numGlyphs, + type, charcodes, handleMissingGlyphs, pathParameterTemplate, emScale); +} + +inline void Qt3DSOpenGLES2Extensions::glPathGlyphRangeNV(GLuint firstPathName, + GLenum fontTarget, const void *fontName, GLbitfield fontStyle, + GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, + GLuint pathParameterTemplate, GLfloat emScale) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathGlyphRangeNV(firstPathName, fontTarget, fontName, fontStyle, + firstGlyph, numGlyphs, handleMissingGlyphs, pathParameterTemplate, + emScale); +} + +inline void Qt3DSOpenGLES2Extensions::glPathParameterfNV(GLuint path, + GLenum pname, GLfloat value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathParameterfNV(path, pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glPathStencilDepthOffsetNV(GLfloat factor, + GLfloat units) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathStencilDepthOffsetNV(factor, units); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilFillPathNV(GLuint path, + GLenum fillMode, GLuint mask) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilFillPathNV(path, fillMode, mask); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathNV(GLuint path, + GLint reference, GLuint mask) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilStrokePathNV(path, reference, mask); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilFillPathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum fillMode, GLuint mask, GLenum transformType, + const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, + fillMode, mask, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLint reference, GLuint mask, GLenum transformType, + const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->StencilStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, + reference, mask, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glPathCoverDepthFuncNV(GLenum func) +{ + Q_D(Qt3DSOpenGLExtensions); + d->PathCoverDepthFuncNV(func); +} + +inline void Qt3DSOpenGLES2Extensions::glCoverFillPathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum coverMode, GLenum transformType, const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->CoverFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glCoverStrokePathInstancedNV( + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLenum coverMode, GLenum transformType, const GLfloat *transformValues) +{ + Q_D(Qt3DSOpenGLExtensions); + d->CoverStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathParameterfvNV(GLuint path, + GLenum pname, GLfloat *value) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathParameterfvNV(path, pname, value); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathMetricsNV( + GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, + const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathMetricsNV(metricQueryMask, numPaths, pathNameType, paths, + pathBase, stride, metrics); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathMetricRangeNV( + GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, + GLsizei stride, GLfloat *metrics) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathMetricRangeNV(metricQueryMask, firstPathName, numPaths, stride, + metrics); +} + +inline void Qt3DSOpenGLES2Extensions::glGetPathSpacingNV(GLenum pathListMode, + GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, + GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, + GLfloat *returnedSpacing) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GetPathSpacingNV(pathListMode, numPaths, pathNameType, paths, pathBase, + advanceScale, kerningScale, transformType, returnedSpacing); +} + +inline void Qt3DSOpenGLES2Extensions::glBindVertexArrayOES(GLuint array) +{ + Q_D(Qt3DSOpenGLExtensions); + d->BindVertexArrayOES(array); +} + +inline void Qt3DSOpenGLES2Extensions::glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) +{ + Q_D(Qt3DSOpenGLExtensions); + d->DeleteVertexArraysOES(n, arrays); +} + +inline void Qt3DSOpenGLES2Extensions::glGenVertexArraysOES(GLsizei n, GLuint *arrays) +{ + Q_D(Qt3DSOpenGLExtensions); + d->GenVertexArraysOES(n, arrays); +} + +inline GLboolean Qt3DSOpenGLES2Extensions::glIsVertexArrayOES(GLuint array) +{ + Q_D(Qt3DSOpenGLExtensions); + return d->IsVertexArrayOES(array); +} + +#endif // QT_OPENGL_ES + +#endif // QT3DSOPENGLEXTENSIONS_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h new file mode 100644 index 00000000..0e6dc6d4 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLPREFIX_H +#define QT3DSOPENGLPREFIX_H + +#include <QtGui/qtguiglobal.h> +#if defined(QT_OPENGL_ES) +#define GL_GLEXT_PROTOTYPES +#if defined(QT_OPENGL_ES_3_2) +#include <GLES3/gl32.h> +#else +#include <GLES2/gl2.h> +#include <GLES3/gl3.h> +#endif + +// Adding this to ensure that platform version of gl2ext.h is included +// before Qt's qopengles2ext.h which is missing symbols we need +#include <GLES2/gl2ext.h> +#endif + +#endif // QT3DSOPENGLPREFIX_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h new file mode 100644 index 00000000..882e2761 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h @@ -0,0 +1,408 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLTOKENS_H +#define QT3DSOPENGLTOKENS_H + +/** + * This is our general internal to GL type conversion routines + * Add defines which are not in standard GL(ext) header but in GL2(ext) + * The define are the same with different names + * Expectation is the NVIDIA defines (need for compile) + */ +#ifndef GL_NVIDIA_PLATFORM_BINARY_NV +#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B +#endif +#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT +#endif + +#if defined(__APPLE__) || defined(ANDROID) || defined(__INTEGRITY) +#ifndef GL_DEPTH_COMPONENT24 +#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES +#endif +#ifndef GL_DEPTH_COMPONENT32 +#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES +#endif + +/** +_* tessellation_shader defines + */ +#ifndef GL_TESS_EVALUATION_SHADER +#define GL_TESS_EVALUATION_SHADER GL_TESS_EVALUATION_SHADER_EXT +#endif +#ifndef GL_TESS_CONTROL_SHADER +#define GL_TESS_CONTROL_SHADER GL_TESS_CONTROL_SHADER_EXT +#endif +#ifndef GL_PATCHES +#define GL_PATCHES GL_PATCHES_EXT +#endif +#ifndef GL_PATCH_VERTICES +#define GL_PATCH_VERTICES GL_PATCH_VERTICES_EXT +#endif +#ifndef GL_TESS_CONTROL_SHADER_BIT +#define GL_TESS_CONTROL_SHADER_BIT GL_TESS_CONTROL_SHADER_BIT_EXT +#endif +#ifndef GL_TESS_EVALUATION_SHADER_BIT +#define GL_TESS_EVALUATION_SHADER_BIT GL_TESS_EVALUATION_SHADER_BIT_EXT +#endif +#ifndef GL_VERTEX_SHADER_BIT +#define GL_VERTEX_SHADER_BIT GL_VERTEX_SHADER_BIT_EXT +#endif +#ifndef GL_FRAGMENT_SHADER_BIT +#define GL_FRAGMENT_SHADER_BIT GL_FRAGMENT_SHADER_BIT_EXT +#endif +#ifndef GL_GEOMETRY_SHADER_BIT +#define GL_GEOMETRY_SHADER_BIT GL_GEOMETRY_SHADER_BIT_EXT +#endif + + +/** + * sample shading extension + */ +#ifndef GL_SAMPLE_SHADING +#define GL_SAMPLE_SHADING GL_SAMPLE_SHADING_OES +#endif +#ifndef GL_MIN_SAMPLE_SHADING_VALUE +#define GL_MIN_SAMPLE_SHADING_VALUE GL_MIN_SAMPLE_SHADING_VALUE_OES +#endif + +/** + * Timer query extension + */ +#ifndef GL_TIME_ELAPSED +#define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT +#endif +#ifndef GL_TIMESTAMP +#define GL_TIMESTAMP GL_TIMESTAMP_EXT +#endif + +/** + * compute shader + */ +#ifndef GL_IMAGE_2D +#define GL_IMAGE_2D 0x904D +#endif + +/** + * texture formats ( make build happy ) + */ +#ifndef GL_R16 +#define GL_R16 0x822A +#endif + +#endif // __APPLE__ || ANDROID || __INTEGRITY + +#if defined(__APPLE__) || defined(ANDROID) + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_SHADER_STORAGE_BUFFER +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_ATOMIC_COUNTER_BUFFER +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#endif + +#ifndef GL_ALL_BARRIER_BITS +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#endif + +#ifndef GL_SHADER_STORAGE_BARRIER_BIT +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#endif + +#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif + + + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_2_BYTES_NV 0x1407 +#define GL_3_BYTES_NV 0x1408 +#define GL_4_BYTES_NV 0x1409 +#define GL_EYE_LINEAR_NV 0x2400 +#define GL_OBJECT_LINEAR_NV 0x2401 +#define GL_CONSTANT_NV 0x8576 +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_FRAGMENT_INPUT_NV 0x936D +#endif /* GL_NV_path_rendering */ + +#ifndef GL_SHADER_STORAGE_BLOCK +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#endif + +#ifndef GL_ACTIVE_RESOURCES +#define GL_ACTIVE_RESOURCES 0x92F5 +#endif + +#ifndef GL_BUFFER_BINDING +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#endif + +#ifndef GL_UNIFORM +#define GL_UNIFORM 0x92E1 +#endif + +#ifndef GL_COMPUTE_SHADER +#define GL_COMPUTE_SHADER 0x91B9 +#endif + +#endif // __APPLE__ || ANDROID + +#endif // QT3DSOPENGLTOKENS_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h new file mode 100644 index 00000000..32f7dad7 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h @@ -0,0 +1,2201 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DSOPENGLUTIL_H +#define QT3DSOPENGLUTIL_H + +#include "render/backends/gl/Qt3DSOpenGLPrefix.h" +#include "render/backends/gl/Qt3DSOpenGLTokens.h" +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLExtraFunctions> + +#include "foundation/Qt3DSVec2.h" +#include "foundation/Qt3DSVec3.h" +#include "foundation/Qt3DSVec4.h" +#include "foundation/Qt3DSFoundation.h" + +// The actual binding to the hardware the does some minor conversions between gles and +// the nv render enumeration types +namespace qt3ds { +namespace render { + +#ifndef GL_TEXTURE_2D_MULTISAMPLE +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#endif + +#ifndef GL_IMAGE_2D +#define GL_IMAGE_2D 0x904D +#endif + +#ifndef GL_MULTISAMPLE_EXT +#define GL_MULTISAMPLE_EXT 0x809D +#endif + +#ifndef GL_COLOR_ATTACHMENT1 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#endif + +#ifndef GL_RED +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#endif + +#ifndef GL_PATCHES +#define GL_PATCHES 0x000E +#endif + +#ifndef GL_READ_ONLY +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#endif + +#ifndef GL_SHADER_STORAGE_BUFFER +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_ATOMIC_COUNTER_BUFFER +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#endif + +#ifndef GL_DRAW_INDIRECT_BUFFER +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#endif + +#ifndef GL_VERTEX_SHADER_BIT +#define GL_VERTEX_SHADER_BIT 0x00000001 +#endif + +#ifndef GL_FRAGMENT_SHADER_BIT +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#endif + +#ifndef GL_GEOMETRY_SHADER_BIT +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#endif + +#ifndef GL_TESS_CONTROL_SHADER_BIT +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#endif + +#ifndef GL_TESS_EVALUATION_SHADER_BIT +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#endif + +#ifndef GL_ETC1_RGB8_OES +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +#ifndef GL_COMPRESSED_RED_RGTC1 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#endif + +#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#endif + +#ifndef GL_COMPRESSED_RG_RGTC2 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#endif + +#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM_ARB +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#endif + +#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#endif + +#ifndef GL_COMPRESSED_RGB8_ETC2 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ETC2 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#endif + +#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#endif + +#ifndef GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#endif + +#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#endif + +#ifndef GL_COMPRESSED_R11_EAC +#define GL_COMPRESSED_R11_EAC 0x9270 +#endif + +#ifndef GL_COMPRESSED_SIGNED_R11_EAC +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#endif + +#ifndef GL_COMPRESSED_RG11_EAC +#define GL_COMPRESSED_RG11_EAC 0x9272 +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG11_EAC +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#endif + +#define QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ZERO, Zero) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE, One) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_COLOR, SrcColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_COLOR, OneMinusSrcColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_COLOR, DstColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_COLOR, OneMinusDstColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_ALPHA, SrcAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_ALPHA, OneMinusSrcAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_ALPHA, DstAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_ALPHA, OneMinusDstAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_COLOR, ConstantColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_COLOR, OneMinusConstantColor) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_ALPHA, ConstantAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_ALPHA, OneMinusConstantAlpha) \ + QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(GL_SRC_ALPHA_SATURATE, SrcAlphaSaturate) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT, Front) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_BACK, Back) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT_AND_BACK, FrontAndBack) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CW, Clockwise) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CCW, CounterClockwise) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NEVER, Never) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LESS, Less) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_EQUAL, Equal) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LEQUAL, LessThanOrEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GREATER, Greater) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NOTEQUAL, NotEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GEQUAL, GreaterThanOrEqual) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_ALWAYS, AlwaysTrue) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_HINT \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_FASTEST, Fastest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_NICEST, Nicest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_DONT_CARE, Unspecified) + +#define QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_KEEP, Keep) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_ZERO, Zero) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_REPLACE, Replace) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR, Increment) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR_WRAP, IncrementWrap) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR, Decrement) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR_WRAP, DecrementWrap) \ + QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INVERT, Invert) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_BYTE, QT3DSU8) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_BYTE, QT3DSI8) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_SHORT, QT3DSU16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_SHORT, QT3DSI16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_INT, QT3DSU32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(GL_INT, QT3DSI32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_FLOAT, QT3DSF32) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_STATIC_DRAW, Static) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_DYNAMIC_DRAW, Dynamic) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_NEAREST, Nearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_LINEAR, Linear) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_NEAREST, NearestMipmapNearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_NEAREST, LinearMipmapNearest) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_LINEAR, NearestMipmapLinear) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_LINEAR, LinearMipmapLinear) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_CLAMP_TO_EDGE, ClampToEdge) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_MIRRORED_REPEAT, MirroredRepeat) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_REPEAT, Repeat) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT, QT3DSF32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC2, QT3DSVec2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC3, QT3DSVec3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC4, QT3DSVec4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT, QT3DSI32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC2, QT3DSI32_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC3, QT3DSI32_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC4, QT3DSI32_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL, QT3DSRenderBool) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC2, bool_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC3, bool_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC4, bool_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT, QT3DSU32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC2, QT3DSU32_2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC3, QT3DSU32_3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC4, QT3DSU32_4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT3, QT3DSMat33) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT4, QT3DSMat44) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D, NVRenderTexture2DPtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D_ARRAY, NVRenderTexture2DArrayPtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_CUBE, NVRenderTextureCubePtr) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_IMAGE_2D, NVRenderImage2DPtr) +// cube Sampler and mat22 unsupported + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT, QT3DSF32, 1) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC2, QT3DSF32, 2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC3, QT3DSF32, 3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC4, QT3DSF32, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT2, QT3DSF32, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT3, QT3DSF32, 9) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT4, QT3DSF32, 16) +#if defined(GL_DEPTH_COMPONENT32) +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT32, Depth32) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) +#else +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8) +#endif + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color0, 0) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color1, 1) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color2, 2) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color3, 3) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color4, 4) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color5, 5) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color6, 6) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color7, 7) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_ATTACHMENT, Depth) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_STENCIL_ATTACHMENT, Stencil) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_STENCIL_ATTACHMENT, DepthStencil) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_COLOR_BUFFER_BIT, Color) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_DEPTH_BUFFER_BIT, Depth) \ + QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_STENCIL_BUFFER_BIT, Stencil) + +#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS + + static bool IsGlEsContext(NVRenderContextType inContextType) + { + NVRenderContextType esContextTypes(NVRenderContextValues::GLES2 + | NVRenderContextValues::GLES3 + | NVRenderContextValues::GLES3PLUS); + + if ((inContextType & esContextTypes)) + return true; + + return false; + } + + struct GLConversion + { + GLConversion() + { } + + static const char *processGLError(GLenum error) + { + const char *errorString = ""; + switch (error) { +#define stringiseError(error) \ + case error: \ + errorString = #error; \ + break + stringiseError(GL_NO_ERROR); + stringiseError(GL_INVALID_ENUM); + stringiseError(GL_INVALID_VALUE); + stringiseError(GL_INVALID_OPERATION); + stringiseError(GL_INVALID_FRAMEBUFFER_OPERATION); + stringiseError(GL_OUT_OF_MEMORY); +#undef stringiseError + default: + errorString = "Unknown GL error"; + break; + } + return errorString; + } + + static NVRenderSrcBlendFunc::Enum fromGLToSrcBlendFunc(QT3DSI32 value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case srcVal: \ + return NVRenderSrcBlendFunc::enumVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ + case srcVal: \ + return NVRenderSrcBlendFunc::enumVal; + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return NVRenderSrcBlendFunc::Unknown; + } + } + + static GLenum fromSrcBlendFuncToGL(NVRenderSrcBlendFunc::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case NVRenderSrcBlendFunc::enumVal: \ + return srcVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \ + case NVRenderSrcBlendFunc::enumVal: \ + return srcVal; + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return 0; + } + } + + static NVRenderDstBlendFunc::Enum fromGLToDstBlendFunc(QT3DSI32 value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case srcVal: \ + return NVRenderDstBlendFunc::enumVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return NVRenderDstBlendFunc::Unknown; + } + } + + static GLenum fromDstBlendFuncToGL(NVRenderDstBlendFunc::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \ + case NVRenderDstBlendFunc::enumVal: \ + return srcVal; +#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) + QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC +#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY + default: + QT3DS_ASSERT(false); + return 0; + } + } + + static GLenum fromBlendEquationToGL(NVRenderBlendEquation::Enum value, + bool nvAdvancedBlendSupported, + bool khrAdvancedBlendSupported) + { + switch (value) { + case NVRenderBlendEquation::Add: + return GL_FUNC_ADD; + case NVRenderBlendEquation::Subtract: + return GL_FUNC_SUBTRACT; + case NVRenderBlendEquation::ReverseSubtract: + return GL_FUNC_REVERSE_SUBTRACT; + default: + QT3DS_ASSERT(nvAdvancedBlendSupported || khrAdvancedBlendSupported); + break; + } + + if (nvAdvancedBlendSupported) { + switch (value) { + case NVRenderBlendEquation::Overlay: + return GL_OVERLAY_NV; + case NVRenderBlendEquation::ColorBurn: + return GL_COLORBURN_NV; + case NVRenderBlendEquation::ColorDodge: + return GL_COLORDODGE_NV; + default: + break; + } + } + +#if defined(GL_KHR_blend_equation_advanced) + if (khrAdvancedBlendSupported) { + switch (value) { + case NVRenderBlendEquation::Overlay: + return GL_OVERLAY_KHR; + case NVRenderBlendEquation::ColorBurn: + return GL_COLORBURN_KHR; + case NVRenderBlendEquation::ColorDodge: + return GL_COLORDODGE_KHR; + default: + break; + } + } +#endif + + QT3DS_ASSERT(false); + return GL_FUNC_ADD; + } + + static NVRenderFaces::Enum fromGLToFaces(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ + case x: \ + return NVRenderFaces::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderFaces::Unknown; + } + + static GLenum fromFacesToGL(NVRenderFaces::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \ + case NVRenderFaces::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVReadFaces::Enum fromGLToReadFaces(GLenum value) + { + switch (value) { + case GL_FRONT: + return NVReadFaces::Front; + case GL_BACK: + return NVReadFaces::Back; + case GL_COLOR_ATTACHMENT0: + return NVReadFaces::Color0; + case GL_COLOR_ATTACHMENT1: + return NVReadFaces::Color1; + case GL_COLOR_ATTACHMENT2: + return NVReadFaces::Color2; + case GL_COLOR_ATTACHMENT3: + return NVReadFaces::Color3; + case GL_COLOR_ATTACHMENT4: + return NVReadFaces::Color4; + case GL_COLOR_ATTACHMENT5: + return NVReadFaces::Color5; + case GL_COLOR_ATTACHMENT6: + return NVReadFaces::Color6; + case GL_COLOR_ATTACHMENT7: + return NVReadFaces::Color7; + + default: + break; + } + QT3DS_ASSERT(false); + return NVReadFaces::Unknown; + } + + static GLenum fromReadFacesToGL(NVReadFaces::Enum value) + { + switch (value) { + case NVReadFaces::Front: + return GL_FRONT; + case NVReadFaces::Back: + return GL_BACK; + case NVReadFaces::Color0: + return GL_COLOR_ATTACHMENT0; + case NVReadFaces::Color1: + return GL_COLOR_ATTACHMENT1; + case NVReadFaces::Color2: + return GL_COLOR_ATTACHMENT2; + case NVReadFaces::Color3: + return GL_COLOR_ATTACHMENT3; + case NVReadFaces::Color4: + return GL_COLOR_ATTACHMENT4; + case NVReadFaces::Color5: + return GL_COLOR_ATTACHMENT5; + case NVReadFaces::Color6: + return GL_COLOR_ATTACHMENT6; + case NVReadFaces::Color7: + return GL_COLOR_ATTACHMENT7; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderWinding::Enum fromGLToWinding(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ + case x: \ + return NVRenderWinding::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderWinding::Unknown; + } + + static GLenum fromWindingToGL(NVRenderWinding::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \ + case NVRenderWinding::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderBoolOp::Enum fromGLToBoolOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case x: \ + return NVRenderBoolOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderBoolOp::Unknown; + } + + static GLenum fromBoolOpToGL(NVRenderBoolOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case NVRenderBoolOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderHint::Enum fromGLToHint(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ + case x: \ + return NVRenderHint::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_HINT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderHint::Unknown; + } + + static GLenum fromHintToGL(NVRenderHint::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \ + case NVRenderHint::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_HINT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderStencilOp::Enum fromGLToStencilOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ + case x: \ + return NVRenderStencilOp::y; + QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP + default: + break; + } + + QT3DS_ASSERT(false); + return NVRenderStencilOp::Unknown; + } + + static GLenum fromStencilOpToGL(NVRenderStencilOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \ + case NVRenderStencilOp::y: \ + return x; + QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP +#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP + default: + break; + } + + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderComponentTypes::Enum fromGLToBufferComponentTypes(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ + case x: \ + return NVRenderComponentTypes::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderComponentTypes::Unknown; + } + + static GLenum fromBufferComponentTypesToGL(NVRenderComponentTypes::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \ + case NVRenderComponentTypes::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) \ + case NVRenderComponentTypes::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromIndexBufferComponentsTypesToGL(NVRenderComponentTypes::Enum value) + { + switch (value) { + case NVRenderComponentTypes::QT3DSU8: + return GL_UNSIGNED_BYTE; + case NVRenderComponentTypes::QT3DSU16: + return GL_UNSIGNED_SHORT; + case NVRenderComponentTypes::QT3DSU32: + return GL_UNSIGNED_INT; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromBindBufferFlagsToGL(NVRenderBufferBindFlags flags) + { + QT3DSU32 value = flags; + GLenum retval = GL_INVALID_ENUM; + if (value & NVRenderBufferBindValues::Vertex) + retval = GL_ARRAY_BUFFER; + else if (value & NVRenderBufferBindValues::Index) + retval = GL_ELEMENT_ARRAY_BUFFER; + else if (value & NVRenderBufferBindValues::Constant) + retval = GL_UNIFORM_BUFFER; + else if (value & NVRenderBufferBindValues::Storage) + retval = GL_SHADER_STORAGE_BUFFER; + else if (value & NVRenderBufferBindValues::Atomic_Counter) + retval = GL_ATOMIC_COUNTER_BUFFER; + else if (value & NVRenderBufferBindValues::Draw_Indirect) + retval = GL_DRAW_INDIRECT_BUFFER; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderBufferBindFlags fromGLToBindBufferFlags(GLenum value) + { + QT3DSU32 retval = 0; + + if (value == GL_ARRAY_BUFFER) + retval |= NVRenderBufferBindValues::Vertex; + else if (value == GL_ELEMENT_ARRAY_BUFFER) + retval |= NVRenderBufferBindValues::Index; + else if (value == GL_UNIFORM_BUFFER) + retval |= NVRenderBufferBindValues::Constant; + else if (value == GL_SHADER_STORAGE_BUFFER) + retval |= NVRenderBufferBindValues::Storage; + else if (value == GL_ATOMIC_COUNTER_BUFFER) + retval |= NVRenderBufferBindValues::Atomic_Counter; + else if (value == GL_DRAW_INDIRECT_BUFFER) + retval |= NVRenderBufferBindValues::Draw_Indirect; + else + QT3DS_ASSERT(false); + + return NVRenderBufferBindFlags(retval); + } + + static NVRenderBufferUsageType::Enum fromGLToBufferUsageType(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ + case x: \ + return NVRenderBufferUsageType::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderBufferUsageType::Unknown; + } + + static GLenum fromBufferUsageTypeToGL(NVRenderBufferUsageType::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \ + case NVRenderBufferUsageType::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromQueryTypeToGL(NVRenderQueryType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderQueryType::Samples) + retval = GL_ANY_SAMPLES_PASSED; +#if defined(GL_TIME_ELAPSED) + else if (type == NVRenderQueryType::Timer) + retval = GL_TIME_ELAPSED; +#elif defined(GL_TIME_ELAPSED_EXT) + else if (type == NVRenderQueryType::Timer) + retval = GL_TIME_ELAPSED_EXT; +#endif + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromQueryResultTypeToGL(NVRenderQueryResultType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderQueryResultType::ResultAvailable) + retval = GL_QUERY_RESULT_AVAILABLE; + else if (type == NVRenderQueryResultType::Result) + retval = GL_QUERY_RESULT; + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromSyncTypeToGL(NVRenderSyncType::Enum type) + { + GLenum retval = GL_INVALID_ENUM; + if (type == NVRenderSyncType::GpuCommandsComplete) + retval = GL_SYNC_GPU_COMMANDS_COMPLETE; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderTextureFormats::Enum + replaceDeprecatedTextureFormat(NVRenderContextType type, NVRenderTextureFormats::Enum value, + NVRenderTextureSwizzleMode::Enum &swizzleMode) + { + NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderTextureFormats::Enum newValue = value; + swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + + if (!(type & deprecatedContextFlags)) { + switch (value) { + case NVRenderTextureFormats::Luminance8: + newValue = NVRenderTextureFormats::R8; + swizzleMode = NVRenderTextureSwizzleMode::L8toR8; + break; + case NVRenderTextureFormats::LuminanceAlpha8: + newValue = NVRenderTextureFormats::RG8; + swizzleMode = NVRenderTextureSwizzleMode::L8A8toRG8; + break; + case NVRenderTextureFormats::Alpha8: + newValue = NVRenderTextureFormats::R8; + swizzleMode = NVRenderTextureSwizzleMode::A8toR8; + break; + case NVRenderTextureFormats::Luminance16: + newValue = NVRenderTextureFormats::R16; + swizzleMode = NVRenderTextureSwizzleMode::L16toR16; + break; + default: + break; + } + } + + return newValue; + } + + static void + NVRenderConvertSwizzleModeToGL(const NVRenderTextureSwizzleMode::Enum swizzleMode, + GLint glSwizzle[4]) + { + switch (swizzleMode) { + case NVRenderTextureSwizzleMode::L16toR16: + case NVRenderTextureSwizzleMode::L8toR8: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_RED; + glSwizzle[2] = GL_RED; + glSwizzle[3] = GL_ONE; + break; + case NVRenderTextureSwizzleMode::L8A8toRG8: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_RED; + glSwizzle[2] = GL_RED; + glSwizzle[3] = GL_GREEN; + break; + case NVRenderTextureSwizzleMode::A8toR8: + glSwizzle[0] = GL_ZERO; + glSwizzle[1] = GL_ZERO; + glSwizzle[2] = GL_ZERO; + glSwizzle[3] = GL_RED; + break; + case NVRenderTextureSwizzleMode::NoSwizzle: + default: + glSwizzle[0] = GL_RED; + glSwizzle[1] = GL_GREEN; + glSwizzle[2] = GL_BLUE; + glSwizzle[3] = GL_ALPHA; + break; + } + } + + static bool fromUncompressedTextureFormatToGL(NVRenderContextType type, + NVRenderTextureFormats::Enum value, + GLenum &outFormat, GLenum &outDataType, + GLenum &outInternalFormat) + { + switch (value) { + case NVRenderTextureFormats::R8: + if (type == NVRenderContextValues::GLES2) { + outFormat = GL_ALPHA; + outInternalFormat = GL_ALPHA; + } else { + outFormat = GL_RED; + outInternalFormat = GL_R8; + } + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RG8: + outFormat = GL_RG; + outInternalFormat = GL_RG8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGBA8: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGB8: + outFormat = GL_RGB; + outInternalFormat = GL_RGB8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::RGB565: + outFormat = GL_RGB; + outInternalFormat = GL_RGB8; + outDataType = GL_UNSIGNED_SHORT_5_6_5; + return true; + case NVRenderTextureFormats::RGBA5551: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA8; + outDataType = GL_UNSIGNED_SHORT_5_5_5_1; + return true; + case NVRenderTextureFormats::Alpha8: + outFormat = GL_ALPHA; + outInternalFormat = GL_ALPHA; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::Luminance8: + outFormat = GL_LUMINANCE; + outInternalFormat = GL_LUMINANCE; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::LuminanceAlpha8: + outFormat = GL_LUMINANCE_ALPHA; + outInternalFormat = GL_LUMINANCE_ALPHA; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::Luminance16: +#if defined(QT_OPENGL_ES) + outFormat = GL_LUMINANCE16F_EXT; + outInternalFormat = GL_LUMINANCE16F_EXT; +#else + outFormat = GL_LUMINANCE; + outInternalFormat = GL_LUMINANCE; +#endif + outDataType = GL_UNSIGNED_INT; + return true; + default: + break; + } + + NVRenderContextType contextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + // check extented texture formats + if (!(type & contextFlags)) { + switch (value) { +#if !defined(QT_OPENGL_ES) + case NVRenderTextureFormats::R16: { + if (IsGlEsContext(type)) { + outFormat = GL_RED_INTEGER; + outInternalFormat = GL_R16UI; + } else { + outFormat = GL_RED; + outInternalFormat = GL_R16; + } + outDataType = GL_UNSIGNED_SHORT; + return true; + } +#endif + case NVRenderTextureFormats::R16F: + outFormat = GL_RED; + outInternalFormat = GL_R16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::R32UI: + outFormat = GL_RED_INTEGER; + outInternalFormat = GL_R32UI; + outDataType = GL_UNSIGNED_INT; + return true; + case NVRenderTextureFormats::R32F: + outFormat = GL_RED; + outInternalFormat = GL_R32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGBA16F: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::RG16F: + outFormat = GL_RG; + outInternalFormat = GL_RG16F; + outDataType = GL_HALF_FLOAT; + return true; + case NVRenderTextureFormats::RG32F: + outFormat = GL_RG; + outInternalFormat = GL_RG32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGBA32F: + outFormat = GL_RGBA; + outInternalFormat = GL_RGBA32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::RGB32F: + outFormat = GL_RGB; + outInternalFormat = GL_RGB32F; + outDataType = GL_FLOAT; + return true; + case NVRenderTextureFormats::R11G11B10: + outFormat = GL_RGB; + outInternalFormat = GL_R11F_G11F_B10F; + outDataType = GL_UNSIGNED_INT_10F_11F_11F_REV; + return true; + case NVRenderTextureFormats::RGB9E5: + outFormat = GL_RGB; + outInternalFormat = GL_RGB9_E5; + outDataType = GL_UNSIGNED_INT_5_9_9_9_REV; + return true; + case NVRenderTextureFormats::SRGB8: + outFormat = GL_RGB; + outInternalFormat = GL_SRGB8; + outDataType = GL_UNSIGNED_BYTE; + return true; + case NVRenderTextureFormats::SRGB8A8: + outFormat = GL_RGBA; + outInternalFormat = GL_SRGB8_ALPHA8; + outDataType = GL_UNSIGNED_BYTE; + return true; + default: + break; + } + } + + QT3DS_ASSERT(false); + return false; + } + + static GLenum fromCompressedTextureFormatToGL(NVRenderTextureFormats::Enum value) + { + switch (value) { + case NVRenderTextureFormats::RGBA_DXT1: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case NVRenderTextureFormats::RGB_DXT1: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case NVRenderTextureFormats::RGBA_DXT3: + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case NVRenderTextureFormats::RGBA_DXT5: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case NVRenderTextureFormats::R_ATI1N_UNorm: + return GL_COMPRESSED_RED_RGTC1; + case NVRenderTextureFormats::R_ATI1N_SNorm: + return GL_COMPRESSED_SIGNED_RED_RGTC1; + case NVRenderTextureFormats::RG_ATI2N_UNorm: + return GL_COMPRESSED_RG_RGTC2; + case NVRenderTextureFormats::RG_ATI2N_SNorm: + return GL_COMPRESSED_SIGNED_RG_RGTC2; + case NVRenderTextureFormats::RGB_BP_UNSIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_SIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_UNorm: + return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + case NVRenderTextureFormats::R11_EAC_UNorm: + return GL_COMPRESSED_R11_EAC; + case NVRenderTextureFormats::R11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_R11_EAC; + case NVRenderTextureFormats::RG11_EAC_UNorm: + return GL_COMPRESSED_RG11_EAC; + case NVRenderTextureFormats::RG11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_RG11_EAC; + case NVRenderTextureFormats::RGB8_ETC2: + return GL_COMPRESSED_RGB8_ETC2; + case NVRenderTextureFormats::SRGB8_ETC2: + return GL_COMPRESSED_SRGB8_ETC2; + case NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::RGBA8_ETC2_EAC: + return GL_COMPRESSED_RGBA8_ETC2_EAC; + case NVRenderTextureFormats::SRGB8_Alpha8_ETC2_EAC: + return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + case NVRenderTextureFormats::RGB8_ETC1: + return GL_ETC1_RGB8_OES; +#ifdef GL_KHR_texture_compression_astc_hdr + case NVRenderTextureFormats::RGBA_ASTC_4x4: + return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x4: + return GL_COMPRESSED_RGBA_ASTC_5x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x5: + return GL_COMPRESSED_RGBA_ASTC_5x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x5: + return GL_COMPRESSED_RGBA_ASTC_6x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x6: + return GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x5: + return GL_COMPRESSED_RGBA_ASTC_8x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x6: + return GL_COMPRESSED_RGBA_ASTC_8x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x8: + return GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x5: + return GL_COMPRESSED_RGBA_ASTC_10x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x6: + return GL_COMPRESSED_RGBA_ASTC_10x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x8: + return GL_COMPRESSED_RGBA_ASTC_10x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x10: + return GL_COMPRESSED_RGBA_ASTC_10x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x10: + return GL_COMPRESSED_RGBA_ASTC_12x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x12: + return GL_COMPRESSED_RGBA_ASTC_12x12_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_4x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x12: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; +#endif // GL_KHR_texture_compression_astc_hdr + default: + break; + } + + QT3DS_ASSERT(false); + return 0; + } + + static bool fromDepthTextureFormatToGL(NVRenderContextType type, + NVRenderTextureFormats::Enum value, + GLenum &outFormat, GLenum &outDataType, + GLenum &outInternalFormat) + { + NVRenderContextType theContextFlags(NVRenderContextValues::GLES2 + | NVRenderContextValues::GL2); + + bool supportDepth24 = !(type & theContextFlags); + bool supportDepth32f = !(type & theContextFlags); + bool supportDepth24Stencil8 = !(type & theContextFlags); + + switch (value) { + case NVRenderTextureFormats::Depth16: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = GL_DEPTH_COMPONENT16; + outDataType = GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth24: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = (supportDepth24) ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth24) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth32: + outFormat = GL_DEPTH_COMPONENT; + outInternalFormat = + (supportDepth32f) ? GL_DEPTH_COMPONENT32F : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth32f) ? GL_FLOAT : GL_UNSIGNED_SHORT; + return true; + case NVRenderTextureFormats::Depth24Stencil8: + outFormat = (supportDepth24Stencil8) ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT; + outInternalFormat = + (supportDepth24Stencil8) ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16; + outDataType = (supportDepth24Stencil8) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_SHORT; + return true; + default: + break; + } + + QT3DS_ASSERT(false); + return false; + } + + static GLenum fromTextureTargetToGL(NVRenderTextureTargetType::Enum value) + { + GLenum retval = 0; + if (value == NVRenderTextureTargetType::Texture2D) + retval = GL_TEXTURE_2D; + else if (value == NVRenderTextureTargetType::Texture2D_MS) + retval = GL_TEXTURE_2D_MULTISAMPLE; + else if (value == NVRenderTextureTargetType::Texture2D_Array) + retval = GL_TEXTURE_2D_ARRAY; + else if (value == NVRenderTextureTargetType::TextureCube) + retval = GL_TEXTURE_CUBE_MAP; + else if (value == NVRenderTextureTargetType::TextureCubeNegX) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; + else if (value == NVRenderTextureTargetType::TextureCubePosX) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + else if (value == NVRenderTextureTargetType::TextureCubeNegY) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; + else if (value == NVRenderTextureTargetType::TextureCubePosY) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; + else if (value == NVRenderTextureTargetType::TextureCubeNegZ) + retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + else if (value == NVRenderTextureTargetType::TextureCubePosZ) + retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; + else + QT3DS_ASSERT(false); + + return retval; + } + + static NVRenderTextureTargetType::Enum fromGLToTextureTarget(GLenum value) + { + NVRenderTextureTargetType::Enum retval = NVRenderTextureTargetType::Unknown; + + if (value == GL_TEXTURE_2D) + retval = NVRenderTextureTargetType::Texture2D; + else if (value == GL_TEXTURE_2D_MULTISAMPLE) + retval = NVRenderTextureTargetType::Texture2D_MS; + else + QT3DS_ASSERT(false); + + return retval; + } + + static GLenum fromTextureUnitToGL(NVRenderTextureUnit::Enum value) + { + QT3DSU32 v = value; + GLenum retval = GL_TEXTURE0; + retval = GL_TEXTURE0 + v; + + return retval; + } + + static GLenum fromGLToTextureUnit(GLenum value) + { + QT3DS_ASSERT(value > GL_TEXTURE0); + + QT3DSU32 v = value - GL_TEXTURE0; + NVRenderTextureUnit::Enum retval = + NVRenderTextureUnit::Enum(NVRenderTextureUnit::TextureUnit_0 + v); + + return retval; + } + + static GLenum fromTextureMinifyingOpToGL(NVRenderTextureMinifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case NVRenderTextureMinifyingOp::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ + case NVRenderTextureMinifyingOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureMinifyingOp::Enum fromGLToTextureMinifyingOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case x: \ + return NVRenderTextureMinifyingOp::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \ + case x: \ + return NVRenderTextureMinifyingOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureMinifyingOp::Unknown; + } + + static GLenum fromTextureMagnifyingOpToGL(NVRenderTextureMagnifyingOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case NVRenderTextureMagnifyingOp::y: \ + return x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureMagnifyingOp::Enum fromGLToTextureMagnifyingOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \ + case x: \ + return NVRenderTextureMagnifyingOp::y; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureMagnifyingOp::Unknown; + } + + static GLenum fromTextureCoordOpToGL(NVRenderTextureCoordOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ + case NVRenderTextureCoordOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderTextureCoordOp::Enum fromGLToTextureCoordOp(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \ + case x: \ + return NVRenderTextureCoordOp::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderTextureCoordOp::Unknown; + } + + static GLenum fromTextureCompareModeToGL(NVRenderTextureCompareMode::Enum value) + { + switch (value) { + case NVRenderTextureCompareMode::NoCompare: + return GL_NONE; + case NVRenderTextureCompareMode::CompareToRef: + return GL_COMPARE_REF_TO_TEXTURE; + default: + break; + } + + QT3DS_ASSERT(false); + return NVRenderTextureCompareMode::Unknown; + } + + static GLenum fromGLToTextureCompareMode(GLenum value) + { + switch (value) { + case GL_NONE: + return NVRenderTextureCompareMode::NoCompare; + case GL_COMPARE_REF_TO_TEXTURE: + return NVRenderTextureCompareMode::CompareToRef; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static GLenum fromTextureCompareFuncToGL(NVRenderTextureCompareOp::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \ + case NVRenderTextureCompareOp::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static GLenum fromImageFormatToGL(NVRenderTextureFormats::Enum value) + { + switch (value) { + case NVRenderTextureFormats::R8: + return GL_R8; + case NVRenderTextureFormats::R32I: + return GL_R32I; + case NVRenderTextureFormats::R32UI: + return GL_R32UI; + case NVRenderTextureFormats::R32F: + return GL_R32F; + case NVRenderTextureFormats::RGBA8: + return GL_RGBA8; + case NVRenderTextureFormats::SRGB8A8: + return GL_RGBA8_SNORM; + case NVRenderTextureFormats::RG16F: + return GL_RG16F; + case NVRenderTextureFormats::RGBA16F: + return GL_RGBA16F; + case NVRenderTextureFormats::RGBA32F: + return GL_RGBA32F; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + + static GLenum fromImageAccessToGL(NVRenderImageAccessType::Enum value) + { + switch (value) { + case NVRenderImageAccessType::Read: + return GL_READ_ONLY; + case NVRenderImageAccessType::Write: + return GL_WRITE_ONLY; + case NVRenderImageAccessType::ReadWrite: + return GL_READ_WRITE; + default: + break; + } + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static GLbitfield fromBufferAccessBitToGL(NVRenderBufferAccessFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; + + if (value & NVRenderBufferAccessTypeValues::Read) + retval |= GL_MAP_READ_BIT; + if (value & NVRenderBufferAccessTypeValues::Write) + retval |= GL_MAP_WRITE_BIT; + if (value & NVRenderBufferAccessTypeValues::Invalid) + retval |= GL_MAP_INVALIDATE_BUFFER_BIT; + if (value & NVRenderBufferAccessTypeValues::InvalidRange) + retval |= GL_MAP_INVALIDATE_RANGE_BIT; + + QT3DS_ASSERT(retval); + return retval; + } + + static GLbitfield fromMemoryBarrierFlagsToGL(NVRenderBufferBarrierFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderBufferBarrierValues::AtomicCounter) + retval |= GL_ATOMIC_COUNTER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::BufferUpdate) + retval |= GL_BUFFER_UPDATE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::CommandBuffer) + retval |= GL_COMMAND_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ElementArray) + retval |= GL_ELEMENT_ARRAY_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::Framebuffer) + retval |= GL_FRAMEBUFFER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::PixelBuffer) + retval |= GL_PIXEL_BUFFER_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ShaderImageAccess) + retval |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::ShaderStorage) + retval |= GL_SHADER_STORAGE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TextureFetch) + retval |= GL_TEXTURE_FETCH_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TextureUpdate) + retval |= GL_TEXTURE_UPDATE_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::TransformFeedback) + retval |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::UniformBuffer) + retval |= GL_UNIFORM_BARRIER_BIT; + if (value & NVRenderBufferBarrierValues::VertexAttribArray) + retval |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; +#endif + QT3DS_ASSERT(retval); + return retval; + } + + static GLbitfield fromShaderTypeFlagsToGL(NVRenderShaderTypeFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; + if (value & NVRenderShaderTypeValue::Vertex) + retval |= GL_VERTEX_SHADER_BIT; + if (value & NVRenderShaderTypeValue::Fragment) + retval |= GL_FRAGMENT_SHADER_BIT; + if (value & NVRenderShaderTypeValue::TessControl) + retval |= GL_TESS_CONTROL_SHADER_BIT; + if (value & NVRenderShaderTypeValue::TessEvaluation) + retval |= GL_TESS_EVALUATION_SHADER_BIT; + if (value & NVRenderShaderTypeValue::Geometry) +#if defined(QT_OPENGL_ES_3_1) + retval |= GL_GEOMETRY_SHADER_BIT_EXT; +#else + retval |= GL_GEOMETRY_SHADER_BIT; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + + static GLenum fromPropertyDataTypesToShaderGL(NVRenderShaderDataTypes::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ + case NVRenderShaderDataTypes::nv: \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderShaderDataTypes::Enum fromShaderGLToPropertyDataTypes(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \ + case gl: \ + return NVRenderShaderDataTypes::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES + case GL_SAMPLER_2D_SHADOW: + return NVRenderShaderDataTypes::NVRenderTexture2DPtr; +#if !defined(QT_OPENGL_ES) + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return NVRenderShaderDataTypes::QT3DSU32; + case GL_UNSIGNED_INT_IMAGE_2D: + return NVRenderShaderDataTypes::NVRenderImage2DPtr; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderShaderDataTypes::Unknown; + } + + static GLenum fromComponentTypeAndNumCompsToAttribGL(NVRenderComponentTypes::Enum compType, + QT3DSU32 numComps) + { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ + if (compType == NVRenderComponentTypes::ct && numComps == nc) \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES + QT3DS_ASSERT(false); + return 0; + } + + static void fromAttribGLToComponentTypeAndNumComps( + GLenum enumVal, NVRenderComponentTypes::Enum &outCompType, QT3DSU32 &outNumComps) + { + switch (enumVal) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \ + case gl: \ + outCompType = NVRenderComponentTypes::ct; \ + outNumComps = nc; \ + return; + QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES + default: + break; + } + QT3DS_ASSERT(false); + outCompType = NVRenderComponentTypes::Unknown; + outNumComps = 0; + } + + static GLenum + fromRenderBufferFormatsToRenderBufferGL(NVRenderRenderBufferFormats::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ + case NVRenderRenderBufferFormats::nv: \ + return gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderRenderBufferFormats::Enum + fromRenderBufferGLToRenderBufferFormats(GLenum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \ + case gl: \ + return NVRenderRenderBufferFormats::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS + QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderRenderBufferFormats::Unknown; + } + + static GLenum fromFramebufferAttachmentsToGL(NVRenderFrameBufferAttachments::Enum value) + { + switch (value) { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ + case NVRenderFrameBufferAttachments::x: \ + return GL_COLOR_ATTACHMENT0 + idx; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ + case NVRenderFrameBufferAttachments::y: \ + return x; + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderFrameBufferAttachments::Unknown; + } + + static NVRenderFrameBufferAttachments::Enum fromGLToFramebufferAttachments(GLenum value) + { +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \ + if (value == GL_COLOR_ATTACHMENT0 + idx) \ + return NVRenderFrameBufferAttachments::x; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \ + if (value == x) \ + return NVRenderFrameBufferAttachments::y; + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS + QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT + QT3DS_ASSERT(false); + return NVRenderFrameBufferAttachments::Unknown; + } + + static GLbitfield fromClearFlagsToGL(NVRenderClearFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ + if ((value & NVRenderClearValues::nv)) \ + retval |= gl; + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS + return retval; + } + + static NVRenderClearFlags fromGLToClearFlags(GLbitfield value) + { + QT3DSU32 retval = 0; +#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \ + if ((value & gl)) \ + retval |= NVRenderClearValues::nv; + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS + QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS +#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS + return NVRenderClearFlags(retval); + } + + static GLenum fromDrawModeToGL(NVRenderDrawMode::Enum value, bool inTesselationSupported) + { + switch (value) { + case NVRenderDrawMode::Points: + return GL_POINTS; + case NVRenderDrawMode::Lines: + return GL_LINES; + case NVRenderDrawMode::LineStrip: + return GL_LINE_STRIP; + case NVRenderDrawMode::LineLoop: + return GL_LINE_LOOP; + case NVRenderDrawMode::TriangleStrip: + return GL_TRIANGLE_STRIP; + case NVRenderDrawMode::TriangleFan: + return GL_TRIANGLE_FAN; + case NVRenderDrawMode::Triangles: + return GL_TRIANGLES; + case NVRenderDrawMode::Patches: + return (inTesselationSupported) ? GL_PATCHES : GL_TRIANGLES; + default: + break; + } + + QT3DS_ASSERT(false); + return GL_INVALID_ENUM; + } + + static NVRenderDrawMode::Enum fromGLToDrawMode(GLenum value) + { + switch (value) { + case GL_POINTS: + return NVRenderDrawMode::Points; + case GL_LINES: + return NVRenderDrawMode::Lines; + case GL_LINE_STRIP: + return NVRenderDrawMode::LineStrip; + case GL_LINE_LOOP: + return NVRenderDrawMode::LineLoop; + case GL_TRIANGLE_STRIP: + return NVRenderDrawMode::TriangleStrip; + case GL_TRIANGLE_FAN: + return NVRenderDrawMode::TriangleFan; + case GL_TRIANGLES: + return NVRenderDrawMode::Triangles; + case GL_PATCHES: + return NVRenderDrawMode::Patches; + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderDrawMode::Unknown; + } + + static GLenum fromRenderStateToGL(NVRenderState::Enum value) + { + switch (value) { + case NVRenderState::Blend: + return GL_BLEND; + case NVRenderState::CullFace: + return GL_CULL_FACE; + case NVRenderState::DepthTest: + return GL_DEPTH_TEST; + case NVRenderState::Multisample: +#if defined(QT_OPENGL_ES) + return GL_MULTISAMPLE_EXT; +#else + return GL_MULTISAMPLE; +#endif + case NVRenderState::StencilTest: + return GL_STENCIL_TEST; + case NVRenderState::ScissorTest: + return GL_SCISSOR_TEST; + default: + break; + } + QT3DS_ASSERT(false); + return 0; + } + + static NVRenderState::Enum fromGLToRenderState(GLenum value) + { + switch (value) { + case GL_BLEND: + return NVRenderState::Blend; + case GL_CULL_FACE: + return NVRenderState::CullFace; + case GL_DEPTH_TEST: + return NVRenderState::DepthTest; +#if defined(QT_OPENGL_ES) + case GL_MULTISAMPLE_EXT: +#else + case GL_MULTISAMPLE: +#endif + return NVRenderState::Multisample; + case GL_STENCIL_TEST: + return NVRenderState::StencilTest; + case GL_SCISSOR_TEST: + return NVRenderState::ScissorTest; + default: + break; + } + QT3DS_ASSERT(false); + return NVRenderState::Unknown; + } + + static bool fromReadPixelsToGlFormatAndType(NVRenderReadPixelFormats::Enum inReadPixels, + GLuint *outFormat, GLuint *outType) + { + switch (inReadPixels) { + case NVRenderReadPixelFormats::Alpha8: + *outFormat = GL_ALPHA; + *outType = GL_UNSIGNED_BYTE; + break; + case NVRenderReadPixelFormats::RGB565: + *outFormat = GL_RGB; + *outType = GL_UNSIGNED_SHORT_5_6_5; + case NVRenderReadPixelFormats::RGB8: + *outFormat = GL_RGB; + *outType = GL_UNSIGNED_BYTE; + break; + case NVRenderReadPixelFormats::RGBA4444: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case NVRenderReadPixelFormats::RGBA5551: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case NVRenderReadPixelFormats::RGBA8: + *outFormat = GL_RGBA; + *outType = GL_UNSIGNED_BYTE; + break; + default: + *outFormat = 0; + *outType = 0; + QT3DS_ASSERT(false); + return false; + }; + + return true; + } + + static GLenum fromPathFillModeToGL(NVRenderPathFillMode::Enum inMode) + { + GLenum glFillMode; + + switch (inMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathFillMode::Fill: + glFillMode = GL_PATH_FILL_MODE_NV; + break; + case NVRenderPathFillMode::CountUp: + glFillMode = GL_COUNT_UP_NV; + break; + case NVRenderPathFillMode::CountDown: + glFillMode = GL_COUNT_DOWN_NV; + break; + case NVRenderPathFillMode::Invert: + glFillMode = GL_INVERT; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glFillMode; + } + + static GLenum fromPathFontTargetToGL(NVRenderPathFontTarget::Enum inFontTarget) + { + GLenum glFontTarget; + + switch (inFontTarget) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathFontTarget::StandardFont: + glFontTarget = GL_STANDARD_FONT_NAME_NV; + break; + case NVRenderPathFontTarget::SystemFont: + glFontTarget = GL_SYSTEM_FONT_NAME_NV; + break; + case NVRenderPathFontTarget::FileFont: + glFontTarget = GL_FILE_NAME_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glFontTarget; + } + + static NVRenderPathReturnValues::Enum fromGLToPathFontReturn(GLenum inReturnValue) + { + NVRenderPathReturnValues::Enum returnValue; + + switch (inReturnValue) { +#if !defined(QT_OPENGL_ES) + case GL_FONT_GLYPHS_AVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontGlypsAvailable; + break; + case GL_FONT_TARGET_UNAVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontTargetUnavailable; + break; + case GL_FONT_UNAVAILABLE_NV: + returnValue = NVRenderPathReturnValues::FontUnavailable; + break; + case GL_FONT_UNINTELLIGIBLE_NV: + returnValue = NVRenderPathReturnValues::FontUnintelligible; + break; +#endif + case GL_INVALID_ENUM: + case GL_INVALID_VALUE: + returnValue = NVRenderPathReturnValues::InvalidEnum; + break; + case GL_OUT_OF_MEMORY: + returnValue = NVRenderPathReturnValues::OutOfMemory; + break; + default: + QT3DS_ASSERT(false); + returnValue = NVRenderPathReturnValues::FontTargetUnavailable; + break; + } + + return returnValue; + } + + static GLenum fromPathMissingGlyphsToGL(NVRenderPathMissingGlyphs::Enum inHandleGlyphs) + { + GLenum glMissingGlyphs; + + switch (inHandleGlyphs) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathMissingGlyphs::SkipMissing: + glMissingGlyphs = GL_SKIP_MISSING_GLYPH_NV; + break; + case NVRenderPathMissingGlyphs::UseMissing: + glMissingGlyphs = GL_USE_MISSING_GLYPH_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glMissingGlyphs; + } + + static GLenum fromPathListModeToGL(NVRenderPathListMode::Enum inListMode) + { + GLenum glListMode; + + switch (inListMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathListMode::AccumAdjacentPairs: + glListMode = GL_ACCUM_ADJACENT_PAIRS_NV; + break; + case NVRenderPathListMode::AdjacentPairs: + glListMode = GL_ADJACENT_PAIRS_NV; + break; + case NVRenderPathListMode::FirstToRest: + glListMode = GL_FIRST_TO_REST_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glListMode; + } + + static GLenum fromPathCoverModeToGL(NVRenderPathCoverMode::Enum inMode) + { + GLenum glCoverMode; + + switch (inMode) { +#if !defined(QT_OPENGL_ES) + case NVRenderPathCoverMode::ConvexHull: + glCoverMode = GL_CONVEX_HULL_NV; + break; + case NVRenderPathCoverMode::BoundingBox: + glCoverMode = GL_BOUNDING_BOX_NV; + break; + case NVRenderPathCoverMode::BoundingBoxOfBoundingBox: + glCoverMode = GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV; + break; + case NVRenderPathCoverMode::PathFillCover: + glCoverMode = GL_PATH_FILL_COVER_MODE_NV; + break; + case NVRenderPathCoverMode::PathStrokeCover: + glCoverMode = GL_PATH_STROKE_COVER_MODE_NV; + break; +#endif + default: + QT3DS_ASSERT(false); + break; + } + + return glCoverMode; + } + + static GLenum fromPathTypeToGL(NVRenderPathFormatType::Enum value) + { + switch (value) { + case NVRenderPathFormatType::Byte: + return GL_BYTE; + case NVRenderPathFormatType::UByte: + return GL_UNSIGNED_BYTE; + case NVRenderPathFormatType::Short: + return GL_SHORT; + case NVRenderPathFormatType::UShort: + return GL_UNSIGNED_SHORT; + case NVRenderPathFormatType::Int: + return GL_INT; + case NVRenderPathFormatType::Uint: + return GL_UNSIGNED_INT; +#if !defined(QT_OPENGL_ES) + case NVRenderPathFormatType::Bytes2: + return GL_2_BYTES_NV; + case NVRenderPathFormatType::Bytes3: + return GL_3_BYTES_NV; + case NVRenderPathFormatType::Bytes4: + return GL_4_BYTES_NV; + case NVRenderPathFormatType::Utf8: + return GL_UTF8_NV; + case NVRenderPathFormatType::Utf16: + return GL_UTF16_NV; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return GL_UNSIGNED_BYTE; + } + + static GLbitfield fromPathFontStyleToGL(NVRenderPathFontStyleFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderPathFontStyleValues::Bold) + retval |= GL_BOLD_BIT_NV; + if (value & NVRenderPathFontStyleValues::Italic) + retval |= GL_ITALIC_BIT_NV; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + + static GLenum fromPathTransformToGL(NVRenderPathTransformType::Enum value) + { + switch (value) { + case NVRenderPathTransformType::NoTransform: + return GL_NONE; +#if !defined(QT_OPENGL_ES) + case NVRenderPathTransformType::TranslateX: + return GL_TRANSLATE_X_NV; + case NVRenderPathTransformType::TranslateY: + return GL_TRANSLATE_Y_NV; + case NVRenderPathTransformType::Translate2D: + return GL_TRANSLATE_2D_NV; + case NVRenderPathTransformType::Translate3D: + return GL_TRANSLATE_3D_NV; + case NVRenderPathTransformType::Affine2D: + return GL_AFFINE_2D_NV; + case NVRenderPathTransformType::Affine3D: + return GL_AFFINE_3D_NV; + case NVRenderPathTransformType::TransposeAffine2D: + return GL_TRANSPOSE_AFFINE_2D_NV; + case NVRenderPathTransformType::TransposeAffine3D: + return GL_TRANSPOSE_AFFINE_3D_NV; +#endif + default: + break; + } + QT3DS_ASSERT(false); + return GL_UNSIGNED_BYTE; + } + + static GLbitfield fromPathMetricQueryFlagsToGL(NVRenderPathGlyphFontMetricFlags flags) + { + QT3DSU32 value = flags; + GLbitfield retval = 0; +#if !defined(QT_OPENGL_ES) + if (value & NVRenderPathGlyphFontMetricValues::GlyphWidth) + retval |= GL_GLYPH_WIDTH_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHeight) + retval |= GL_GLYPH_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingX) + retval |= GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingY) + retval |= GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingAdvance) + retval |= GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingX) + retval |= GL_GLYPH_VERTICAL_BEARING_X_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingY) + retval |= GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingAdvance) + retval |= GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::GlyphHasKerning) + retval |= GL_GLYPH_HAS_KERNING_BIT_NV; + + if (value & NVRenderPathGlyphFontMetricValues::FontXMinBounds) + retval |= GL_FONT_X_MIN_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontYMinBounds) + retval |= GL_FONT_Y_MIN_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontXMaxBounds) + retval |= GL_FONT_X_MAX_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontYMaxBounds) + retval |= GL_FONT_Y_MAX_BOUNDS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontUnitsPerEm) + retval |= GL_FONT_UNITS_PER_EM_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontAscender) + retval |= GL_FONT_ASCENDER_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontDescender) + retval |= GL_FONT_DESCENDER_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontHeight) + retval |= GL_FONT_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) + retval |= GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceHeight) + retval |= GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontUnderlinePosition) + retval |= GL_FONT_UNDERLINE_POSITION_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth) + retval |= GL_FONT_UNDERLINE_THICKNESS_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontHasKerning) + retval |= GL_FONT_HAS_KERNING_BIT_NV; + if (value & NVRenderPathGlyphFontMetricValues::FontNumGlyphIndices) + retval |= GL_FONT_NUM_GLYPH_INDICES_BIT_NV; +#endif + QT3DS_ASSERT(retval || !value); + return retval; + } + }; +} +} + +#endif // QT3DSOPENGLUTIL_H diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp new file mode 100644 index 00000000..d78c51d9 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp @@ -0,0 +1,784 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +#if defined(QT_OPENGL_ES) +#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_TIMER_EXT(x) m_timerExtension->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_TESSELATION_EXT(x) m_tessellationShader->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_MULTISAMPLE_EXT(x) m_multiSample->x; RENDER_LOG_ERROR_PARAMS(x); +#endif + +namespace qt3ds { +namespace render { + +#ifndef GL_PATCH_VERTICES +#define GL_PATCH_VERTICES 0x8E72 +#endif + + /// constructor + NVRenderBackendGL3Impl::NVRenderBackendGL3Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGLBase(fnd, stringTable, format) + { + eastl::string exts3tc("GL_EXT_texture_compression_s3tc"); + eastl::string extsdxt("GL_EXT_texture_compression_dxt1"); + eastl::string extsAniso("GL_EXT_texture_filter_anisotropic"); + eastl::string extsTexSwizzle("GL_ARB_texture_swizzle"); + eastl::string extsAstcHDR("GL_KHR_texture_compression_astc_hdr"); + eastl::string extsAstcLDR("GL_KHR_texture_compression_astc_ldr"); + eastl::string extsFPRenderTarget("GL_EXT_color_buffer_float"); + eastl::string extsTimerQuery("GL_EXT_timer_query"); + eastl::string extsGpuShader5("EXT_gpu_shader5"); + + const char *languageVersion = GetShadingLanguageVersion(); + qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + eastl::string apiVendor(getVendorString()); + qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str()); + + eastl::string apiRenderer(getRendererString()); + qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str()); + + // clear support bits + m_backendSupport.caps.u32Values = 0; + + // get extension count + GLint numExtensions = 0; + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); + + eastl::string extensionBuffer; + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); + + m_extensions.push_back(QString::fromLocal8Bit(extensionString)); + + if (extensionBuffer.size()) + extensionBuffer.append(" "); + extensionBuffer.append(extensionString); + + // search for extension + if (!m_backendSupport.caps.bits.bDXTImagesSupported + && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) { + m_backendSupport.caps.bits.bDXTImagesSupported = true; + } else if (!m_backendSupport.caps.bits.bAnistropySupported + && extsAniso.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAnistropySupported = true; + } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported + && extsFPRenderTarget.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + } else if (!m_backendSupport.caps.bits.bTimerQuerySupported + && extsTimerQuery.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported + && extsGpuShader5.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true; + } + + } + + qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensionBuffer.c_str()); + + // texture swizzle is always true + m_backendSupport.caps.bits.bTextureSwizzleSupported = true; + // depthstencil renderbuffer support is always true + m_backendSupport.caps.bits.bDepthStencilSupported = true; + // constant buffers support is always true + m_backendSupport.caps.bits.bConstantBufferSupported = true; + m_backendSupport.caps.bits.bStandardDerivativesSupported = true; + m_backendSupport.caps.bits.bVertexArrayObjectSupported = true; + m_backendSupport.caps.bits.bTextureLodSupported = true; + + if (!isESCompatible()) { + // render to float textures is always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bFPRenderTargetsSupported = true; + // multisampled texture is always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bMsTextureSupported = true; + // timer queries are always supported on none ES systems which support >=GL3 + m_backendSupport.caps.bits.bTimerQuerySupported = true; + } + + // query hardware + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount)); + + // internal state tracker + m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)(); + + // finally setup caps based on device + setAndInspectHardwareCaps(); + + // Initialize extensions +#if defined(QT_OPENGL_ES_2) + m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#else + m_timerExtension = new QOpenGLExtension_ARB_timer_query; + m_timerExtension->initializeOpenGLFunctions(); + m_tessellationShader = new QOpenGLExtension_ARB_tessellation_shader; + m_tessellationShader->initializeOpenGLFunctions(); + m_multiSample = new QOpenGLExtension_ARB_texture_multisample; + m_multiSample->initializeOpenGLFunctions(); + m_qt3dsExtensions = new Qt3DSOpenGLExtensions; + m_qt3dsExtensions->initializeOpenGLFunctions(); +#endif + } + /// destructor + NVRenderBackendGL3Impl::~NVRenderBackendGL3Impl() + { + if (m_pCurrentMiscState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState); +#if !defined(QT_OPENGL_ES_2) + if (m_timerExtension) + delete m_timerExtension; + if (m_tessellationShader) + delete m_tessellationShader; + if (m_multiSample) + delete m_multiSample; +#endif + if (m_qt3dsExtensions) + delete m_qt3dsExtensions; + } + + void NVRenderBackendGL3Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) + { +// Not supported by ES 3 yet +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(samples); + NVRENDER_BACKEND_UNUSED(internalFormat); + NVRENDER_BACKEND_UNUSED(width); + NVRENDER_BACKEND_UNUSED(height); + NVRENDER_BACKEND_UNUSED(fixedsamplelocations); +#else + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + GL_CALL_MULTISAMPLE_EXT(glTexImage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, + (GLsizei)width, (GLsizei)height, fixedsamplelocations)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); +#endif + } + + void NVRenderBackendGL3Impl::SetTextureData3D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth, + QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + (GLsizei)depth, border, glformat, gltype, hostPtr)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGL3Impl::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) + { + + // Satisfy the compiler + // These are not available in GLES 3 and we don't use them right now + QT3DS_ASSERT(lodBias == 0.0); + QT3DS_ASSERT(!borderColor); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(borderColor); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_R, + m_Conversion.fromTextureCoordOpToGL(wrapR))); + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MIN_LOD, minLod)); + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_LOD, maxLod)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_MODE, + m_Conversion.fromTextureCompareModeToGL(compareMode))); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_FUNC, + m_Conversion.fromTextureCompareFuncToGL(compareFunc))); + + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy)); + } + } + + void NVRenderBackendGL3Impl::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) + { + NVRENDER_BACKEND_UNUSED(to); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel)); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel)); + } + + void NVRenderBackendGL3Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) + { + NVRENDER_BACKEND_UNUSED(to); + if (m_backendSupport.caps.bits.bTextureSwizzleSupported) { + GLint glSwizzle[4]; + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle); +#if defined(QT_OPENGL_ES) + // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2])); + GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3])); +#else + GL_CALL_EXTRA_FUNCTION(glTexParameteriv(glTarget, GL_TEXTURE_SWIZZLE_RGBA, glSwizzle)); +#endif + } + } + + QT3DSU32 + NVRenderBackendGL3Impl::GetDepthBits() const + { + QT3DSI32 depthBits; + GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv( + GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits)); + + return depthBits; + } + + QT3DSU32 + NVRenderBackendGL3Impl::GetStencilBits() const + { + QT3DSI32 stencilBits; + GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilBits)); + + return stencilBits; + } + + void NVRenderBackendGL3Impl::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum /*genType*/) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + bool NVRenderBackendGL3Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) + { + if (iao == NULL) { + // unbind and return; + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(0)); + return true; + } + + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout; + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + NVDataRef<NVRenderBackendShaderInputEntryGL> shaderAttribBuffer; + if (pProgram->m_shaderInput) + shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries; + + if (attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size()) + return false; + + if (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot) { + QT3DS_ASSERT(false); + return false; + } + + if (inputAssembler->m_VaoID == 0) { + // generate vao + GL_CALL_EXTRA_FUNCTION(glGenVertexArrays(1, &inputAssembler->m_VaoID)); + QT3DS_ASSERT(inputAssembler->m_VaoID); + } + + // set patch parameter count if changed + if (m_backendSupport.caps.bits.bTessellationSupported + && m_pCurrentMiscState->m_PatchVertexCount != inputAssembler->m_PatchVertexCount) { + m_pCurrentMiscState->m_PatchVertexCount = inputAssembler->m_PatchVertexCount; +#if defined(QT_OPENGL_ES) + GL_CALL_TESSELATION_EXT(glPatchParameteriEXT(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); +#else + GL_CALL_TESSELATION_EXT(glPatchParameteri(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount)); +#endif + } + + if (inputAssembler->m_cachedShaderHandle != programID) { + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); + inputAssembler->m_cachedShaderHandle = programID; + + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents) { + qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + return false; + } else { + entryData.m_AttribIndex = attrib.m_AttribLocation; + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + + // disable max possible used first + // this is currently sufficient since we always re-arrange input attributes from 0 + for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i)); + } + + // setup all attribs + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName); + if (entry) { + const NVRenderBackendLayoutEntryGL &entryData(*entry); + GLuint id = HandleToID_cast( + GLuint, size_t, + inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]); + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id)); + GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex)); + GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot]; + GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot]; + GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer( + entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE, + stride, (const void *)(entryData.m_Offset + offset))); + + } else { + GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx)); + } + } + + // setup index buffer. + if (inputAssembler->m_IndexbufferHandle) { + GL_CALL_EXTRA_FUNCTION(glBindBuffer( + GL_ELEMENT_ARRAY_BUFFER, + HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle))); + } else { + GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + } else { + GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID)); + } +#ifdef _DEBUG + if (inputAssembler->m_VaoID) { + QT3DS_FOREACH(idx, shaderAttribBuffer.size()) + { + const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]); + NVRenderBackendLayoutEntryGL *entry = + attribLayout->getEntryByName(attrib.m_AttribName); + + if (entry) { + NVRenderBackendLayoutEntryGL &entryData(*entry); + if (entryData.m_Type != attrib.m_Type + || entryData.m_NumComponents != attrib.m_NumComponents + || entryData.m_AttribIndex != attrib.m_AttribLocation) { + qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout", + attrib.m_AttribName.c_str()); + QT3DS_ASSERT(false); + } + } else { + qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str()); + } + } + } +#endif // _DEBUG + + return true; + } + + void NVRenderBackendGL3Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef<QT3DSI32> inDrawBufferSet) + { + NVRENDER_BACKEND_UNUSED(rto); + + m_DrawBuffersArray.clear(); + + for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) { + if (inDrawBufferSet[idx] < 0) + m_DrawBuffersArray.push_back(GL_NONE); + else + m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]); + } + + GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), m_DrawBuffersArray.data())); + } + + void NVRenderBackendGL3Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) + { + NVRENDER_BACKEND_UNUSED(rto); + + GL_CALL_EXTRA_FUNCTION(glReadBuffer(m_Conversion.fromReadFacesToGL(inReadFace))); + } + + void NVRenderBackendGL3Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, + QT3DSI32 layer) + { + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_EXTRA_FUNCTION(glFramebufferTextureLayer(GL_FRAMEBUFFER, glAttach, texID, level, layer)) + } + + void NVRenderBackendGL3Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto) + { + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID)); + } + + void NVRenderBackendGL3Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) + { + GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + m_Conversion.fromClearFlagsToGL(flags), + m_Conversion.fromTextureMagnifyingOpToGL(filter))); + } + + void *NVRenderBackendGL3Impl::MapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t length, NVRenderBufferAccessFlags accessFlags) + { + void *ret = NULL; + ret = GL_CALL_EXTRA_FUNCTION(glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset, + length, m_Conversion.fromBufferAccessBitToGL(accessFlags))); + + return ret; + } + + bool NVRenderBackendGL3Impl::UnmapBuffer(NVRenderBackendBufferObject, + NVRenderBufferBindFlags bindFlags) + { + GLboolean ret; + + ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags))); + + return (ret) ? true : false; + } + + QT3DSI32 NVRenderBackendGL3Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) + { + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GLint numUniformBuffers; + GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBuffers)); + + return numUniformBuffers; + } + + QT3DSI32 + NVRenderBackendGL3Impl::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + GLuint blockIndex = GL_INVALID_INDEX; + + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, nameBuf)); + + if (*length > 0) { + blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf)); + if (blockIndex != GL_INVALID_INDEX) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize)); + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount)); + } + } + + return blockIndex; + } + + void + NVRenderBackendGL3Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + if (indices) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices)); + } + } + + void NVRenderBackendGL3Impl::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) + { + QT3DS_ASSERT(po); + QT3DS_ASSERT(count); + QT3DS_ASSERT(indices); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + if (count && indices) { + if (type) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_TYPE, type)); + // convert to UIC types + QT3DS_FOREACH(idx, count) + { + type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]); + } + } + if (size) { + GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_SIZE, size)); + } + if (offset) { + GL_CALL_EXTRA_FUNCTION( + glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset)); + } + } + } + + void NVRenderBackendGL3Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding)); + } + + void NVRenderBackendGL3Impl::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { + QT3DS_ASSERT(bo); + + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID)); + } + + NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGL3Impl::CreateQuery() + { + QT3DSU32 glQueryID = 0; + + GL_CALL_EXTRA_FUNCTION(glGenQueries(1, &glQueryID)); + + return (NVRenderBackendQueryObject)glQueryID; + } + + void NVRenderBackendGL3Impl::ReleaseQuery(NVRenderBackendQueryObject qo) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + GL_CALL_EXTRA_FUNCTION(glDeleteQueries(1, &queryID)); + } + + void NVRenderBackendGL3Impl::BeginQuery(NVRenderBackendQueryObject qo, + NVRenderQueryType::Enum type) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + GL_CALL_EXTRA_FUNCTION(glBeginQuery(m_Conversion.fromQueryTypeToGL(type), queryID)); + } + + void NVRenderBackendGL3Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum type) + { + GL_CALL_EXTRA_FUNCTION(glEndQuery(m_Conversion.fromQueryTypeToGL(type))); + } + + void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, + QT3DSU32 *params) + { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + if (params) + GL_CALL_EXTRA_FUNCTION(glGetQueryObjectuiv( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); + } + + void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, + QT3DSU64 *params) + { + if (m_backendSupport.caps.bits.bTimerQuerySupported) { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); + + if (params) +#if defined(QT_OPENGL_ES) + GL_CALL_TIMER_EXT(glGetQueryObjectui64vEXT( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); +#else + GL_CALL_TIMER_EXT(glGetQueryObjectui64v( + queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params)); +#endif + } + } + + void NVRenderBackendGL3Impl::SetQueryTimer(NVRenderBackendQueryObject qo) + { + if (m_backendSupport.caps.bits.bTimerQuerySupported) { + GLuint queryID = HandleToID_cast(GLuint, size_t, qo); +#if defined(QT_OPENGL_ES) + GL_CALL_TIMER_EXT(glQueryCounterEXT(queryID, GL_TIMESTAMP_EXT)); +#else + GL_CALL_TIMER_EXT(glQueryCounter(queryID, GL_TIMESTAMP)); +#endif + } + } + + NVRenderBackend::NVRenderBackendSyncObject + NVRenderBackendGL3Impl::CreateSync(NVRenderSyncType::Enum syncType, NVRenderSyncFlags) + { + GLsync syncID = 0; + + syncID = GL_CALL_EXTRA_FUNCTION(glFenceSync(m_Conversion.fromSyncTypeToGL(syncType), 0)); + + return NVRenderBackendSyncObject(syncID); + } + + void NVRenderBackendGL3Impl::ReleaseSync(NVRenderBackendSyncObject so) + { + GLsync syncID = (GLsync)so; + + GL_CALL_EXTRA_FUNCTION(glDeleteSync(syncID)); + } + + void NVRenderBackendGL3Impl::WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags, + QT3DSU64) + { + GLsync syncID = (GLsync)so; + + GL_CALL_EXTRA_FUNCTION(glWaitSync(syncID, 0, GL_TIMEOUT_IGNORED)); + } +} +} diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h new file mode 100644 index 00000000..7147b341 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL3_H +#define QT3DS_RENDER_BACKEND_GL3_H + +/// @file Qt3DSRenderBackendGL3.h +/// NVRender OpenGL 3 backend definition. + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSOpenGLExtensions.h" + +#include <QtGui/QOpenGLExtraFunctions> +#include <QtOpenGLExtensions/QtOpenGLExtensions> + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendMiscStateGL; + + using namespace foundation; + + class NVRenderBackendGL3Impl : public NVRenderBackendGLBase + { + public: + /// constructor + NVRenderBackendGL3Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGL3Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override; + + void SetDrawBuffers(NVRenderBackendRenderTargetObject rto, + NVConstDataRef<QT3DSI32> inDrawBufferSet) override; + void SetReadBuffer(NVRenderBackendRenderTargetObject rto, + NVReadFaces::Enum inReadFace) override; + + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; + void SetReadTarget(NVRenderBackendRenderTargetObject rto) override; + + void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) override; + + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + protected: + NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state +#if defined(QT_OPENGL_ES_2) + Qt3DSOpenGLES2Extensions *m_qt3dsExtensions; +#else + QOpenGLExtension_ARB_timer_query *m_timerExtension; + QOpenGLExtension_ARB_tessellation_shader *m_tessellationShader; + QOpenGLExtension_ARB_texture_multisample *m_multiSample; + Qt3DSOpenGLExtensions *m_qt3dsExtensions; +#endif + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp new file mode 100644 index 00000000..083fc35e --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp @@ -0,0 +1,875 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGL4.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" + +#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +#if defined(QT_OPENGL_ES) +#define GL_CALL_NVPATH_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#else +#define GL_CALL_NVPATH_EXT(x) m_nvPathRendering->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_DIRECTSTATE_EXT(x) m_directStateAccess->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x); +#endif + +#ifndef GL_GEOMETRY_SHADER_EXT +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#endif + +namespace qt3ds { +namespace render { + + /// constructor + NVRenderBackendGL4Impl::NVRenderBackendGL4Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : NVRenderBackendGL3Impl(fnd, stringTable, format) + { + eastl::string extTess("GL_ARB_tessellation_shader"); + eastl::string extGeometry("GL_EXT_geometry_shader4"); + eastl::string arbCompute("GL_ARB_compute_shader"); + eastl::string arbStorageBuffer("GL_ARB_shader_storage_buffer_object"); + eastl::string arbAtomicCounterBuffer("GL_ARB_shader_atomic_counters"); + eastl::string arbProgInterface("GL_ARB_program_interface_query"); + eastl::string arbShaderImageLoadStore("GL_ARB_shader_image_load_store"); + eastl::string nvPathRendering("GL_NV_path_rendering"); + eastl::string nvBlendAdvanced("GL_NV_blend_equation_advanced"); + eastl::string khrBlendAdvanced("GL_KHR_blend_equation_advanced"); + eastl::string nvBlendAdvancedCoherent("GL_NV_blend_equation_advanced_coherent"); + eastl::string khrBlendAdvancedCoherent("GL_KHR_blend_equation_advanced_coherent"); + + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + // get extension count + GLint numExtensions = 0; + GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions)); + + for (QT3DSI32 i = 0; i < numExtensions; i++) { + char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i)); + + // search for extension + if (!m_backendSupport.caps.bits.bTessellationSupported + && extTess.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bTessellationSupported = true; + } else if (!m_backendSupport.caps.bits.bComputeSupported + && arbCompute.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bComputeSupported = true; + } else if (!m_backendSupport.caps.bits.bGeometrySupported + && extGeometry.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bGeometrySupported = true; + } else if (!m_backendSupport.caps.bits.bStorageBufferSupported + && arbStorageBuffer.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bStorageBufferSupported = true; + } else if (!m_backendSupport.caps.bits.bAtomicCounterBufferSupported + && arbAtomicCounterBuffer.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; + } else if (!m_backendSupport.caps.bits.bProgramInterfaceSupported + && arbProgInterface.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bProgramInterfaceSupported = true; + } else if (!m_backendSupport.caps.bits.bShaderImageLoadStoreSupported + && arbShaderImageLoadStore.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; + } else if (!m_backendSupport.caps.bits.bNVPathRenderingSupported + && nvPathRendering.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVPathRenderingSupported = true; + } else if (!m_backendSupport.caps.bits.bNVAdvancedBlendSupported + && nvBlendAdvanced.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVAdvancedBlendSupported = true; + } else if (!m_backendSupport.caps.bits.bNVBlendCoherenceSupported + && nvBlendAdvancedCoherent.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bNVBlendCoherenceSupported = true; + } else if (!m_backendSupport.caps.bits.bKHRAdvancedBlendSupported + && khrBlendAdvanced.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported = true; + } else if (!m_backendSupport.caps.bits.bKHRBlendCoherenceSupported + && khrBlendAdvancedCoherent.compare(extensionString) == 0) { + m_backendSupport.caps.bits.bKHRBlendCoherenceSupported = true; + } + } + + // always true for GL4.1 and GLES 3.1 devices + m_backendSupport.caps.bits.bMsTextureSupported = true; + m_backendSupport.caps.bits.bProgramPipelineSupported = true; + + if (!isESCompatible()) { + // TODO: investigate GL 4.0 support + // we expect minimum GL 4.1 context anything beyond is handeled via extensions + // Tessellation is always supported on none ES systems which support >=GL4 + m_backendSupport.caps.bits.bTessellationSupported = true; + // geometry shader is always supported on none ES systems which support >=GL4 ( actually + // 3.2 already ) + m_backendSupport.caps.bits.bGeometrySupported = true; + } else { + // always true for GLES 3.1 devices + m_backendSupport.caps.bits.bComputeSupported = true; + m_backendSupport.caps.bits.bProgramInterfaceSupported = true; + m_backendSupport.caps.bits.bStorageBufferSupported = true; + m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true; + m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true; + } + +#if !defined(QT_OPENGL_ES) + // Initialize extensions + m_nvPathRendering = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_NV_path_rendering)(); + m_nvPathRendering->initializeOpenGLFunctions(); + m_directStateAccess = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_EXT_direct_state_access)(); + m_directStateAccess->initializeOpenGLFunctions(); +#endif + } + + /// destructor + NVRenderBackendGL4Impl::~NVRenderBackendGL4Impl() + { +#if !defined(QT_OPENGL_ES) + if (m_nvPathRendering) + NVDelete(m_Foundation.getAllocator(), m_nvPathRendering); + if (m_directStateAccess) + NVDelete(m_Foundation.getAllocator(), m_directStateAccess); +#endif + } + + void NVRenderBackendGL4Impl::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) + { + GL_CALL_EXTRA_FUNCTION( + glDrawArraysIndirect(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + indirect)); + } + + void NVRenderBackendGL4Impl::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) + { + GL_CALL_EXTRA_FUNCTION(glDrawElementsIndirect( + m_Conversion.fromDrawModeToGL(drawMode, + m_backendSupport.caps.bits.bTessellationSupported), + m_Conversion.fromIndexBufferComponentsTypesToGL(type), indirect)); + } + + void NVRenderBackendGL4Impl::CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + // up to now compressed is not supported + QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + GL_CALL_EXTRA_FUNCTION( + glTexStorage2D(glTarget, levels, glInternalFormat, (GLsizei)width, (GLsizei)height)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGL4Impl::SetMultisampledTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, + bool fixedsamplelocations) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + GL_CALL_EXTRA_FUNCTION(glTexStorage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat, + (GLsizei)width, (GLsizei)height, + fixedsamplelocations)); + + GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0)); + } + + NVRenderBackend::NVRenderBackendTessControlShaderObject + NVRenderBackendGL4Impl::CreateTessControlShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { +#if !defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_CONTROL_SHADER)); +#else + GLuint shaderID = 0; +#endif + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendTessControlShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendTessEvaluationShaderObject + NVRenderBackendGL4Impl::CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { +#if !defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_EVALUATION_SHADER)); +#else + GLuint shaderID = 0; +#endif + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendGeometryShaderObject + NVRenderBackendGL4Impl::CreateGeometryShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { +#if defined(QT_OPENGL_ES) + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER_EXT)); +#else + GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER)); +#endif + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendGeometryShaderObject)shaderID; + } + + void NVRenderBackendGL4Impl::SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, + QT3DSU32 count) + { + QT3DS_ASSERT(iao); + QT3DS_ASSERT(count); + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + inputAssembler->m_PatchVertexCount = count; + } + + void NVRenderBackendGL4Impl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) + { + GL_CALL_EXTRA_FUNCTION(glMemoryBarrier(m_Conversion.fromMemoryBarrierFlagsToGL(barriers))); + } + + void NVRenderBackendGL4Impl::BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, + QT3DSI32 level, bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + GL_CALL_EXTRA_FUNCTION(glBindImageTexture(unit, texID, level, layered, layer, + m_Conversion.fromImageAccessToGL(access), + m_Conversion.fromImageFormatToGL(format))); + } + + QT3DSI32 NVRenderBackendGL4Impl::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) + { + GLint numStorageBuffers = 0; + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) + GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_SHADER_STORAGE_BLOCK, + GL_ACTIVE_RESOURCES, &numStorageBuffers)); +#endif + return numStorageBuffers; + } + + QT3DSI32 + NVRenderBackendGL4Impl::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) + { + GLint bufferIndex = GL_INVALID_INDEX; + + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + QT3DS_ASSERT(bufferSize); + QT3DS_ASSERT(paramCount); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_SHADER_STORAGE_BLOCK, id, nameBufSize, + length, nameBuf)); + + if (*length > 0) { +#define QUERY_COUNT 3 + GLsizei actualCount; + GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, + GL_NUM_ACTIVE_VARIABLES }; + GLint params[QUERY_COUNT]; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_SHADER_STORAGE_BLOCK, id, + QUERY_COUNT, props, QUERY_COUNT, &actualCount, + params)); + + QT3DS_ASSERT(actualCount == QUERY_COUNT); + + bufferIndex = params[0]; + *bufferSize = params[1]; + *paramCount = params[2]; + } + } +#endif + return bufferIndex; + } + + void NVRenderBackendGL4Impl::ProgramSetStorageBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + GL_CALL_EXTRA_FUNCTION( + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); +#endif + } + + QT3DSI32 NVRenderBackendGL4Impl::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) + { + GLint numAtomicCounterBuffers = 0; + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) + GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_ATOMIC_COUNTER_BUFFER, + GL_ACTIVE_RESOURCES, &numAtomicCounterBuffers)); +#endif + return numAtomicCounterBuffers; + } + + QT3DSI32 + NVRenderBackendGL4Impl::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + GLint bufferIndex = GL_INVALID_INDEX; + + QT3DS_ASSERT(po); + QT3DS_ASSERT(length); + QT3DS_ASSERT(nameBuf); + QT3DS_ASSERT(bufferSize); + QT3DS_ASSERT(paramCount); + + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + if (m_backendSupport.caps.bits.bProgramInterfaceSupported) { + { +#define QUERY_COUNT 3 + GLsizei actualCount; + GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, + GL_NUM_ACTIVE_VARIABLES }; + GLint params[QUERY_COUNT]; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_ATOMIC_COUNTER_BUFFER, id, + QUERY_COUNT, props, QUERY_COUNT, &actualCount, + params)); + + QT3DS_ASSERT(actualCount == QUERY_COUNT); + + bufferIndex = params[0]; + *bufferSize = params[1]; + *paramCount = params[2]; + + GLenum props1[1] = { GL_ATOMIC_COUNTER_BUFFER_INDEX }; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_UNIFORM, id, 1, props1, 1, + &actualCount, params)); + + QT3DS_ASSERT(actualCount == 1); + + *nameBuf = '\0'; + GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_UNIFORM, params[0], nameBufSize, + length, nameBuf)); + } + } +#endif + return bufferIndex; + } + + void NVRenderBackendGL4Impl::ProgramSetAtomicCounterBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { +#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1) + GL_CALL_EXTRA_FUNCTION( + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, index, HandleToID_cast(GLuint, size_t, bo))); +#endif + } + + void NVRenderBackendGL4Impl::SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); + + switch (glType) { + case GL_FLOAT: + GL_CALL_EXTRA_FUNCTION(glProgramUniform1fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC2: + GL_CALL_EXTRA_FUNCTION(glProgramUniform2fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC3: + GL_CALL_EXTRA_FUNCTION(glProgramUniform3fv(programID, id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC4: + GL_CALL_EXTRA_FUNCTION(glProgramUniform4fv(programID, id, count, (GLfloat *)value)); + break; + case GL_INT: + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, (GLint *)value)); + break; + case GL_BOOL: + { + GLint boolValue = *(GLboolean *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, &boolValue)); + } + break; + case GL_INT_VEC2: + case GL_BOOL_VEC2: + GL_CALL_EXTRA_FUNCTION(glProgramUniform2iv(programID, id, count, (GLint *)value)); + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + GL_CALL_EXTRA_FUNCTION(glProgramUniform3iv(programID, id, count, (GLint *)value)); + break; + case GL_INT_VEC4: + case GL_BOOL_VEC4: + GL_CALL_EXTRA_FUNCTION(glProgramUniform4iv(programID, id, count, (GLint *)value)); + break; + case GL_FLOAT_MAT3: + GL_CALL_EXTRA_FUNCTION( + glProgramUniformMatrix3fv(programID, id, count, transpose, (GLfloat *)value)); + break; + case GL_FLOAT_MAT4: + GL_CALL_EXTRA_FUNCTION( + glProgramUniformMatrix4fv(programID, id, count, transpose, (GLfloat *)value)); + break; + case GL_IMAGE_2D: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_CUBE: { + if (count <= 1) { + GLint sampler = *(GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1i(programID, id, sampler)); + } else { + GLint *sampler = (GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, sampler)); + } + } break; + default: + qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); + QT3DS_ASSERT(false); + break; + } + } + + NVRenderBackend::NVRenderBackendComputeShaderObject + NVRenderBackendGL4Impl::CreateComputeShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + GLuint shaderID = 0; +#if defined(GL_COMPUTE_SHADER) + shaderID = m_glExtraFunctions->glCreateShader(GL_COMPUTE_SHADER); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } +#endif + return (NVRenderBackend::NVRenderBackendComputeShaderObject)shaderID; + } + + void NVRenderBackendGL4Impl::DispatchCompute(NVRenderBackendShaderProgramObject, + QT3DSU32 numGroupsX, QT3DSU32 numGroupsY, + QT3DSU32 numGroupsZ) + { + GL_CALL_EXTRA_FUNCTION(glDispatchCompute(numGroupsX, numGroupsY, numGroupsZ)); + } + + NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGL4Impl::CreateProgramPipeline() + { + GLuint pipeline; + GL_CALL_EXTRA_FUNCTION(glGenProgramPipelines(1, &pipeline)); + + return NVRenderBackend::NVRenderBackendProgramPipeline(pipeline); + } + + void NVRenderBackendGL4Impl::ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + GL_CALL_EXTRA_FUNCTION(glDeleteProgramPipelines(1, &pipeline)); + } + + void NVRenderBackendGL4Impl::SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + + GL_CALL_EXTRA_FUNCTION(glBindProgramPipeline(pipeline)); + } + + void NVRenderBackendGL4Impl::SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) + { + GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo); + GLuint programID = 0; + + if (po) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + programID = static_cast<GLuint>(pProgram->m_ProgramID); + } + + GL_CALL_EXTRA_FUNCTION( + glUseProgramStages(pipeline, m_Conversion.fromShaderTypeFlagsToGL(flags), programID)); + } + + void NVRenderBackendGL4Impl::SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) + { + if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported || + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported) + GL_CALL_EXTRA_FUNCTION(glBlendEquation(m_Conversion.fromBlendEquationToGL( + pBlendEquArg.m_RGBEquation, m_backendSupport.caps.bits.bNVAdvancedBlendSupported, + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported))); + } + + void NVRenderBackendGL4Impl::SetBlendBarrier(void) + { + if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported) + GL_CALL_QT3DS_EXT(glBlendBarrierNV()); + } + + NVRenderBackend::NVRenderBackendPathObject + NVRenderBackendGL4Impl::CreatePathNVObject(size_t range) + { + GLuint pathID = GL_CALL_NVPATH_EXT(glGenPathsNV((GLsizei)range)); + + return NVRenderBackend::NVRenderBackendPathObject(pathID); + } + void NVRenderBackendGL4Impl::SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef<QT3DSU8> inPathCommands, + NVConstDataRef<QT3DSF32> inPathCoords) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, inPathObject); + GL_CALL_NVPATH_EXT(glPathCommandsNV(pathID, inPathCommands.size(), inPathCommands.begin(), + inPathCoords.size(), GL_FLOAT, inPathCoords.begin())); + } + + NVBounds3 + NVRenderBackendGL4Impl::GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_OBJECT_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + NVBounds3 NVRenderBackendGL4Impl::GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_FILL_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + NVBounds3 NVRenderBackendGL4Impl::GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) + { + float data[4]; +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glGetPathParameterfvNV( + HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_STROKE_BOUNDING_BOX_NV, data)); +#endif + return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f)); + } + + void NVRenderBackendGL4Impl::SetStrokeWidth(NVRenderBackendPathObject inPathObject, + QT3DSF32 inStrokeWidth) + { +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glPathParameterfNV(HandleToID_cast(GLuint, size_t, inPathObject), + GL_PATH_STROKE_WIDTH_NV, inStrokeWidth)); +#endif + } + + void NVRenderBackendGL4Impl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) + { +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(inPathProjection); +#else + GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_PROJECTION, inPathProjection.front())); +#endif + } + + void NVRenderBackendGL4Impl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) + { +#if defined(QT_OPENGL_ES) + NVRENDER_BACKEND_UNUSED(inPathModelview); +#else + GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_MODELVIEW, inPathModelview.front())); +#endif + } + + void NVRenderBackendGL4Impl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) + { + GL_CALL_NVPATH_EXT(glPathStencilDepthOffsetNV(inSlope, inBias)); + } + + void NVRenderBackendGL4Impl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) + { + GL_CALL_NVPATH_EXT(glPathCoverDepthFuncNV(m_Conversion.fromBoolOpToGL(inDepthFunction))); + } + + void NVRenderBackendGL4Impl::StencilStrokePath(NVRenderBackendPathObject inPathObject) + { + GL_CALL_NVPATH_EXT(glStencilStrokePathNV(HandleToID_cast(GLuint, size_t, inPathObject), 0x1, (GLuint)~0)); + } + + void NVRenderBackendGL4Impl::StencilFillPath(NVRenderBackendPathObject inPathObject) + { +#if defined(GL_NV_path_rendering) + GL_CALL_NVPATH_EXT(glStencilFillPathNV(HandleToID_cast(GLuint, size_t, inPathObject), + GL_COUNT_UP_NV, (GLuint)~0)); +#endif + } + + void NVRenderBackendGL4Impl::ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glDeletePathsNV(pathID, (GLsizei)range)); + } + + void NVRenderBackendGL4Impl::StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glStencilFillPathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathFillModeToGL(fillMode), stencilMask, + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::StencilStrokePathInstancedN( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glStencilStrokePathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, stencilRef, + stencilMask, m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::CoverFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glCoverFillPathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathCoverModeToGL(coverMode), + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::CoverStrokePathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glCoverStrokePathInstancedNV( + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, + m_Conversion.fromPathCoverModeToGL(coverMode), + m_Conversion.fromPathTransformToGL(transformType), transformValues)); + } + + void NVRenderBackendGL4Impl::LoadPathGlyphs( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + + GL_CALL_NVPATH_EXT(glPathGlyphsNV(pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), (GLsizei)numGlyphs, + m_Conversion.fromPathTypeToGL(type), charCodes, + m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), + pathTemplateID, emScale)); + } + + NVRenderPathReturnValues::Enum NVRenderBackendGL4Impl::LoadPathGlyphsIndexed( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + GLenum glRet = 0; + + glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexArrayNV( + pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyphIndex, + (GLsizei)numGlyphs, pathTemplateID, emScale)); + + return m_Conversion.fromGLToPathFontReturn(glRet); + } + + NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGL4Impl::LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale, QT3DSU32 *count) + { + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + GLenum glRet = 0; + GLuint baseAndCount[2] = { 0, 0 }; + + glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexRangeNV(m_Conversion.fromPathFontTargetToGL(fontTarget), + fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), + pathTemplateID, emScale, baseAndCount)); + + if (count) + *count = baseAndCount[1]; + + return NVRenderBackend::NVRenderBackendPathObject(baseAndCount[0]); + } + + void NVRenderBackendGL4Impl::LoadPathGlyphRange( + NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + GLuint pathTemplateID = (pathParameterTemplate == NULL) + ? ~0 + : HandleToID_cast(GLuint, size_t, pathParameterTemplate); + + GL_CALL_NVPATH_EXT(glPathGlyphRangeNV( + pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName, + m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyph, (GLsizei)numGlyphs, + m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), pathTemplateID, emScale)); + } + + void NVRenderBackendGL4Impl::GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, + const void *charCodes, size_t stride, + QT3DSF32 *metrics) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathMetricsNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), + charCodes, pathID, (GLsizei)stride, metrics)); + } + + void + NVRenderBackendGL4Impl::GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathMetricRangeNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask), + pathID, (GLsizei)numPaths, (GLsizei)stride, metrics)); + } + + void NVRenderBackendGL4Impl::GetPathSpacing( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, QT3DSF32 advanceScale, + QT3DSF32 kerningScale, NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) + { + GLuint pathID = HandleToID_cast(GLuint, size_t, po); + + GL_CALL_NVPATH_EXT(glGetPathSpacingNV(m_Conversion.fromPathListModeToGL(pathListMode), + (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), + charCodes, pathID, advanceScale, kerningScale, + m_Conversion.fromPathTransformToGL(transformType), spacing)); + } +} +} diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h new file mode 100644 index 00000000..bfdc03b7 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL4_H +#define QT3DS_RENDER_BACKEND_GL4_H + +/// @file Qt3DSRenderBackendGL4.h +/// NVRender OpenGL 4 backend definition. + +#include "foundation/Qt3DSAtomic.h" +#include "render/backends/gl/Qt3DSRenderBackendGL3.h" + +namespace qt3ds { +namespace render { + + using namespace foundation; + + class NVRenderBackendGL4Impl : public NVRenderBackendGL3Impl + { + public: + /// constructor + NVRenderBackendGL4Impl(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGL4Impl(); + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation) + + public: + void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; + void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, const void *indirect) override; + + void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) override; + + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override; + + void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, const void *value, + bool transpose) override; + + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) override; + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override; + + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) override; + + virtual NVRenderBackendComputeShaderObject + CreateComputeShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override; + void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + + NVRenderBackendProgramPipeline CreateProgramPipeline() override; + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) override; + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) override; + void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) override; + + void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; + void SetBlendBarrier(void) override; + + NVRenderBackendPathObject CreatePathNVObject(size_t range) override; + void SetPathSpecification(NVRenderBackendPathObject inPathObject, + NVConstDataRef<QT3DSU8> inPathCommands, + NVConstDataRef<QT3DSF32> inPathCoords) override; + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) override; + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) override; + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) override; + void SetStrokeWidth(NVRenderBackendPathObject inPathObject, QT3DSF32 inStrokeWidth) override; + + void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override; + void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override; + void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override; + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) override; + void StencilStrokePath(NVRenderBackendPathObject inPathObject) override; + void StencilFillPath(NVRenderBackendPathObject inPathObject) override; + void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; + + void StencilFillPathInstanced( + NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type, + const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) override; + void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, QT3DSI32 stencilRef, + QT3DSU32 stencilMask, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathFormatType::Enum type, + const void *charCodes, + NVRenderPathCoverMode::Enum coverMode, + NVRenderPathTransformType::Enum transformType, + const QT3DSF32 *transformValues) override; + void LoadPathGlyphs(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, + NVRenderPathFormatType::Enum type, const void *charCodes, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName, + NVRenderPathFontStyleFlags fontStyle, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale, + QT3DSU32 *count) override; + void LoadPathGlyphRange(NVRenderBackendPathObject po, + NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyph, size_t numGlyphs, + NVRenderPathMissingGlyphs::Enum handleMissingGlyphs, + NVRenderBackendPathObject pathParameterTemplate, + QT3DSF32 emScale) override; + void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + NVRenderPathFormatType::Enum type, const void *charCodes, + size_t stride, QT3DSF32 *metrics) override; + void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathGlyphFontMetricFlags metricQueryMask, + size_t stride, QT3DSF32 *metrics) override; + void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths, + NVRenderPathListMode::Enum pathListMode, + NVRenderPathFormatType::Enum type, const void *charCodes, + QT3DSF32 advanceScale, QT3DSF32 kerningScale, + NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) override; + private: +#if !defined(QT_OPENGL_ES) + QOpenGLExtension_NV_path_rendering *m_nvPathRendering; + QOpenGLExtension_EXT_direct_state_access *m_directStateAccess; +#endif + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp new file mode 100644 index 00000000..940ab094 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp @@ -0,0 +1,2220 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render/backends/gl/Qt3DSRenderBackendGLBase.h" +#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h" +#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h" +#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h" +#include "foundation/StringTable.h" + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__) +#else +#define RENDER_LOG_ERROR_PARAMS(x) checkGLError() +#endif + +#define GL_CALL_FUNCTION(x) m_glFunctions->x; RENDER_LOG_ERROR_PARAMS(x); +#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x); + +namespace qt3ds { +namespace render { + +#ifndef GL_PROGRAM_SEPARABLE +#define GL_PROGRAM_SEPARABLE 0x8258 +#endif + +#ifndef GL_UNSIGNED_INT_IMAGE_2D +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif + +#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + + /// constructor + NVRenderBackendGLBase::NVRenderBackendGLBase(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format) + : mRefCount(0) + , m_Foundation(fnd) + , m_StringTable(stringTable) + , m_Conversion() + , m_MaxAttribCount(0) + , m_DrawBuffersArray(m_Foundation.getAllocator(), + "NVRenderBackendGLBase::m_DrawBuffersArray") + , m_format(format) + { + m_glFunctions = new QOpenGLFunctions; + m_glFunctions->initializeOpenGLFunctions(); + m_glExtraFunctions = new QOpenGLExtraFunctions; + m_glExtraFunctions->initializeOpenGLFunctions(); + + // internal state tracker + m_pCurrentRasterizerState = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendRasterizerStateGL)(); + m_pCurrentDepthStencilState = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)(); + } + /// destructor + NVRenderBackendGLBase::~NVRenderBackendGLBase() + { + if (m_pCurrentRasterizerState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentRasterizerState); + if (m_pCurrentDepthStencilState) + NVDelete(m_Foundation.getAllocator(), m_pCurrentDepthStencilState); + if (m_glFunctions) + delete m_glFunctions; + if (m_glExtraFunctions) + delete m_glExtraFunctions; + } + + NVRenderContextType NVRenderBackendGLBase::GetRenderContextType() const + { + if (m_format.renderableType() == QSurfaceFormat::OpenGLES) { + if (m_format.majorVersion() == 2) + return NVRenderContextValues::GLES2; + + if (m_format.majorVersion() == 3) { + if (m_format.minorVersion() >= 1) + return NVRenderContextValues::GLES3PLUS; + else + return NVRenderContextValues::GLES3; + } + } else if (m_format.majorVersion() == 2) { + return NVRenderContextValues::GL2; + } else if (m_format.majorVersion() == 3) { + return NVRenderContextValues::GL3; + } else if (m_format.majorVersion() == 4) { + return NVRenderContextValues::GL4; + } + + return NVRenderContextValues::NullContext; + } + + bool NVRenderBackendGLBase::isESCompatible() const + { + return m_format.renderableType() == QSurfaceFormat::OpenGLES; + } + + const char *NVRenderBackendGLBase::GetShadingLanguageVersion() + { + const char *retval = (const char *)GL_CALL_FUNCTION( + glGetString(GL_SHADING_LANGUAGE_VERSION)); + if (retval == NULL) + return ""; + + return retval; + } + + QT3DSU32 + NVRenderBackendGLBase::GetMaxCombinedTextureUnits() + { + QT3DSI32 maxUnits; + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxUnits)); + return maxUnits; + } + + bool NVRenderBackendGLBase::GetRenderBackendCap( + NVRenderBackend::NVRenderBackendCaps::Enum inCap) const + { + bool bSupported = false; + + switch (inCap) { + case NVRenderBackendCaps::FpRenderTarget: + bSupported = m_backendSupport.caps.bits.bFPRenderTargetsSupported; + break; + case NVRenderBackendCaps::DepthStencilTexture: + bSupported = m_backendSupport.caps.bits.bDepthStencilSupported; + break; + case NVRenderBackendCaps::ConstantBuffer: + bSupported = m_backendSupport.caps.bits.bConstantBufferSupported; + break; + case NVRenderBackendCaps::DxtImages: + bSupported = m_backendSupport.caps.bits.bDXTImagesSupported; + break; + case NVRenderBackendCaps::MsTexture: + bSupported = m_backendSupport.caps.bits.bMsTextureSupported; + break; + case NVRenderBackendCaps::TexSwizzle: + bSupported = m_backendSupport.caps.bits.bTextureSwizzleSupported; + break; + case NVRenderBackendCaps::FastBlits: + bSupported = m_backendSupport.caps.bits.bFastBlitsSupported; + break; + case NVRenderBackendCaps::Tessellation: + bSupported = m_backendSupport.caps.bits.bTessellationSupported; + break; + case NVRenderBackendCaps::Compute: + bSupported = m_backendSupport.caps.bits.bComputeSupported; + break; + case NVRenderBackendCaps::Geometry: + bSupported = m_backendSupport.caps.bits.bGeometrySupported; + break; + case NVRenderBackendCaps::SampleQuery: { + // On the following context sample query is not supported + NVRenderContextType noSamplesQuerySupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noSamplesQuerySupportedContextFlags); + } break; + case NVRenderBackendCaps::TimerQuery: + bSupported = m_backendSupport.caps.bits.bTimerQuerySupported; + break; + case NVRenderBackendCaps::CommandSync: { + // On the following context sync objects are not supported + NVRenderContextType noSyncObjectSupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noSyncObjectSupportedContextFlags); + } break; + case NVRenderBackendCaps::TextureArray: { + // On the following context texture arrays are not supported + NVRenderContextType noTextureArraySupportedContextFlags(NVRenderContextValues::GL2 + | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + bSupported = !(ctxType & noTextureArraySupportedContextFlags); + } break; + case NVRenderBackendCaps::StorageBuffer: + bSupported = m_backendSupport.caps.bits.bStorageBufferSupported; + break; + case NVRenderBackendCaps::AtomicCounterBuffer: + bSupported = m_backendSupport.caps.bits.bAtomicCounterBufferSupported; + break; + case NVRenderBackendCaps::ShaderImageLoadStore: + bSupported = m_backendSupport.caps.bits.bShaderImageLoadStoreSupported; + break; + case NVRenderBackendCaps::ProgramPipeline: + bSupported = m_backendSupport.caps.bits.bProgramPipelineSupported; + break; + case NVRenderBackendCaps::PathRendering: + bSupported = m_backendSupport.caps.bits.bNVPathRenderingSupported; + break; + case NVRenderBackendCaps::AdvancedBlend: + bSupported = m_backendSupport.caps.bits.bNVAdvancedBlendSupported | + m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; + break; + case NVRenderBackendCaps::AdvancedBlendKHR: + bSupported = m_backendSupport.caps.bits.bKHRAdvancedBlendSupported; + break; + case NVRenderBackendCaps::BlendCoherency: + bSupported = m_backendSupport.caps.bits.bNVBlendCoherenceSupported | + m_backendSupport.caps.bits.bKHRBlendCoherenceSupported; + break; + case NVRenderBackendCaps::gpuShader5: + bSupported = m_backendSupport.caps.bits.bGPUShader5ExtensionSupported; + break; + case NVRenderBackendCaps::VertexArrayObject: + bSupported = m_backendSupport.caps.bits.bVertexArrayObjectSupported; + break; + case NVRenderBackendCaps::StandardDerivatives: + bSupported = m_backendSupport.caps.bits.bStandardDerivativesSupported; + break; + case NVRenderBackendCaps::TextureLod: + bSupported = m_backendSupport.caps.bits.bTextureLodSupported; + break; + default: + QT3DS_ASSERT(false); + bSupported = false; + break; + } + + return bSupported; + } + + void NVRenderBackendGLBase::GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, + QT3DSI32 *params) const + { + if (params) { + switch (inQuery) { + case NVRenderBackendQuery::MaxTextureSize: + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_TEXTURE_SIZE, params)); + break; + case NVRenderBackendQuery::MaxTextureArrayLayers: { + NVRenderContextType noTextureArraySupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noTextureArraySupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, params)); + } else { + *params = 0; + } + } break; + case NVRenderBackendQuery::MaxConstantBufferSlots: { + NVRenderContextType noConstantBufferSupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noConstantBufferSupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, params)); + } else { + *params = 0; + } + } break; + case NVRenderBackendQuery::MaxConstantBufferBlockSize: { + NVRenderContextType noConstantBufferSupportedContextFlags( + NVRenderContextValues::GL2 | NVRenderContextValues::GLES2); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noConstantBufferSupportedContextFlags)) { + GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, params)); + } else { + *params = 0; + } + } break; + default: + QT3DS_ASSERT(false); + *params = 0; + break; + } + } + } + + QT3DSU32 + NVRenderBackendGLBase::GetDepthBits() const + { + QT3DSI32 depthBits; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_BITS, &depthBits)); + return depthBits; + } + + QT3DSU32 + NVRenderBackendGLBase::GetStencilBits() const + { + QT3DSI32 stencilBits; + GL_CALL_FUNCTION(glGetIntegerv(GL_STENCIL_BITS, &stencilBits)); + return stencilBits; + } + + void NVRenderBackendGLBase::SetMultisample(bool bEnable) + { + QT3DS_ASSERT(m_backendSupport.caps.bits.bMsTextureSupported || !bEnable); + // For GL ES explicit multisample enabling is not needed + // and does not exist + NVRenderContextType noMsaaEnableContextFlags(NVRenderContextValues::GLES2 + | NVRenderContextValues::GLES3 + | NVRenderContextValues::GLES3PLUS); + NVRenderContextType ctxType = GetRenderContextType(); + if (!(ctxType & noMsaaEnableContextFlags)) { + SetRenderState(bEnable, NVRenderState::Multisample); + } + } + + void NVRenderBackendGLBase::SetRenderState(bool bEnable, const NVRenderState::Enum value) + { + if (value == NVRenderState::DepthWrite) { + GL_CALL_FUNCTION(glDepthMask(bEnable)); + } else { + if (bEnable) { + GL_CALL_FUNCTION(glEnable(m_Conversion.fromRenderStateToGL(value))); + } else { + GL_CALL_FUNCTION(glDisable(m_Conversion.fromRenderStateToGL(value))); + } + } + } + + NVRenderBackend::NVRenderBackendDepthStencilStateObject + NVRenderBackendGLBase::CreateDepthStencilState( + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + { + NVRenderBackendDepthStencilStateGL *retval = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)( + enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack, + depthStencilOpFront, depthStencilOpBack); + + return (NVRenderBackend::NVRenderBackendDepthStencilStateObject)retval; + } + + void NVRenderBackendGLBase::ReleaseDepthStencilState( + NVRenderBackendDepthStencilStateObject inDepthStencilState) + { + NVRenderBackendDepthStencilStateGL *inputState = + (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; + if (inputState) + NVDelete(m_Foundation.getAllocator(), inputState); + } + + NVRenderBackend::NVRenderBackendRasterizerStateObject + NVRenderBackendGLBase::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + { + NVRenderBackendRasterizerStateGL *retval = + QT3DS_NEW(m_Foundation.getAllocator(), + NVRenderBackendRasterizerStateGL)(depthBias, depthScale, cullFace); + + return (NVRenderBackend::NVRenderBackendRasterizerStateObject)retval; + } + + void NVRenderBackendGLBase::ReleaseRasterizerState( + NVRenderBackendRasterizerStateObject rasterizerState) + { + NVRenderBackendRasterizerStateGL *inputState = + (NVRenderBackendRasterizerStateGL *)rasterizerState; + if (inputState) + NVDelete(m_Foundation.getAllocator(), inputState); + } + + void NVRenderBackendGLBase::SetDepthStencilState( + NVRenderBackendDepthStencilStateObject inDepthStencilState) + { + NVRenderBackendDepthStencilStateGL *inputState = + (NVRenderBackendDepthStencilStateGL *)inDepthStencilState; + if (inputState && !(*m_pCurrentDepthStencilState == *inputState)) { + // we check on a per single state base + if (inputState->m_DepthEnable != m_pCurrentDepthStencilState->m_DepthEnable) { + SetRenderState(inputState->m_DepthEnable, NVRenderState::DepthTest); + m_pCurrentDepthStencilState->m_DepthEnable = inputState->m_DepthEnable; + } + if (inputState->m_StencilEnable != m_pCurrentDepthStencilState->m_StencilEnable) { + SetRenderState(inputState->m_StencilEnable, NVRenderState::StencilTest); + m_pCurrentDepthStencilState->m_StencilEnable = inputState->m_StencilEnable; + } + + if (inputState->m_DepthMask != m_pCurrentDepthStencilState->m_DepthMask) { + GL_CALL_FUNCTION(glDepthMask(inputState->m_DepthMask)); + m_pCurrentDepthStencilState->m_DepthMask = inputState->m_DepthMask; + } + + if (inputState->m_DepthFunc != m_pCurrentDepthStencilState->m_DepthFunc) { + GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(inputState->m_DepthFunc))); + m_pCurrentDepthStencilState->m_DepthFunc = inputState->m_DepthFunc; + } + + if (!(inputState->m_DepthStencilOpFront + == m_pCurrentDepthStencilState->m_DepthStencilOpFront)) { + GL_CALL_FUNCTION(glStencilOpSeparate( + GL_FRONT, + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_StencilFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthPass))); + m_pCurrentDepthStencilState->m_DepthStencilOpFront = + inputState->m_DepthStencilOpFront; + } + + if (!(inputState->m_DepthStencilOpBack + == m_pCurrentDepthStencilState->m_DepthStencilOpBack)) { + GL_CALL_FUNCTION(glStencilOpSeparate( + GL_BACK, + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_StencilFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthFail), + m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthPass))); + m_pCurrentDepthStencilState->m_DepthStencilOpBack = + inputState->m_DepthStencilOpBack; + } + + if (!(inputState->m_StencilFuncFront + == m_pCurrentDepthStencilState->m_StencilFuncFront)) { + GL_CALL_FUNCTION(glStencilFuncSeparate( + GL_FRONT, + m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncFront.m_Function), + inputState->m_StencilFuncFront.m_ReferenceValue, + inputState->m_StencilFuncFront.m_Mask)); + m_pCurrentDepthStencilState->m_StencilFuncFront = inputState->m_StencilFuncFront; + } + + if (!(inputState->m_StencilFuncBack + == m_pCurrentDepthStencilState->m_StencilFuncBack)) { + GL_CALL_FUNCTION(glStencilFuncSeparate( + GL_BACK, m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncBack.m_Function), + inputState->m_StencilFuncBack.m_ReferenceValue, + inputState->m_StencilFuncBack.m_Mask)); + m_pCurrentDepthStencilState->m_StencilFuncBack = inputState->m_StencilFuncBack; + } + } + } + + void + NVRenderBackendGLBase::SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) + { + NVRenderBackendRasterizerStateGL *inputState = + (NVRenderBackendRasterizerStateGL *)rasterizerState; + if (inputState && !(*m_pCurrentRasterizerState == *inputState)) { + // store current state + *m_pCurrentRasterizerState = *inputState; + + if (m_pCurrentRasterizerState->m_DepthBias != 0.0 + || m_pCurrentRasterizerState->m_DepthScale != 0.0) { + GL_CALL_FUNCTION(glEnable(GL_POLYGON_OFFSET_FILL)); + } else { + GL_CALL_FUNCTION(glDisable(GL_POLYGON_OFFSET_FILL)); + } + + GL_CALL_FUNCTION(glPolygonOffset(m_pCurrentRasterizerState->m_DepthBias, + m_pCurrentRasterizerState->m_DepthScale)); + + GL_CALL_FUNCTION( + glCullFace(m_Conversion.fromFacesToGL(m_pCurrentRasterizerState->m_CullFace))); + } + } + + bool NVRenderBackendGLBase::GetRenderState(const NVRenderState::Enum value) + { + bool enabled = GL_CALL_FUNCTION(glIsEnabled(m_Conversion.fromRenderStateToGL(value))); + return enabled; + } + + NVRenderBoolOp::Enum NVRenderBackendGLBase::GetDepthFunc() + { + QT3DSI32 value; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_FUNC, &value)); + return m_Conversion.fromGLToBoolOp(value); + } + + void NVRenderBackendGLBase::SetDepthFunc(const NVRenderBoolOp::Enum func) + { + GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(func))); + } + + bool NVRenderBackendGLBase::GetDepthWrite() + { + QT3DSI32 value; + GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_WRITEMASK, (GLint *)&value)); + return value ? true : false; + } + + void NVRenderBackendGLBase::SetDepthWrite(bool bEnable) { GL_CALL_FUNCTION(glDepthMask(bEnable)); } + + void NVRenderBackendGLBase::SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) + { + GL_CALL_FUNCTION(glColorMask(bRed, bGreen, bBlue, bAlpha)); + } + + void NVRenderBackendGLBase::GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) + { + QT3DS_ASSERT(pBlendFuncArg); + QT3DSI32_4 values; + + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&values.x)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&values.y)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&values.z)); + GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&values.w)); + + pBlendFuncArg->m_SrcRGB = m_Conversion.fromGLToSrcBlendFunc(values.x); + pBlendFuncArg->m_SrcAlpha = m_Conversion.fromGLToSrcBlendFunc(values.y); + pBlendFuncArg->m_DstRGB = m_Conversion.fromGLToDstBlendFunc(values.z); + pBlendFuncArg->m_DstAlpha = m_Conversion.fromGLToDstBlendFunc(values.w); + } + + void NVRenderBackendGLBase::SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) + { + QT3DSI32_4 values; + + values.x = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcRGB); + values.y = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstRGB); + values.z = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcAlpha); + values.w = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstAlpha); + + GL_CALL_FUNCTION(glBlendFuncSeparate(values.x, values.y, values.z, values.w)); + } + + void NVRenderBackendGLBase::SetBlendEquation(const NVRenderBlendEquationArgument &) + { + // needs GL4 / GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetBlendBarrier() + { + // needs GL4 / GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetScissorRect(NVRenderRect *pRect) + { + QT3DS_ASSERT(pRect); + GL_CALL_FUNCTION(glGetIntegerv(GL_SCISSOR_BOX, (GLint *)pRect)); + } + + void NVRenderBackendGLBase::SetScissorRect(const NVRenderRect &rect) + { + GL_CALL_FUNCTION(glScissor(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height)); + } + + void NVRenderBackendGLBase::GetViewportRect(NVRenderRect *pRect) + { + QT3DS_ASSERT(pRect); + GL_CALL_FUNCTION(glGetIntegerv(GL_VIEWPORT, (GLint *)pRect)); + } + + void NVRenderBackendGLBase::SetViewportRect(const NVRenderRect &rect) + { + GL_CALL_FUNCTION(glViewport(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height);); + } + + void NVRenderBackendGLBase::SetClearColor(const QT3DSVec4 *pClearColor) + { + QT3DS_ASSERT(pClearColor); + + GL_CALL_FUNCTION(glClearColor(pClearColor->x, pClearColor->y, + pClearColor->z, pClearColor->w)); + } + + void NVRenderBackendGLBase::Clear(NVRenderClearFlags flags) + { + GL_CALL_FUNCTION(glClear(m_Conversion.fromClearFlagsToGL(flags))); + } + + NVRenderBackend::NVRenderBackendBufferObject + NVRenderBackendGLBase::CreateBuffer(size_t size, NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, const void *hostPtr) + { + GLuint bufID = 0; + + GL_CALL_FUNCTION(glGenBuffers(1, &bufID)); + + if (bufID && size) { + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + if (target != GL_INVALID_ENUM) { + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferData(target, size, hostPtr, + m_Conversion.fromBufferUsageTypeToGL(usage))); + } else { + GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); + bufID = 0; + qCCritical(GL_ERROR, GLConversion::processGLError(target)); + } + } + + return (NVRenderBackend::NVRenderBackendBufferObject)bufID; + } + + void NVRenderBackendGLBase::BindBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_FUNCTION(glBindBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags), bufID)); + } + + void NVRenderBackendGLBase::ReleaseBuffer(NVRenderBackendBufferObject bo) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID)); + } + + void NVRenderBackendGLBase::UpdateBuffer(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t size, + NVRenderBufferUsageType::Enum usage, const void *data) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferData(target, size, data, m_Conversion.fromBufferUsageTypeToGL(usage))); + } + + void NVRenderBackendGLBase::UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, bo); + GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags); + GL_CALL_FUNCTION(glBindBuffer(target, bufID)); + GL_CALL_FUNCTION(glBufferSubData(target, offset, size, data)); + } + + void *NVRenderBackendGLBase::MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, + size_t, size_t, NVRenderBufferAccessFlags) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NULL; + } + + bool NVRenderBackendGLBase::UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return true; + } + + void NVRenderBackendGLBase::SetMemoryBarrier(NVRenderBufferBarrierFlags) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLBase::CreateQuery() + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackendQueryObject(0); + } + + void NVRenderBackendGLBase::ReleaseQuery(NVRenderBackendQueryObject) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, QT3DSU32 *) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject, + NVRenderQueryResultType::Enum, QT3DSU64 *) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetQueryTimer(NVRenderBackendQueryObject) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderBackend::NVRenderBackendSyncObject + NVRenderBackendGLBase::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackendSyncObject(0); + } + + void NVRenderBackendGLBase::ReleaseSync(NVRenderBackendSyncObject) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, + QT3DSU64) + { + // needs GL 3 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLBase::CreateRenderTarget() + { + GLuint fboID = 0; + + GL_CALL_FUNCTION(glGenFramebuffers(1, &fboID)); + + return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID; + } + + void NVRenderBackendGLBase::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) + { + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + if (fboID) { + GL_CALL_FUNCTION(glDeleteFramebuffers(1, &fboID)); + } + } + + void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) + { + // rto must be the current render target + GLuint rbID = HandleToID_cast(GLuint, size_t, rbo); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + + GL_CALL_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, rbID)); + } + + void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target) + { + // rto must be the current render target + GLuint texID = HandleToID_cast(GLuint, size_t, to); + + QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D + || m_backendSupport.caps.bits.bMsTextureSupported); + + GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, 0)) + } + + void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) + { + // Needs GL3 or GLES 3 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetRenderTarget(NVRenderBackendRenderTargetObject rto) + { + GLuint fboID = HandleToID_cast(GLuint, size_t, rto); + + GL_CALL_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID)); + } + + bool NVRenderBackendGLBase::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */) + { + // rto must be the current render target + GLenum completeStatus = GL_CALL_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER)); + switch (completeStatus) { +#define HANDLE_INCOMPLETE_STATUS(x) \ + case x: \ + qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \ + return false; + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) + HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED) +#undef HANDLE_INCOMPLETE_STATUS + } + return true; + } + + NVRenderBackend::NVRenderBackendRenderbufferObject + NVRenderBackendGLBase::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) + { + GLuint bufID = 0; + + GL_CALL_FUNCTION(glGenRenderbuffers(1, &bufID)); + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + bufID = 0; + } + + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID; + } + + void NVRenderBackendGLBase::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) + { + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + if (bufID) { + GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID)); + } + } + + bool NVRenderBackendGLBase::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) + { + bool success = true; + GLuint bufID = HandleToID_cast(GLuint, size_t, rbo); + + QT3DS_ASSERT(bufID); + + GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID)); + GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER, + GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat), + (GLsizei)width, (GLsizei)height)); + + // check for error + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR, GLConversion::processGLError(error)); + QT3DS_ASSERT(false); + success = false; + } + + return success; + } + + NVRenderBackend::NVRenderBackendTextureObject NVRenderBackendGLBase::CreateTexture() + { + GLuint texID = 0; + + GL_CALL_FUNCTION(glGenTextures(1, &texID)); + return (NVRenderBackend::NVRenderBackendTextureObject)texID; + } + + void NVRenderBackendGLBase::BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0 + unit)); + GL_CALL_FUNCTION(glBindTexture(m_Conversion.fromTextureTargetToGL(target), texID)); + } + + void NVRenderBackendGLBase::BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, + QT3DSI32, NVRenderImageAccessType::Enum, + NVRenderTextureFormats::Enum) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::ReleaseTexture(NVRenderBackendTextureObject to) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GL_CALL_FUNCTION(glDeleteTextures(1, &texID)); + } + + void NVRenderBackendGLBase::SetTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + border, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + // This will look very SetTextureData2D, but the target for glBindTexture will be different from + // the target for + // glTexImage2D. + void NVRenderBackendGLBase::SetTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GLenum glTexTarget = + m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); + bool conversionRequired = format != internalFormat; + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), + internalFormat, swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat, + glformat, gltype, glInternalFormat); + + + if (conversionRequired) { + GLenum dummy; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, dummy); + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) + m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + + // for es2 internal format must be same as format + if (GetRenderContextType() == NVRenderContextValues::GLES2) + glInternalFormat = glformat; + + GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height, + border, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); + } + + void NVRenderBackendGLBase::CreateTextureStorage2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t) + { + // you need GL 4.2 or GLES 3.1 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, + size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + format = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), format, + swizzleMode); + + GLenum glformat = 0, glInternalFormat = 0, gltype = 0; + m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat, + gltype, glInternalFormat); + GL_CALL_FUNCTION(glTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, + (GLsizei)height, glformat, gltype, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGLBase::SetCompressedTextureData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, + (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGLBase::SetCompressedTextureDataCubeFace( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GLenum glTexTarget = + m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat); + GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width, + (GLsizei)height, border, (GLsizei)imageSize, hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0)); + } + + void NVRenderBackendGLBase::SetCompressedTextureSubData2D( + NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(format); + GL_CALL_FUNCTION(glCompressedTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width, + (GLsizei)height, glformat, (GLsizei)imageSize, + hostPtr)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + void NVRenderBackendGLBase::SetTextureData3D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, + size_t, QT3DSI32, NVRenderTextureFormats::Enum, + const void *) + { + // needs GL3 or GLES3 + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) + { + GLuint texID = HandleToID_cast(GLuint, size_t, to); + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0)); + GL_CALL_FUNCTION(glBindTexture(glTarget, texID)); + + GLenum glValue = GLConversion::fromHintToGL(genType); + GL_CALL_FUNCTION(glHint(GL_GENERATE_MIPMAP_HINT, glValue)); + GL_CALL_FUNCTION(glGenerateMipmap(glTarget)); + + GL_CALL_FUNCTION(glBindTexture(glTarget, 0)); + } + + NVRenderTextureSwizzleMode::Enum + NVRenderBackendGLBase::GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const + { + NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle; + m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), inFormat, swizzleMode); + + return swizzleMode; + } + + NVRenderBackend::NVRenderBackendSamplerObject NVRenderBackendGLBase::CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSI32 minLod, QT3DSI32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) + { + // Satisfy the compiler + // We don"t setup the state here for GL + // but we need to pass on the variables here + // to satisfy the interface + NVRENDER_BACKEND_UNUSED(minFilter); + NVRENDER_BACKEND_UNUSED(magFilter); + NVRENDER_BACKEND_UNUSED(wrapS); + NVRENDER_BACKEND_UNUSED(wrapT); + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + NVRENDER_BACKEND_UNUSED(anisotropy); + NVRENDER_BACKEND_UNUSED(borderColor); + + // return a dummy handle + return (NVRenderBackend::NVRenderBackendSamplerObject)0x0001; + } + + void NVRenderBackendGLBase::UpdateSampler( + NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter, + NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT, + NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, + NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc, + QT3DSF32 anisotropy, QT3DSF32 *borderColor) + { + // Satisfy the compiler + // These are not available in GLES 2 and we don't use them right now + NVRENDER_BACKEND_UNUSED(wrapR); + NVRENDER_BACKEND_UNUSED(lodBias); + NVRENDER_BACKEND_UNUSED(minLod); + NVRENDER_BACKEND_UNUSED(maxLod); + NVRENDER_BACKEND_UNUSED(compareMode); + NVRENDER_BACKEND_UNUSED(compareFunc); + NVRENDER_BACKEND_UNUSED(borderColor); + + GLenum glTarget = m_Conversion.fromTextureTargetToGL(target); + + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, + m_Conversion.fromTextureMinifyingOpToGL(minFilter))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, + m_Conversion.fromTextureMagnifyingOpToGL(magFilter))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, + m_Conversion.fromTextureCoordOpToGL(wrapS))); + GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, + m_Conversion.fromTextureCoordOpToGL(wrapT))); + if (m_backendSupport.caps.bits.bAnistropySupported) { + GL_CALL_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy)); + } + } + + void NVRenderBackendGLBase::UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSI32 baseLevel, QT3DSI32 maxLevel) + { + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + NVRENDER_BACKEND_UNUSED(baseLevel); + NVRENDER_BACKEND_UNUSED(maxLevel); + } + + void NVRenderBackendGLBase::UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) + { + NVRENDER_BACKEND_UNUSED(to); + NVRENDER_BACKEND_UNUSED(target); + + // Nothing to do here still might be called + QT3DS_ASSERT(swizzleMode == NVRenderTextureSwizzleMode::NoSwizzle); + + NVRENDER_BACKEND_UNUSED(swizzleMode); + } + + void NVRenderBackendGLBase::ReleaseSampler(NVRenderBackendSamplerObject so) + { + GLuint samplerID = HandleToID_cast(GLuint, size_t, so); + if (!samplerID) + return; + // otherwise nothing to do + } + + NVRenderBackend::NVRenderBackendAttribLayoutObject + NVRenderBackendGLBase::CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) + { + QT3DSU32 attribLayoutSize = sizeof(NVRenderBackendAttributeLayoutGL); + QT3DSU32 entrySize = sizeof(NVRenderBackendLayoutEntryGL) * attribs.size(); + QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), attribLayoutSize + entrySize, + "BackendAttributeLayoutGL"); + NVDataRef<NVRenderBackendLayoutEntryGL> entryRef = + PtrAtOffset<NVRenderBackendLayoutEntryGL>(newMem, attribLayoutSize, entrySize); + QT3DSU32 maxInputSlot = 0; + + // copy data + QT3DS_FOREACH(idx, attribs.size()) + { + entryRef[idx].m_AttribName = m_StringTable->RegisterStr(attribs.mData[idx].m_Name); + entryRef[idx].m_Normalize = 0; + entryRef[idx].m_AttribIndex = 0; // will be set later + entryRef[idx].m_Type = m_Conversion.fromComponentTypeAndNumCompsToAttribGL( + attribs.mData[idx].m_ComponentType, attribs.mData[idx].m_NumComponents); + entryRef[idx].m_NumComponents = attribs.mData[idx].m_NumComponents; + entryRef[idx].m_InputSlot = attribs.mData[idx].m_InputSlot; + entryRef[idx].m_Offset = attribs.mData[idx].m_FirstItemOffset; + + if (maxInputSlot < entryRef[idx].m_InputSlot) + maxInputSlot = entryRef[idx].m_InputSlot; + } + + NVRenderBackendAttributeLayoutGL *retval = + new (newMem) NVRenderBackendAttributeLayoutGL(entryRef, maxInputSlot); + + return (NVRenderBackend::NVRenderBackendAttribLayoutObject)retval; + } + + void NVRenderBackendGLBase::ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) + { + NVRenderBackendAttributeLayoutGL *attribLayout = (NVRenderBackendAttributeLayoutGL *)ao; + + NVDelete(m_Foundation.getAllocator(), attribLayout); + }; + + NVRenderBackend::NVRenderBackendInputAssemblerObject + NVRenderBackendGLBase::CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef<NVRenderBackendBufferObject> buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef<QT3DSU32> strides, + NVConstDataRef<QT3DSU32> offsets, + QT3DSU32 patchVertexCount) + { + NVRenderBackendAttributeLayoutGL *attribLayoutGL = + (NVRenderBackendAttributeLayoutGL *)attribLayout; + + NVRenderBackendInputAssemblerGL *retval = QT3DS_NEW(m_Foundation.getAllocator(), + NVRenderBackendInputAssemblerGL)( + m_Foundation, attribLayoutGL, buffers, indexBuffer, strides, offsets, patchVertexCount); + + return (NVRenderBackend::NVRenderBackendInputAssemblerObject)retval; + } + + void NVRenderBackendGLBase::ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) + { + NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao; + NVDelete(m_Foundation.getAllocator(), inputAssembler); + } + + bool NVRenderBackendGLBase::compileSource(GLuint shaderID, NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + GLint shaderSourceSize = static_cast<GLint>(source.size()); + const char *shaderSourceData = (const char *)source.begin(); + GLint shaderStatus = GL_TRUE; + + if (!binary) { + + GL_CALL_FUNCTION(glShaderSource(shaderID, 1, &shaderSourceData, &shaderSourceSize)); + GL_CALL_FUNCTION(glCompileShader(shaderID)); + + GLint logLen; + GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_COMPILE_STATUS, &shaderStatus)); + GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLen)); + + // Check if some log exists. We also write warnings here + // Should at least contain more than the null termination + if (logLen > 2) { + errorMessage.resize(logLen + 1); + + GLint lenWithoutNull; + GL_CALL_FUNCTION(glGetShaderInfoLog(shaderID, logLen, &lenWithoutNull, + (char *)errorMessage.c_str())); + } + } else { + GL_CALL_FUNCTION(glShaderBinary(1, &shaderID, GL_NVIDIA_PLATFORM_BINARY_NV, shaderSourceData, + shaderSourceSize)); + GLenum binaryError = m_glFunctions->glGetError(); + if (binaryError != GL_NO_ERROR) { + shaderStatus = GL_FALSE; + qCCritical(GL_ERROR, GLConversion::processGLError(binaryError)); + } + } + + return (shaderStatus == GL_TRUE); + } + + NVRenderBackend::NVRenderBackendVertexShaderObject + NVRenderBackendGLBase::CreateVertexShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_VERTEX_SHADER)); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendVertexShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendFragmentShaderObject + NVRenderBackendGLBase::CreateFragmentShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_FRAGMENT_SHADER)); + + if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) { + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + shaderID = 0; + } + + return (NVRenderBackend::NVRenderBackendFragmentShaderObject)shaderID; + } + + NVRenderBackend::NVRenderBackendTessControlShaderObject + NVRenderBackendGLBase::CreateTessControlShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4 or GLES EXT_tessellation_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendTessControlShaderObject)0; + } + + NVRenderBackend::NVRenderBackendTessEvaluationShaderObject + NVRenderBackendGLBase::CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4 or GLES EXT_tessellation_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)0; + } + + NVRenderBackend::NVRenderBackendGeometryShaderObject + NVRenderBackendGLBase::CreateGeometryShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4 or GLES EXT_geometry_shader support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendGeometryShaderObject)0; + } + + NVRenderBackend::NVRenderBackendComputeShaderObject + NVRenderBackendGLBase::CreateComputeShader(NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary) + { + // needs GL 4.3 or GLES3.1 support + NVRENDER_BACKEND_UNUSED(source); + NVRENDER_BACKEND_UNUSED(errorMessage); + NVRENDER_BACKEND_UNUSED(binary); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return (NVRenderBackend::NVRenderBackendComputeShaderObject)0; + } + + void NVRenderBackendGLBase::ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void + NVRenderBackendGLBase::ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseTessEvaluationShader( + NVRenderBackendTessEvaluationShaderObject teso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) + { + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glDeleteShader(shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, vso); + + GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, fso); + + GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso); + + GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, teso); + + GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, gso); + + GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint shaderID = HandleToID_cast(GLuint, size_t, cso); + + GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID)); + } + + NVRenderBackend::NVRenderBackendShaderProgramObject + NVRenderBackendGLBase::CreateShaderProgram(bool isSeparable) + { + NVRenderBackendShaderProgramGL *theProgram = NULL; + GLuint programID = GL_CALL_FUNCTION(glCreateProgram()); + + if (programID) { + theProgram = + QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendShaderProgramGL)(programID); + + if (!theProgram) { + GL_CALL_FUNCTION(glDeleteProgram(programID)); + } else if (isSeparable && m_backendSupport.caps.bits.bProgramPipelineSupported) { + GL_CALL_EXTRA_FUNCTION(glProgramParameteri(programID, GL_PROGRAM_SEPARABLE, GL_TRUE)); + } + } + + return (NVRenderBackend::NVRenderBackendShaderProgramObject)theProgram; + } + + void NVRenderBackendGLBase::ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GL_CALL_FUNCTION(glDeleteProgram(programID)); + + if (pProgram->m_shaderInput) { + NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); + pProgram->m_shaderInput = NULL; + } + + NVDelete(m_Foundation.getAllocator(), pProgram); + } + + bool NVRenderBackendGLBase::LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) + { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GL_CALL_FUNCTION(glLinkProgram(programID)); + + GLint linkStatus, logLen; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_LINK_STATUS, &linkStatus)); + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLen)); + + // if succesfuly linked get the attribute information + if (linkStatus) { + // release old stuff + if (pProgram->m_shaderInput) { + NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput); + pProgram->m_shaderInput = NULL; + } + + GLint numAttribs; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTES, &numAttribs)); + + if (numAttribs) { + NVRenderBackendShaderInputEntryGL *tempShaderInputEntry = + (NVRenderBackendShaderInputEntryGL *)QT3DS_ALLOC( + m_Foundation.getAllocator(), + sizeof(NVRenderBackendShaderInputEntryGL) * m_MaxAttribCount, + "BackendShaderInputEntryGL"); + + GLint maxLength; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength)); + QT3DSI8 *nameBuf = + (QT3DSI8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), maxLength, "LinkProgram"); + + // fill in data + QT3DSU32 count = 0; + QT3DS_FOREACH(idx, numAttribs) + { + GLint size = 0; + GLenum glType; + NVRenderComponentTypes::Enum compType = NVRenderComponentTypes::Unknown; + QT3DSU32 numComps = 0; + + GL_CALL_FUNCTION(glGetActiveAttrib(programID, idx, maxLength, NULL, &size, &glType, + (char *)nameBuf)); + // Skip anything named with gl_ + if (memcmp(nameBuf, "gl_", 3) == 0) + continue; + + m_Conversion.fromAttribGLToComponentTypeAndNumComps(glType, compType, numComps); + + tempShaderInputEntry[count].m_AttribName = + m_StringTable->RegisterStr((char *)nameBuf); + tempShaderInputEntry[count].m_AttribLocation = + GL_CALL_FUNCTION(glGetAttribLocation(programID, (char *)nameBuf)); + tempShaderInputEntry[count].m_Type = glType; + tempShaderInputEntry[count].m_NumComponents = numComps; + + ++count; + } + + // Now allocate space for the actuall entries + QT3DSU32 shaderInputSize = sizeof(NVRenderBackendShaderInputGL); + QT3DSU32 entrySize = sizeof(NVRenderBackendShaderInputEntryGL) * count; + QT3DSU8 *newMem = + (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), shaderInputSize + entrySize, + "BackendShaderInputEntryGL"); + NVDataRef<NVRenderBackendShaderInputEntryGL> entryRef = + PtrAtOffset<NVRenderBackendShaderInputEntryGL>(newMem, shaderInputSize, + entrySize); + // fill data + QT3DS_FOREACH(idx, count) + { + entryRef[idx].m_AttribName = tempShaderInputEntry[idx].m_AttribName; + entryRef[idx].m_AttribLocation = tempShaderInputEntry[idx].m_AttribLocation; + entryRef[idx].m_Type = tempShaderInputEntry[idx].m_Type; + entryRef[idx].m_NumComponents = tempShaderInputEntry[idx].m_NumComponents; + } + + // placement new + NVRenderBackendShaderInputGL *shaderInput = + new (newMem) NVRenderBackendShaderInputGL(entryRef); + // set the pointer + pProgram->m_shaderInput = shaderInput; + + QT3DS_FREE(m_Foundation.getAllocator(), nameBuf); + QT3DS_FREE(m_Foundation.getAllocator(), tempShaderInputEntry); + } + } + + // Check if some log exists. We also write warnings here + // Should at least contain more than the null termination + if (logLen > 2) { + errorMessage.resize(logLen + 1); + + GLint lenWithoutNull; + GL_CALL_FUNCTION(glGetProgramInfoLog(programID, logLen, &lenWithoutNull, + (char *)errorMessage.c_str())); + } + + return (linkStatus == GL_TRUE); + } + + void NVRenderBackendGLBase::SetActiveProgram(NVRenderBackendShaderProgramObject po) + { + GLuint programID = 0; + + if (po) { + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + programID = static_cast<GLuint>(pProgram->m_ProgramID); + } + + GL_CALL_FUNCTION(glUseProgram(programID)); + } + + NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGLBase::CreateProgramPipeline() + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + return NVRenderBackend::NVRenderBackendProgramPipeline(0); + } + + void NVRenderBackendGLBase::ReleaseProgramPipeline(NVRenderBackendProgramPipeline) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::SetActiveProgramPipeline(NVRenderBackendProgramPipeline) + { + // needs GL 4 context + //TODO: should be fixed? + // QT3DS_ASSERT(false); + } + + void NVRenderBackendGLBase::SetProgramStages(NVRenderBackendProgramPipeline, + NVRenderShaderTypeFlags, + NVRenderBackendShaderProgramObject) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSU32) + { + // needs GL 4 context + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + QT3DSI32 NVRenderBackendGLBase::GetConstantCount(NVRenderBackendShaderProgramObject po) + { + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GLint numUniforms; + GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORMS, &numUniforms)); + + return numUniforms; + } + + QT3DSI32 NVRenderBackendGLBase::GetConstantBufferCount(NVRenderBackendShaderProgramObject po) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; + } + + QT3DSI32 + NVRenderBackendGLBase::GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) + { + QT3DS_ASSERT(po); + NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po; + GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID); + + GLenum glType; + GL_CALL_FUNCTION(glGetActiveUniform(programID, id, bufSize, NULL, numElem, &glType, nameBuf)); + *type = m_Conversion.fromShaderGLToPropertyDataTypes(glType); + + QT3DSI32 uniformLoc = GL_CALL_FUNCTION(glGetUniformLocation(programID, nameBuf)); + + // get unit binding point + *binding = -1; + if (uniformLoc != -1 && (glType == GL_IMAGE_2D || glType == GL_UNSIGNED_INT_IMAGE_2D + || glType == GL_UNSIGNED_INT_ATOMIC_COUNTER)) { + GL_CALL_FUNCTION(glGetUniformiv(programID, uniformLoc, binding)); + } + + return uniformLoc; + } + + QT3DSI32 + NVRenderBackendGLBase::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; + } + + void NVRenderBackendGLBase::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSI32 *indices) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(indices); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetConstantBufferParamInfoByIndices( + NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(count); + NVRENDER_BACKEND_UNUSED(indices); + NVRENDER_BACKEND_UNUSED(type); + NVRENDER_BACKEND_UNUSED(size); + NVRENDER_BACKEND_UNUSED(offset); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(blockIndex); + NVRENDER_BACKEND_UNUSED(binding); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::ProgramSetConstantBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { + // needs GL3 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + QT3DSI32 NVRenderBackendGLBase::GetStorageBufferCount(NVRenderBackendShaderProgramObject po) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; + } + + QT3DSI32 + NVRenderBackendGLBase::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; + } + + void NVRenderBackendGLBase::ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); + } + + QT3DSI32 NVRenderBackendGLBase::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + + return 0; + } + + QT3DSI32 + NVRenderBackendGLBase::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, + QT3DSI32 *paramCount, QT3DSI32 *bufferSize, + QT3DSI32 *length, char *nameBuf) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(po); + NVRENDER_BACKEND_UNUSED(id); + NVRENDER_BACKEND_UNUSED(nameBufSize); + NVRENDER_BACKEND_UNUSED(paramCount); + NVRENDER_BACKEND_UNUSED(bufferSize); + NVRENDER_BACKEND_UNUSED(length); + NVRENDER_BACKEND_UNUSED(nameBuf); + + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return -1; + } + + void NVRenderBackendGLBase::ProgramSetAtomicCounterBuffer(QT3DSU32 index, + NVRenderBackendBufferObject bo) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(index); + NVRENDER_BACKEND_UNUSED(bo); + } + + void NVRenderBackendGLBase::SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) + { + GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type); + + switch (glType) { + case GL_FLOAT: + GL_CALL_FUNCTION(glUniform1fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC2: + GL_CALL_FUNCTION(glUniform2fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC3: + GL_CALL_FUNCTION(glUniform3fv(id, count, (GLfloat *)value)); + break; + case GL_FLOAT_VEC4: + GL_CALL_FUNCTION(glUniform4fv(id, count, (GLfloat *)value)); + break; + case GL_INT: + GL_CALL_FUNCTION(glUniform1iv(id, count, (GLint *)value)); + break; + case GL_BOOL: + { + GLint boolValue = *(GLboolean *)value; + GL_CALL_FUNCTION(glUniform1iv(id, count, &boolValue)); + } + break; + case GL_INT_VEC2: + case GL_BOOL_VEC2: + GL_CALL_FUNCTION(glUniform2iv(id, count, (GLint *)value)); + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + GL_CALL_FUNCTION(glUniform3iv(id, count, (GLint *)value)); + break; + case GL_INT_VEC4: + case GL_BOOL_VEC4: + GL_CALL_FUNCTION(glUniform4iv(id, count, (GLint *)value)); + break; + case GL_FLOAT_MAT3: + GL_CALL_FUNCTION(glUniformMatrix3fv(id, count, transpose, (GLfloat *)value)); + break; + case GL_FLOAT_MAT4: + GL_CALL_FUNCTION(glUniformMatrix4fv(id, count, transpose, (GLfloat *)value)); + break; + case GL_IMAGE_2D: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_CUBE: { + if (count > 1) { + GLint *sampler = (GLint *)value; + GL_CALL_FUNCTION(glUniform1iv(id, count, sampler)); + } else { + GLint sampler = *(GLint *)value; + GL_CALL_FUNCTION(glUniform1i(id, sampler)); + } + } break; + default: + qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); + QT3DS_ASSERT(false); + break; + } + } + + void NVRenderBackendGLBase::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) + { + GL_CALL_FUNCTION(glDrawArrays(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + start, count)); + } + + void NVRenderBackendGLBase::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(drawMode); + NVRENDER_BACKEND_UNUSED(indirect); + } + + void NVRenderBackendGLBase::DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) + { + GL_CALL_FUNCTION(glDrawElements(m_Conversion.fromDrawModeToGL( + drawMode, m_backendSupport.caps.bits.bTessellationSupported), + count, m_Conversion.fromIndexBufferComponentsTypesToGL(type), + indices)); + } + + void NVRenderBackendGLBase::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, + const void *indirect) + { + // needs GL4 and above + NVRENDER_BACKEND_UNUSED(drawMode); + NVRENDER_BACKEND_UNUSED(type); + NVRENDER_BACKEND_UNUSED(indirect); + } + + void NVRenderBackendGLBase::ReadPixel(NVRenderBackendRenderTargetObject /* rto */, QT3DSI32 x, + QT3DSI32 y, QT3DSI32 width, QT3DSI32 height, + NVRenderReadPixelFormats::Enum inFormat, void *pixels) + { + GLuint glFormat; + GLuint glType; + if (m_Conversion.fromReadPixelsToGlFormatAndType(inFormat, &glFormat, &glType)) { + GL_CALL_FUNCTION(glReadPixels(x, y, width, height, glFormat, glType, pixels)); + } + } + + NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::CreatePathNVObject(size_t) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderBackend::NVRenderBackendPathObject(0); + } + + void NVRenderBackendGLBase::ReleasePathNVObject(NVRenderBackendPathObject, size_t) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::LoadPathGlyphs(NVRenderBackendPathObject, + NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, + NVRenderBackendPathObject, QT3DSF32) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::LoadPathGlyphRange(NVRenderBackendPathObject, + NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, + NVRenderBackendPathObject, QT3DSF32) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + NVRenderPathReturnValues::Enum NVRenderBackendGLBase::LoadPathGlyphsIndexed( + NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, QT3DSF32) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + + return NVRenderPathReturnValues::FontUnavailable; + } + + NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::LoadPathGlyphsIndexedRange( + NVRenderPathFontTarget::Enum, const void *, NVRenderPathFontStyleFlags, + NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) + { + return NVRenderBackendPathObject(0); + } + + void NVRenderBackendGLBase::GetPathMetrics(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, + NVRenderPathFormatType::Enum, const void *, size_t, + QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, + QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::GetPathSpacing(NVRenderBackendPathObject, size_t, + NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, + QT3DSF32, NVRenderPathTransformType::Enum, QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, + const void *, QT3DSI32, QT3DSU32, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + void NVRenderBackendGLBase::CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, + const QT3DSF32 *) + { + // Needs GL 4 backend + qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__; + } + + ///< private calls + const char *NVRenderBackendGLBase::getVersionString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VERSION)); + if (retval == NULL) + return ""; + + return retval; + } + + const char *NVRenderBackendGLBase::getVendorString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VENDOR)); + if (retval == NULL) + return ""; + + return retval; + } + + const char *NVRenderBackendGLBase::getRendererString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_RENDERER)); + if (retval == NULL) + return ""; + + return retval; + } + + const char *NVRenderBackendGLBase::getExtensionString() + { + const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_EXTENSIONS)); + if (retval == NULL) + return ""; + + return retval; + } + + /** + * @brief This function inspects the various strings to setup + * HW capabilities of the device. + * We can do a lot of smart things here based on GL version + * renderer string and vendor. + * + * @return No return + */ + void NVRenderBackendGLBase::setAndInspectHardwareCaps() + { + eastl::string apiVersion(getVersionString()); + qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str()); + + // we assume all GLES versions running on mobile with shared memory + // this means framebuffer blits are slow and should be optimized or avoided + if (apiVersion.find("OpenGL ES") == eastl::string::npos) { + // no ES device + m_backendSupport.caps.bits.bFastBlitsSupported = true; + } + } + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS + void NVRenderBackendGLBase::checkGLError(const char *function, const char *file, + const unsigned int line) const + { + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) { + qCCritical(GL_ERROR) << GLConversion::processGLError(error) << " " + << function << " " << file << " " << line; + } + } +#else + void NVRenderBackendGLBase::checkGLError() const + { +#if !defined(NDEBUG) || defined(_DEBUG) + GLenum error = m_glFunctions->glGetError(); + if (error != GL_NO_ERROR) + qCCritical(GL_ERROR) << GLConversion::processGLError(error); +#endif + } +#endif + +} +} diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h new file mode 100644 index 00000000..9048a9c4 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h @@ -0,0 +1,530 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_GL_BASE_H +#define QT3DS_RENDER_BACKEND_GL_BASE_H + +/// @file Qt3DSRenderBackendGLBase.h +/// NVRender OpenGL Core backend definition. + +#include "foundation/Qt3DSContainers.h" +#include "foundation/StringTable.h" +#include "render/backends/Qt3DSRenderBackend.h" +#include "render/backends/gl/Qt3DSOpenGLUtil.h" +#include <EASTL/string.h> + +#include <QtGui/QSurfaceFormat> +#include <QtGui/QOpenGLFunctions> +#include <QtOpenGLExtensions/QtOpenGLExtensions> + +#define NVRENDER_BACKEND_UNUSED(arg) (void)arg; + +// Enable this to log opengl errors instead of an assert +//#define RENDER_BACKEND_LOG_GL_ERRORS + +namespace qt3ds { +namespace render { + + ///< forward declaration + class NVRenderBackendRasterizerStateGL; + class NVRenderBackendDepthStencilStateGL; + + using namespace foundation; + + typedef eastl::basic_string<char8_t, ForwardingAllocator> TContextStr; + + class NVRenderBackendGLBase : public NVRenderBackend + { + public: + /// constructor + NVRenderBackendGLBase(NVFoundationBase &fnd, + qt3ds::foundation::IStringTable &stringTable, + const QSurfaceFormat &format); + /// destructor + virtual ~NVRenderBackendGLBase(); + + public: + /// API Interface + NVRenderContextType GetRenderContextType() const override; + bool isESCompatible() const; + + const char *GetShadingLanguageVersion() override; + /// get implementation depended values + QT3DSU32 GetMaxCombinedTextureUnits() override; + bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const override; + QT3DSU32 GetDepthBits() const override; + QT3DSU32 GetStencilBits() const override; + void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override; + + /// state get/set functions + void SetRenderState(bool bEnable, const NVRenderState::Enum value) override; + bool GetRenderState(const NVRenderState::Enum value) override; + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, + bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) override; + virtual void + ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; + virtual NVRenderBackendRasterizerStateObject + CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) override; + void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; + virtual void + SetDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override; + void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override; + NVRenderBoolOp::Enum GetDepthFunc() override; + void SetDepthFunc(const NVRenderBoolOp::Enum func) override; + bool GetDepthWrite() override; + void SetDepthWrite(bool bEnable) override; + void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) override; + void SetMultisample(bool bEnable) override; + void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) override; + void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) override; + void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override; + void SetBlendBarrier(void) override; + void GetScissorRect(NVRenderRect *pRect) override; + void SetScissorRect(const NVRenderRect &rect) override; + void GetViewportRect(NVRenderRect *pRect) override; + void SetViewportRect(const NVRenderRect &rect) override; + + void SetClearColor(const QT3DSVec4 *pClearColor) override; + void Clear(NVRenderClearFlags flags) override; + + /// resource handling + NVRenderBackendBufferObject CreateBuffer(size_t size, + NVRenderBufferBindFlags bindFlags, + NVRenderBufferUsageType::Enum usage, + const void *hostPtr = NULL) override; + void BindBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + void ReleaseBuffer(NVRenderBackendBufferObject bo) override; + void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t size, NVRenderBufferUsageType::Enum usage, + const void *data) override; + void UpdateBufferRange(NVRenderBackendBufferObject bo, + NVRenderBufferBindFlags bindFlags, size_t offset, + size_t size, const void *data) override; + void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags, + size_t offset, size_t length, + NVRenderBufferAccessFlags accessFlags) override; + bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override; + void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override; + + NVRenderBackendQueryObject CreateQuery() override; + void ReleaseQuery(NVRenderBackendQueryObject qo) override; + void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override; + void GetQueryResult(NVRenderBackendQueryObject qo, + NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override; + void SetQueryTimer(NVRenderBackendQueryObject qo) override; + + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye, + NVRenderSyncFlags syncFlags) override; + void ReleaseSync(NVRenderBackendSyncObject so) override; + void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags, + QT3DSU64 timeout) override; + + NVRenderBackendRenderTargetObject CreateRenderTarget() override; + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendRenderbufferObject rbo) override; + void RenderTargetAttach( + NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) override; + void RenderTargetAttach(NVRenderBackendRenderTargetObject rto, + NVRenderFrameBufferAttachments::Enum attachment, + NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override; + void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override; + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override; + + virtual NVRenderBackendRenderbufferObject + CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width, + size_t height) override; + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override; + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo, + NVRenderRenderBufferFormats::Enum storageFormat, + size_t width, size_t height) override; + + NVRenderBackendTextureObject CreateTexture() override; + void BindTexture(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 unit) override; + void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level, + bool layered, QT3DSI32 layer, + NVRenderImageAccessType::Enum access, + NVRenderTextureFormats::Enum format) override; + void ReleaseTexture(NVRenderBackendTextureObject to) override; + void SetTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void SetTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void CreateTextureStorage2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 levels, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height) override; + void SetTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + void SetCompressedTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) override; + void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, QT3DSI32 border, + size_t imageSize, const void *hostPtr = NULL) override; + void SetCompressedTextureSubData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset, + size_t width, size_t height, + NVRenderTextureFormats::Enum format, + size_t imageSize, const void *hostPtr = NULL) override; + void SetMultisampledTextureData2D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + size_t samples, + NVRenderTextureFormats::Enum internalFormat, + size_t width, size_t height, + bool fixedsamplelocations) override = 0; + + void SetTextureData3D(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSU32 level, + NVRenderTextureFormats::Enum internalFormat, size_t width, + size_t height, size_t depth, QT3DSI32 border, + NVRenderTextureFormats::Enum format, + const void *hostPtr = NULL) override; + + void GenerateMipMaps(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderHint::Enum genType) override; + + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const override; + + NVRenderBackendSamplerObject CreateSampler( + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateSampler( + NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target, + NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear, + NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear, + NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge, + NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge, + QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0, + NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare, + NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual, + QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override; + + void UpdateTextureObject(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel, + QT3DSI32 maxLevel) override; + + void UpdateTextureSwizzle(NVRenderBackendTextureObject to, + NVRenderTextureTargetType::Enum target, + NVRenderTextureSwizzleMode::Enum swizzleMode) override; + + void ReleaseSampler(NVRenderBackendSamplerObject so) override; + + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) override; + void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) override; + + virtual NVRenderBackendInputAssemblerObject + CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout, + NVConstDataRef<NVRenderBackendBufferObject> buffers, + const NVRenderBackendBufferObject indexBuffer, + NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets, + QT3DSU32 patchVertexCount) override; + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) override; + + bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao, + NVRenderBackendShaderProgramObject po) override = 0; + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override + { + QT3DS_ASSERT(false); + } + + // shader + virtual NVRenderBackendVertexShaderObject + CreateVertexShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendFragmentShaderObject + CreateFragmentShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendTessControlShaderObject + CreateTessControlShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, + bool binary) override; + virtual NVRenderBackendGeometryShaderObject + CreateGeometryShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override; + virtual NVRenderBackendComputeShaderObject + CreateComputeShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override; + void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) override; + void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) override; + void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) override; + void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) override; + void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) override; + void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) override; + void AttachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendVertexShaderObject vso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendFragmentShaderObject fso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessControlShaderObject tcso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendTessEvaluationShaderObject teso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendGeometryShaderObject gso) override; + void DetachShader(NVRenderBackendShaderProgramObject po, + NVRenderBackendComputeShaderObject cso) override; + NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) override; + void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) override; + bool LinkProgram(NVRenderBackendShaderProgramObject po, + eastl::string &errorMessage) override; + void SetActiveProgram(NVRenderBackendShaderProgramObject po) override; + void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override; + NVRenderBackendProgramPipeline CreateProgramPipeline() override; + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline po) override; + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline po) override; + void SetProgramStages(NVRenderBackendProgramPipeline ppo, + NVRenderShaderTypeFlags flags, + NVRenderBackendShaderProgramObject po) override; + + // uniforms + QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 bufSize, QT3DSI32 *numElem, + NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding, + char *nameBuf) override; + void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + NVRenderShaderDataTypes::Enum type, QT3DSI32 count, + const void *value, bool transpose) override; + + // uniform buffers + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSI32 *indices) override; + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po, + QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type, + QT3DSI32 *size, QT3DSI32 *offset) override; + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po, + QT3DSU32 blockIndex, QT3DSU32 binding) override; + void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + // storage buffers + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id, + QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override; + void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + // atomic counter buffers + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override; + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po, + QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount, + QT3DSI32 *bufferSize, QT3DSI32 *length, + char *nameBuf) override; + void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override; + + /// draw calls + void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) override; + void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override; + void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, + NVRenderComponentTypes::Enum type, const void *indices) override; + void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode, + NVRenderComponentTypes::Enum type, const void *indirect) override; + + // read calls + void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width, + QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, void *pixels) override; + + // NV path rendering + NVRenderBackendPathObject CreatePathNVObject(size_t range) override; + // Pathing requires gl4 backend. + void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef<QT3DSU8>, + NVConstDataRef<QT3DSF32>) override + { + } + + ///< Bounds of the fill and stroke + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + + /** + * Defaults to 0 if unset. + */ + void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} + void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} + void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} + void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} + void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} + void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} + void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override; + + void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override; + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, + const void *fontName, NVRenderPathFontStyleFlags fontStyle, + QT3DSU32 firstGlyphIndex, size_t numGlyphs, + NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override; + virtual NVRenderBackendPathObject + LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, + NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) override; + void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override; + void GetPathMetrics(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, NVRenderPathFormatType::Enum, + const void *, size_t, QT3DSF32 *) override; + void GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override; + void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, + NVRenderPathTransformType::Enum, QT3DSF32 *) override; + + void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, QT3DSI32, + QT3DSU32, NVRenderPathTransformType::Enum, + const QT3DSF32 *) override; + void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override; + + QSurfaceFormat format() const override + { + return m_format; + } + + protected: + virtual NVFoundationBase &GetFoundation() { return m_Foundation; } + virtual bool compileSource(GLuint shaderID, NVConstDataRef<QT3DSI8> source, + eastl::string &errorMessage, bool binary); + virtual const char *getVersionString(); + virtual const char *getVendorString(); + virtual const char *getRendererString(); + virtual const char *getExtensionString(); + + virtual void setAndInspectHardwareCaps(); + + protected: + volatile QT3DSI32 mRefCount; ///< reference count + NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things + NVScopedRefCounted<qt3ds::foundation::IStringTable> + m_StringTable; ///< pointer to a string table + GLConversion m_Conversion; ///< Class for conversion from base type to GL types + QStringList m_extensions; ///< contains the OpenGL extension string + QT3DSI32 m_MaxAttribCount; ///< Maximum attributes which can be used + nvvector<GLenum> m_DrawBuffersArray; ///< Contains the drawbuffer enums + QSurfaceFormat m_format; + + NVRenderBackendRasterizerStateGL + *m_pCurrentRasterizerState; ///< this holds the current rasterizer state + NVRenderBackendDepthStencilStateGL + *m_pCurrentDepthStencilState; ///< this holds the current depth stencil state + +#ifdef RENDER_BACKEND_LOG_GL_ERRORS + void checkGLError(const char *function, const char *file, const unsigned int line) const; +#else + void checkGLError() const; +#endif + QOpenGLFunctions *m_glFunctions; + QOpenGLExtraFunctions *m_glExtraFunctions; + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h new file mode 100644 index 00000000..e14111af --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H +#define QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/StringTable.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + struct NVRenderBackendLayoutEntryGL + { + CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader + QT3DSU8 m_Normalize; ///< normalize parameter + QT3DSU32 m_AttribIndex; ///< attribute index + QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT + QT3DSU32 m_NumComponents; ///< component count. max 4 + QT3DSU32 m_InputSlot; ///< Input slot where to fetch the data from + QT3DSU32 m_Offset; ///< offset in byte + }; + + ///< this class handles the vertex attribute layout setup + class NVRenderBackendAttributeLayoutGL + { + public: + ///< constructor + NVRenderBackendAttributeLayoutGL(NVDataRef<NVRenderBackendLayoutEntryGL> entries, + QT3DSU32 maxInputSlot) + : m_LayoutAttribEntries(entries) + , m_MaxInputSlot(maxInputSlot) + { + } + ///< destructor + ~NVRenderBackendAttributeLayoutGL(){} + + NVRenderBackendLayoutEntryGL *getEntryByName(CRegisteredString entryName) const + { + QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) + { + if (m_LayoutAttribEntries[idx].m_AttribName == entryName) + return &m_LayoutAttribEntries.mData[idx]; + } + return NULL; + } + + Option<NVRenderBackendLayoutEntryGL> getEntryByAttribIndex(QT3DSU32 attribIndex) const + { + QT3DS_FOREACH(idx, m_LayoutAttribEntries.size()) + { + if (m_LayoutAttribEntries[idx].m_AttribIndex == attribIndex) + return m_LayoutAttribEntries[idx]; + } + return Empty(); + } + + NVDataRef<NVRenderBackendLayoutEntryGL> + m_LayoutAttribEntries; ///< vertex attribute layout entries + QT3DSU32 m_MaxInputSlot; ///< max used input slot + }; + + ///< this class handles the input assembler setup + class NVRenderBackendInputAssemblerGL + { + public: + ///< constructor + NVRenderBackendInputAssemblerGL( + NVFoundationBase &fnd, NVRenderBackendAttributeLayoutGL *attribLayout, + NVConstDataRef<NVRenderBackend::NVRenderBackendBufferObject> buffers, + const NVRenderBackend::NVRenderBackendBufferObject indexBuffer, + NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets, QT3DSU32 patchVertexCount) + : m_Foundation(fnd) + , m_attribLayout(attribLayout) + , m_VertexbufferHandles(buffers) + , m_IndexbufferHandle(indexBuffer) + , m_VaoID(0) + , m_cachedShaderHandle(0) + , m_PatchVertexCount(patchVertexCount) + { + QT3DSU32 *strideMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), + "BackendAttributeLayoutGL:m_strides"); + QT3DSU32 *offsetMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32), + "BackendAttributeLayoutGL:m_strides"); + // copy offsets and strides + QT3DS_FOREACH(idx, strides.size()) + { + strideMem[idx] = strides.mData[idx]; + offsetMem[idx] = offsets.mData[idx]; + } + + m_strides = toDataRef(strideMem, strides.size()); + m_offsets = toDataRef(offsetMem, offsets.size()); + } + ///< destructor + ~NVRenderBackendInputAssemblerGL() + { + QT3DS_FREE(m_Foundation.getAllocator(), m_strides.mData); + QT3DS_FREE(m_Foundation.getAllocator(), m_offsets.mData); + }; + + NVFoundationBase &m_Foundation; ///< pointer to foundation + NVRenderBackendAttributeLayoutGL *m_attribLayout; ///< pointer to attribute layout + NVConstDataRef<NVRenderBackend::NVRenderBackendBufferObject> + m_VertexbufferHandles; ///< opaque vertex buffer backend handles + NVRenderBackend::NVRenderBackendBufferObject + m_IndexbufferHandle; ///< opaque index buffer backend handles + QT3DSU32 m_VaoID; ///< this is only used if GL version is greater or equal 3 + QT3DSU32 m_cachedShaderHandle; ///< this is the shader id which was last used with this object + QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive + NVDataRef<QT3DSU32> m_strides; ///< buffer strides + NVDataRef<QT3DSU32> m_offsets; ///< buffer offsets + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h new file mode 100644 index 00000000..3a74a8e3 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H +#define QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + ///< this class handles the shader input variables + class NVRenderBackendDepthStencilStateGL + { + public: + ///< constructor + NVRenderBackendDepthStencilStateGL(bool enableDepth, bool depthMask, + NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + : m_DepthEnable(enableDepth) + , m_DepthMask(depthMask) + , m_DepthFunc(depthFunc) + , m_StencilEnable(enableStencil) + , m_StencilFuncFront(stencilFuncFront) + , m_StencilFuncBack(stencilFuncBack) + , m_DepthStencilOpFront(depthStencilOpFront) + , m_DepthStencilOpBack(depthStencilOpBack) + { + } + + ///< constructor + NVRenderBackendDepthStencilStateGL() + : m_DepthEnable(true) + , m_DepthMask(true) + , m_DepthFunc(NVRenderBoolOp::LessThanOrEqual) + , m_StencilEnable(false) + { + } + + ///< destructor + ~NVRenderBackendDepthStencilStateGL(){} + + ///< assignement + NVRenderBackendDepthStencilStateGL &operator=(const NVRenderBackendDepthStencilStateGL &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_DepthEnable = rhs.m_DepthEnable; + m_DepthMask = rhs.m_DepthMask; + m_DepthFunc = rhs.m_DepthFunc; + m_StencilEnable = rhs.m_StencilEnable; + m_StencilFuncFront = rhs.m_StencilFuncFront; + m_StencilFuncBack = rhs.m_StencilFuncBack; + m_DepthStencilOpFront = rhs.m_DepthStencilOpFront; + m_DepthStencilOpBack = rhs.m_DepthStencilOpBack; + + return *this; + } + + bool operator==(const NVRenderBackendDepthStencilStateGL &other) const + { + return (m_DepthEnable == other.m_DepthEnable && m_DepthMask == other.m_DepthMask + && m_DepthFunc == other.m_DepthFunc && m_StencilEnable == other.m_StencilEnable + && m_StencilFuncFront == other.m_StencilFuncFront + && m_StencilFuncBack == other.m_StencilFuncBack + && m_DepthStencilOpFront == other.m_DepthStencilOpFront + && m_DepthStencilOpBack == other.m_DepthStencilOpBack); + } + + bool m_DepthEnable; ///< depth test enabled + bool m_DepthMask; ///< enable / disable depth writes + NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func + bool m_StencilEnable; ///< enable disable stencil test + NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup for front faces + NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup for back faces + NVRenderStencilOperationArgument + m_DepthStencilOpFront; ///< depth stencil operation for front faces + NVRenderStencilOperationArgument + m_DepthStencilOpBack; ///< depth stencil operation for back faces + }; + + class NVRenderBackendMiscStateGL + { + public: + ///< constructor + NVRenderBackendMiscStateGL() + : m_PatchVertexCount(1) + { + } + + QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive + }; + + class NVRenderBackendRasterizerStateGL + { + public: + ///< constructor + NVRenderBackendRasterizerStateGL(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + : m_DepthBias(depthBias) + , m_DepthScale(depthScale) + , m_CullFace(cullFace) + { + } + ///< constructor + NVRenderBackendRasterizerStateGL() + : m_DepthBias(0.0) + , m_DepthScale(0.0) + , m_CullFace(NVRenderFaces::Back) + { + } + + NVRenderBackendRasterizerStateGL &operator=(const NVRenderBackendRasterizerStateGL &rhs) + { + // Check for self-assignment! + if (this == &rhs) + return *this; + + m_DepthBias = rhs.m_DepthBias; + m_DepthScale = rhs.m_DepthScale; + m_CullFace = rhs.m_CullFace; + + return *this; + } + + bool operator==(const NVRenderBackendRasterizerStateGL &other) const + { + return (m_DepthBias == other.m_DepthBias && m_DepthScale == other.m_DepthScale + && m_CullFace == other.m_CullFace); + } + + QT3DSF32 m_DepthBias; ///< depth bias + QT3DSF32 m_DepthScale; ///< mulitply constant + NVRenderFaces::Enum m_CullFace; ///< cull face front or back + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h new file mode 100644 index 00000000..f7caffd8 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H +#define QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Utils.h" +#include "render/Qt3DSRenderBaseTypes.h" + +namespace qt3ds { +namespace render { + + struct NVRenderBackendShaderInputEntryGL + { + CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader + QT3DSU32 m_AttribLocation; ///< attribute index + QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT + QT3DSU32 m_NumComponents; ///< component count. max 4 + }; + + ///< this class handles the shader input variables + class NVRenderBackendShaderInputGL + { + public: + ///< constructor + NVRenderBackendShaderInputGL(NVDataRef<NVRenderBackendShaderInputEntryGL> entries) + : m_ShaderInputEntries(entries) + { + } + ///< destructor + ~NVRenderBackendShaderInputGL(){} + + NVRenderBackendShaderInputEntryGL *getEntryByName(CRegisteredString entryName) const + { + QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) + { + if (m_ShaderInputEntries[idx].m_AttribName == entryName) + return &m_ShaderInputEntries.mData[idx]; + } + return NULL; + } + + Option<NVRenderBackendShaderInputEntryGL> + getEntryByAttribLocation(QT3DSU32 attribLocation) const + { + QT3DS_FOREACH(idx, m_ShaderInputEntries.size()) + { + if (m_ShaderInputEntries[idx].m_AttribLocation == attribLocation) + return m_ShaderInputEntries[idx]; + } + return Empty(); + } + + NVDataRef<NVRenderBackendShaderInputEntryGL> m_ShaderInputEntries; ///< shader input entries + }; + + ///< this class represents the internals of a GL program + class NVRenderBackendShaderProgramGL + { + public: + ///< constructor + NVRenderBackendShaderProgramGL(QT3DSU32 programID) + : m_ProgramID(programID) + , m_shaderInput(NULL) + { + } + + ///< destructor + ~NVRenderBackendShaderProgramGL(){} + + QT3DSU32 m_ProgramID; ///< this is the OpenGL object ID + NVRenderBackendShaderInputGL *m_shaderInput; ///< pointer to shader input object + }; +} +} + +#endif diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp new file mode 100644 index 00000000..88670ef7 --- /dev/null +++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSMat44.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Utils.h" +#include "EASTL/set.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace eastl; + +namespace qt3ds { +namespace render { + + NVRenderContext &NVRenderContext::CreateGL(NVFoundationBase &foundation, + IStringTable &inStringTable, + const QSurfaceFormat &format) + { + NVRenderContext *retval = NULL; + + QT3DS_ASSERT(format.majorVersion() >= 2); + + // create backend + NVScopedRefCounted<IStringTable> theStringTable(inStringTable); + NVScopedRefCounted<NVRenderBackend> theBackend; + bool isES = format.renderableType() == QSurfaceFormat::OpenGLES; + if (isES && (format.majorVersion() == 2 + || (format.majorVersion() == 3 && format.minorVersion() == 0))) { + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGLES2Impl)(foundation, + *theStringTable, + format); + } else if (format.majorVersion() == 3 && format.minorVersion() >= 1 && !isES) { + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, + *theStringTable, + format); + } else if (format.majorVersion() == 4 + || (isES && format.majorVersion() == 3 && format.minorVersion() >= 1)) { +#ifdef Q_OS_MACOS + // TODO: macOS crashes with glTextStorage2DMultisample, so fall back to OpenGL3 + // for now (QT3DS-590) + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation, + *theStringTable, + format); +#else + theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL4Impl)(foundation, + *theStringTable, + format); +#endif + } else { + QT3DS_ASSERT(false); + qCCritical(INTERNAL_ERROR) << "Can't find a suitable OpenGL version for" << format; + } + + + retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, + *theStringTable); + + return *retval; + } +} +} diff --git a/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp new file mode 100644 index 00000000..af93e928 --- /dev/null +++ b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp @@ -0,0 +1,588 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "render/backends/software/Qt3DSRenderBackendNULL.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "foundation/Qt3DSAtomic.h" + +#include <QSurfaceFormat> + +using namespace qt3ds::render; +using namespace qt3ds::foundation; +using namespace qt3ds; + +namespace { +struct SNullBackend : public NVRenderBackend +{ + NVFoundationBase &m_Foundation; + QT3DSI32 mRefCount; + + SNullBackend(NVFoundationBase &fnd) + : m_Foundation(fnd) + , mRefCount(0) + { + } + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator()) + + /// backend interface + + NVRenderContextType GetRenderContextType() const override + { + return NVRenderContextValues::NullContext; + } + const char *GetShadingLanguageVersion() override { return ""; } + QT3DSU32 GetMaxCombinedTextureUnits() override { return 32; } + bool GetRenderBackendCap(NVRenderBackendCaps::Enum) const override { return false; } + void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override + { + if (params) { + switch (inQuery) { + case NVRenderBackendQuery::MaxTextureSize: + *params = 4096; + break; + case NVRenderBackendQuery::MaxTextureArrayLayers: + *params = 0; + break; + default: + QT3DS_ASSERT(false); + *params = 0; + break; + } + } + } + QT3DSU32 GetDepthBits() const override { return 16; } + QT3DSU32 GetStencilBits() const override { return 0; } + void SetRenderState(bool, const NVRenderState::Enum) override {} + bool GetRenderState(const NVRenderState::Enum) override { return false; } + virtual NVRenderBackendDepthStencilStateObject + CreateDepthStencilState(bool, bool, NVRenderBoolOp::Enum, bool, + NVRenderStencilFunctionArgument &, NVRenderStencilFunctionArgument &, + NVRenderStencilOperationArgument &, NVRenderStencilOperationArgument &) override + { + return NVRenderBackendDepthStencilStateObject(1); + } + void ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} + NVRenderBackendRasterizerStateObject CreateRasterizerState(QT3DSF32, QT3DSF32, + NVRenderFaces::Enum) override + { + return NVRenderBackendRasterizerStateObject(1); + } + void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject) override {} + void SetDepthStencilState(NVRenderBackendDepthStencilStateObject) override {} + void SetRasterizerState(NVRenderBackendRasterizerStateObject) override {} + NVRenderBoolOp::Enum GetDepthFunc() override { return NVRenderBoolOp::Equal; } + void SetDepthFunc(const NVRenderBoolOp::Enum) override {} + bool GetDepthWrite() override { return false; } + + void SetDepthWrite(bool) override {} + void SetColorWrites(bool, bool, bool, bool) override {} + void SetMultisample(bool) override {} + void GetBlendFunc(NVRenderBlendFunctionArgument *) override {} + void SetBlendFunc(const NVRenderBlendFunctionArgument &) override {} + void SetBlendEquation(const NVRenderBlendEquationArgument &) override {} + void SetBlendBarrier(void) override {} + void GetScissorRect(NVRenderRect *) override {} + void SetScissorRect(const NVRenderRect &) override {} + void GetViewportRect(NVRenderRect *) override {} + void SetViewportRect(const NVRenderRect &) override {} + void SetClearColor(const QT3DSVec4 *) override {} + void Clear(NVRenderClearFlags) override {} + NVRenderBackendBufferObject CreateBuffer(size_t, NVRenderBufferBindFlags, + NVRenderBufferUsageType::Enum, const void *) override + { + return NVRenderBackendBufferObject(1); + } + void BindBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override {} + void ReleaseBuffer(NVRenderBackendBufferObject) override {} + + void UpdateBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, + NVRenderBufferUsageType::Enum, const void *) override + { + } + void UpdateBufferRange(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, + const void *) override + { + } + void *MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t, + NVRenderBufferAccessFlags) override + { + return NULL; + } + bool UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override { return true; } + void SetMemoryBarrier(NVRenderBufferBarrierFlags) override {} + NVRenderBackendQueryObject CreateQuery() override { return NVRenderBackendQueryObject(1); } + void ReleaseQuery(NVRenderBackendQueryObject) override {} + void BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} + void EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {} + void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, + QT3DSU32 *) override {} + void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum, + QT3DSU64 *) override {} + void SetQueryTimer(NVRenderBackendQueryObject) override {} + NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) override + { + return NVRenderBackendSyncObject(1); + }; + void ReleaseSync(NVRenderBackendSyncObject) override {} + void WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, QT3DSU64) override {} + NVRenderBackendRenderTargetObject CreateRenderTarget() override + { + return NVRenderBackendRenderTargetObject(1); + } + void ReleaseRenderTarget(NVRenderBackendRenderTargetObject) override {} + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendRenderbufferObject) override + { + } + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum) override + { + } + void RenderTargetAttach(NVRenderBackendRenderTargetObject, + NVRenderFrameBufferAttachments::Enum, + NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) override + { + } + void SetRenderTarget(NVRenderBackendRenderTargetObject) override {} + bool RenderTargetIsValid(NVRenderBackendRenderTargetObject) override { return false; } + void SetReadTarget(NVRenderBackendRenderTargetObject) override {} + void SetDrawBuffers(NVRenderBackendRenderTargetObject, NVConstDataRef<QT3DSI32>) override {} + void SetReadBuffer(NVRenderBackendRenderTargetObject, NVReadFaces::Enum) override {} + + void BlitFramebuffer(QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, + NVRenderClearFlags, NVRenderTextureMagnifyingOp::Enum) override + { + } + NVRenderBackendRenderbufferObject CreateRenderbuffer(NVRenderRenderBufferFormats::Enum, + size_t, size_t) override + { + return NVRenderBackendRenderbufferObject(1); + } + void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject) override {} + + bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject, + NVRenderRenderBufferFormats::Enum, size_t, size_t) override + { + return false; + } + NVRenderBackendTextureObject CreateTexture() override { return NVRenderBackendTextureObject(1); } + + void SetTextureData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + NVRenderTextureFormats::Enum, const void *) override + { + } + void SetTextureDataCubeFace(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + NVRenderTextureFormats::Enum, const void *) override + { + } + void CreateTextureStorage2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t) override + { + } + void SetTextureSubData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, QT3DSI32, QT3DSI32, size_t, size_t, + NVRenderTextureFormats::Enum, const void *) override + { + } + void SetCompressedTextureData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32, + size_t, const void *) override + { + } + void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, + NVRenderTextureFormats::Enum, size_t, size_t, + QT3DSI32, size_t, const void *) override + { + } + void SetCompressedTextureSubData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, QT3DSU32, QT3DSI32, QT3DSI32, + size_t, size_t, NVRenderTextureFormats::Enum, size_t, + const void *) override + { + } + void SetMultisampledTextureData2D(NVRenderBackendTextureObject, + NVRenderTextureTargetType::Enum, size_t, + NVRenderTextureFormats::Enum, size_t, size_t, bool) override + { + } + void SetTextureData3D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, size_t, + QT3DSI32, NVRenderTextureFormats::Enum, const void *) override + { + } + void GenerateMipMaps(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + NVRenderHint::Enum) override + { + } + void BindTexture(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, QT3DSU32) override + { + } + void BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, QT3DSI32, + NVRenderImageAccessType::Enum, NVRenderTextureFormats::Enum) override + { + } + void ReleaseTexture(NVRenderBackendTextureObject) override {} + + virtual NVRenderTextureSwizzleMode::Enum + GetTextureSwizzleMode(const NVRenderTextureFormats::Enum) const override + { + return NVRenderTextureSwizzleMode::NoSwizzle; + } + + virtual NVRenderBackendSamplerObject + CreateSampler(NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, + NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, + NVRenderTextureCoordOp::Enum, QT3DSI32, QT3DSI32, QT3DSF32, + NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, QT3DSF32, QT3DSF32 *) override + { + return NVRenderBackendSamplerObject(1); + } + + void UpdateSampler(NVRenderBackendSamplerObject, NVRenderTextureTargetType::Enum, + NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum, + NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum, + NVRenderTextureCoordOp::Enum, QT3DSF32, QT3DSF32, QT3DSF32, + NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, + QT3DSF32, QT3DSF32 *) override + { + } + + void UpdateTextureObject(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + QT3DSI32, QT3DSI32) override + { + } + + void UpdateTextureSwizzle(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, + NVRenderTextureSwizzleMode::Enum) override + { + } + + void ReleaseSampler(NVRenderBackendSamplerObject) override {} + + virtual NVRenderBackendAttribLayoutObject + CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry>) override + { + return NVRenderBackendAttribLayoutObject(1); + } + + void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject) override {} + + NVRenderBackendInputAssemblerObject CreateInputAssembler( + NVRenderBackendAttribLayoutObject, NVConstDataRef<NVRenderBackendBufferObject>, + const NVRenderBackendBufferObject, NVConstDataRef<QT3DSU32>, NVConstDataRef<QT3DSU32>, QT3DSU32) override + { + return NVRenderBackendInputAssemblerObject(1); + } + void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject) override {} + bool SetInputAssembler(NVRenderBackendInputAssemblerObject, + NVRenderBackendShaderProgramObject) override + { + return false; + } + void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override {} + NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef<QT3DSI8>, + eastl::string &, bool) override + { + return NVRenderBackendVertexShaderObject(1); + } + void ReleaseVertexShader(NVRenderBackendVertexShaderObject) override {} + NVRenderBackendFragmentShaderObject CreateFragmentShader(NVConstDataRef<QT3DSI8>, + eastl::string &, bool) override + { + return NVRenderBackendFragmentShaderObject(1); + } + void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject) override {} + NVRenderBackendTessControlShaderObject CreateTessControlShader(NVConstDataRef<QT3DSI8>, + eastl::string &, bool) override + { + return NVRenderBackendTessControlShaderObject(1); + } + void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject) override {} + virtual NVRenderBackendTessEvaluationShaderObject + CreateTessEvaluationShader(NVConstDataRef<QT3DSI8>, eastl::string &, bool) override + { + return NVRenderBackendTessEvaluationShaderObject(1); + } + void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject) override {} + NVRenderBackendGeometryShaderObject CreateGeometryShader(NVConstDataRef<QT3DSI8>, + eastl::string &, bool) override + { + return NVRenderBackendGeometryShaderObject(1); + } + void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject) override {} + NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef<QT3DSI8>, + eastl::string &, bool) override + { + return NVRenderBackendComputeShaderObject(1); + } + void ReleaseComputeShader(NVRenderBackendComputeShaderObject) override {} + void AttachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendFragmentShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessControlShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessEvaluationShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendGeometryShaderObject) override + { + } + void AttachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendComputeShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendFragmentShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessControlShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendTessEvaluationShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendGeometryShaderObject) override + { + } + void DetachShader(NVRenderBackendShaderProgramObject, + NVRenderBackendComputeShaderObject) override + { + } + NVRenderBackendShaderProgramObject CreateShaderProgram(bool) override + { + return NVRenderBackendShaderProgramObject(1); + } + void ReleaseShaderProgram(NVRenderBackendShaderProgramObject) override {} + NVRenderBackendProgramPipeline CreateProgramPipeline() override + { + return NVRenderBackendProgramPipeline(1); + } + void ReleaseProgramPipeline(NVRenderBackendProgramPipeline) override {} + + bool LinkProgram(NVRenderBackendShaderProgramObject, eastl::string &) override { return false; } + void SetActiveProgram(NVRenderBackendShaderProgramObject) override {} + void SetActiveProgramPipeline(NVRenderBackendProgramPipeline) override {} + void SetProgramStages(NVRenderBackendProgramPipeline, NVRenderShaderTypeFlags, + NVRenderBackendShaderProgramObject) override {} + void DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSU32) override {} + QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSI32 *, + NVRenderShaderDataTypes::Enum *, QT3DSI32 *, char *) override + { + return 0; + } + + QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return 0; + } + + void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSI32 *) override + { + } + void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject, QT3DSU32, + QT3DSU32 *, QT3DSI32 *, QT3DSI32 *, QT3DSI32 *) override {} + void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32) override {} + void ProgramSetConstantBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject) override { return 0; }; + QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return -1; + } + void ProgramSetStorageBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject) override { return 0; } + QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, + QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override + { + return -1; + }; + void ProgramSetAtomicCounterBuffer(QT3DSU32, NVRenderBackendBufferObject) override {} + + void SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32, + NVRenderShaderDataTypes::Enum, QT3DSI32, const void *, bool) override + { + } + + void Draw(NVRenderDrawMode::Enum, QT3DSU32, QT3DSU32) override {} + void DrawIndirect(NVRenderDrawMode::Enum, const void *) override {} + + void DrawIndexed(NVRenderDrawMode::Enum, QT3DSU32, NVRenderComponentTypes::Enum, + const void *) override + { + } + void DrawIndexedIndirect(NVRenderDrawMode::Enum, NVRenderComponentTypes::Enum, + const void *) override + { + } + + void ReadPixel(NVRenderBackendRenderTargetObject, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, + NVRenderReadPixelFormats::Enum, void *) override + { + } + + NVRenderBackendPathObject CreatePathNVObject(size_t) override + { + return NVRenderBackendPathObject(1); + }; + void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef<QT3DSU8>, + NVConstDataRef<QT3DSF32>) override + { + } + + ///< Bounds of the fill and stroke + NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override + { + return NVBounds3(); + } + + /** + * Defaults to 0 if unset. + */ + void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {} + void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {} + void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {} + + void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {} + void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {} + void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {} + void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {} + void ReleasePathNVObject(NVRenderBackendPathObject, size_t) override {} + + void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, QT3DSF32) override + { + } + virtual NVRenderPathReturnValues::Enum + LoadPathGlyphsIndexed(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *, + NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, + QT3DSF32) override + { + return NVRenderPathReturnValues::FontUnavailable; + } + NVRenderBackendPathObject LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, + const void *, + NVRenderPathFontStyleFlags, + NVRenderBackendPathObject, QT3DSF32, + QT3DSU32 *) override + { + return NVRenderBackendPathObject(1); + } + void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, + const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t, + NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, + QT3DSF32) override + { + } + void GetPathMetrics(NVRenderBackendPathObject, size_t, NVRenderPathGlyphFontMetricFlags, + NVRenderPathFormatType::Enum, const void *, size_t, QT3DSF32 *) override + { + } + void GetPathMetricsRange(NVRenderBackendPathObject, size_t, + NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override + { + } + void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum, + NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32, + NVRenderPathTransformType::Enum, QT3DSF32 *) override + { + } + + void StencilFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathFillMode::Enum, QT3DSU32, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, QT3DSI32, + QT3DSU32, NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void CoverFillPathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t, + NVRenderPathFormatType::Enum, const void *, + NVRenderPathCoverMode::Enum, + NVRenderPathTransformType::Enum, const QT3DSF32 *) override + { + } + QSurfaceFormat format() const override + { + return QSurfaceFormat(); + } +}; +} + +NVRenderBackend &NVRenderBackendNULL::CreateBackend(NVFoundationBase &foundation) +{ + return *QT3DS_NEW(foundation.getAllocator(), SNullBackend)(foundation); +} diff --git a/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h new file mode 100644 index 00000000..397ecfb1 --- /dev/null +++ b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_BACKEND_NULL_H +#define QT3DS_RENDER_BACKEND_NULL_H +#include "render/backends/Qt3DSRenderBackend.h" + +namespace qt3ds { +namespace render { + + class NVRenderBackendNULL : public NVRenderBackend + { + public: + static NVRenderBackend &CreateBackend(NVFoundationBase &foundation); + }; +} +} + +#endif
\ No newline at end of file diff --git a/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h b/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h new file mode 100644 index 00000000..28f246fd --- /dev/null +++ b/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_GL_IMPL_OBJECTS_H +#define QT3DS_RENDER_GL_IMPL_OBJECTS_H +#include "render/backends/gl/Qt3DSOpenGLUtil.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "foundation/StringTable.h" +#include "foundation/Qt3DSContainers.h" + +namespace qt3ds { +namespace render { + + // The set of all properties as they are currently set in hardware. + struct SNVGLHardPropertyContext + { + NVRenderFrameBuffer *m_FrameBuffer; + NVRenderShaderProgram *m_ActiveShader; + NVRenderProgramPipeline *m_ActiveProgramPipeline; + NVRenderInputAssembler *m_InputAssembler; + NVRenderBlendFunctionArgument m_BlendFunction; + NVRenderBlendEquationArgument m_BlendEquation; + bool m_CullingEnabled; + NVRenderBoolOp::Enum m_DepthFunction; + bool m_BlendingEnabled; + bool m_DepthWriteEnabled; + bool m_DepthTestEnabled; + bool m_StencilTestEnabled; + bool m_ScissorTestEnabled; + bool m_ColorWritesEnabled; + bool m_MultisampleEnabled; + NVRenderRect m_ScissorRect; + NVRenderRect m_Viewport; + QT3DSVec4 m_ClearColor; + + SNVGLHardPropertyContext() + : m_FrameBuffer(NULL) + , m_ActiveShader(NULL) + , m_ActiveProgramPipeline(NULL) + , m_InputAssembler(NULL) + , m_CullingEnabled(true) + , m_DepthFunction(NVRenderBoolOp::Less) + , m_BlendingEnabled(true) + , m_DepthWriteEnabled(true) + , m_DepthTestEnabled(true) + , m_StencilTestEnabled(false) + , m_ScissorTestEnabled(true) + , m_ColorWritesEnabled(true) + , m_MultisampleEnabled(false) + , m_ClearColor(0, 0, 0, 1) + { + } + }; +} +} +#endif |