/****************************************************************************
**
** Copyright (C) 2008-2012 NVIDIA Corporation.
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Quick 3D.
**
** $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 <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendererimpl_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderlayer_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderresourcemanager_p.h>
#include <QtQuick3DRender/private/qssgrenderframebuffer_p.h>
#include <QtQuick3DRender/private/qssgrenderrenderbuffer_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderresourcebufferobjects_p.h>
#include <QtQuick3DUtils/private/qssgperftimer_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendercustommaterialsystem_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendererutil_p.h>
#include <QtQuick3DUtils/private/qssgutils_p.h>

namespace {
const float QSSG_PI = float(M_PI);
const float QSSG_HALFPI = float(M_PI_2);
}

QT_BEGIN_NAMESPACE

QSSGLayerRenderData::QSSGLayerRenderData(QSSGRenderLayer &inLayer, const QSSGRef<QSSGRendererImpl> &inRenderer)
    : QSSGLayerRenderPreparationData(inLayer, inRenderer)
    , m_layerTexture(inRenderer->contextInterface()->resourceManager())
    , m_temporalAATexture(inRenderer->contextInterface()->resourceManager())
    , m_prevTemporalAATexture(inRenderer->contextInterface()->resourceManager())
    , m_layerDepthTexture(inRenderer->contextInterface()->resourceManager())
    , m_layerPrepassDepthTexture(inRenderer->contextInterface()->resourceManager())
    , m_layerSsaoTexture(inRenderer->contextInterface()->resourceManager())
    , m_layerMultisampleTexture(inRenderer->contextInterface()->resourceManager())
    , m_layerMultisamplePrepassDepthTexture(inRenderer->contextInterface()->resourceManager())
    , m_layerMultisampleWidgetTexture(inRenderer->contextInterface()->resourceManager())
    , m_progressiveAAPassIndex(0)
    , m_temporalAAPassIndex(0)
    , m_nonDirtyTemporalAAPassIndex(0)
    , m_textScale(1.0f)
    , m_depthBufferFormat(QSSGRenderTextureFormat::Unknown)
{
}

QSSGLayerRenderData::~QSSGLayerRenderData()
{
}

void QSSGLayerRenderData::prepareForRender(const QSize &inViewportDimensions)
{
    QSSGLayerRenderPreparationData::prepareForRender(inViewportDimensions);
    QSSGLayerRenderPreparationResult &thePrepResult(*layerPrepResult);
    const QSSGRef<QSSGResourceManager> &theResourceManager(renderer->contextInterface()->resourceManager());
    // at that time all values shoud be updated
    renderer->updateCbAoShadow(&layer, camera, m_layerDepthTexture);

    // Generate all necessary lighting keys

    if (thePrepResult.flags.wasLayerDataDirty()) {
        m_progressiveAAPassIndex = 0;
    }

    // Get rid of the layer texture if we aren't rendering to texture this frame.
    if (m_layerTexture.getTexture()) {
        m_layerTexture.releaseTexture();
        m_layerDepthTexture.releaseTexture();
        m_layerSsaoTexture.releaseTexture();
        m_layerMultisampleTexture.releaseTexture();
        m_layerMultisamplePrepassDepthTexture.releaseTexture();
        m_layerMultisampleWidgetTexture.releaseTexture();
    }

    if (m_layerDepthTexture.getTexture() && !thePrepResult.flags.requiresDepthTexture())
        m_layerDepthTexture.releaseTexture();

    if (m_layerSsaoTexture.getTexture() && !thePrepResult.flags.requiresSsaoPass())
        m_layerSsaoTexture.releaseTexture();

    renderer->layerNeedsFrameClear(*this);

    // Clean up the texture cache if layer dimensions changed
    if (inViewportDimensions.width() != m_previousDimensions.width()
            || inViewportDimensions.height() != m_previousDimensions.height()) {
        m_layerTexture.releaseTexture();
        m_layerDepthTexture.releaseTexture();
        m_layerSsaoTexture.releaseTexture();
        m_layerPrepassDepthTexture.releaseTexture();
        m_temporalAATexture.releaseTexture();
        m_layerMultisampleTexture.releaseTexture();
        m_layerMultisamplePrepassDepthTexture.releaseTexture();
        m_layerMultisampleWidgetTexture.releaseTexture();

        m_previousDimensions.setWidth(inViewportDimensions.width());
        m_previousDimensions.setHeight(inViewportDimensions.height());

        theResourceManager->destroyFreeSizedResources();
    }
}

QSSGRenderTextureFormat QSSGLayerRenderData::getDepthBufferFormat()
{
    if (m_depthBufferFormat == QSSGRenderTextureFormat::Unknown) {
        quint32 theExistingDepthBits = renderer->context()->depthBits();
        quint32 theExistingStencilBits = renderer->context()->stencilBits();
        switch (theExistingDepthBits) {
        case 32:
            m_depthBufferFormat = QSSGRenderTextureFormat::Depth32;
            break;
        case 24:
            //  check if we have stencil bits
            if (theExistingStencilBits > 0)
                m_depthBufferFormat = QSSGRenderTextureFormat::Depth24Stencil8; // currently no stencil usage
            // should be Depth24Stencil8 in
            // this case
            else
                m_depthBufferFormat = QSSGRenderTextureFormat::Depth24;
            break;
        case 16:
            m_depthBufferFormat = QSSGRenderTextureFormat::Depth16;
            break;
        default:
            Q_ASSERT(false);
            m_depthBufferFormat = QSSGRenderTextureFormat::Depth16;
            break;
        }
    }
    return m_depthBufferFormat;
}

QSSGRenderFrameBufferAttachment QSSGLayerRenderData::getFramebufferDepthAttachmentFormat(QSSGRenderTextureFormat depthFormat)
{
    QSSGRenderFrameBufferAttachment fmt = QSSGRenderFrameBufferAttachment::Depth;

    switch (depthFormat.format) {
    case QSSGRenderTextureFormat::Depth16:
    case QSSGRenderTextureFormat::Depth24:
    case QSSGRenderTextureFormat::Depth32:
        fmt = QSSGRenderFrameBufferAttachment::Depth;
        break;
    case QSSGRenderTextureFormat::Depth24Stencil8:
        fmt = QSSGRenderFrameBufferAttachment::DepthStencil;
        break;
    default:
        Q_ASSERT(false);
        break;
    }

    return fmt;
}

void QSSGLayerRenderData::renderClearPass()
{
    QSSGStackPerfTimer ___timer(renderer->contextInterface()->performanceTimer(), Q_FUNC_INFO);
    if (camera == nullptr)
        return;

    renderer->beginLayerRender(*this);

    const auto &theContext = renderer->context();
    if (layer.background == QSSGRenderLayer::Background::SkyBox) {
        theContext->setDepthTestEnabled(false); // Draw to every pixel
        theContext->setDepthWriteEnabled(false); // Depth will be cleared in a separate step
        QSSGRef<QSSGSkyBoxShader> shader = renderer->getSkyBoxShader();
        theContext->setActiveShader(shader->shader);
        // Setup constants
        shader->projection.set(camera->projection);
        shader->viewMatrix.set(camera->globalTransform);
        shader->skyboxTexture.set(layer.lightProbe->m_textureData.m_texture.data());
        renderer->renderQuad();
    }

    QSSGRenderClearFlags clearFlags = 0;
    if (!layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthPrePass)) {
        clearFlags |= QSSGRenderClearValues::Depth;
        clearFlags |= QSSGRenderClearValues::Stencil;
        // Enable depth write for the clear below
        theContext->setDepthWriteEnabled(true);
    }

    if (layer.background == QSSGRenderLayer::Background::SkyBox) {
        theContext->clear(clearFlags);
    } else if (layer.background == QSSGRenderLayer::Background::Color) {
        clearFlags |= QSSGRenderClearValues::Color;
        QSSGRenderContextScopedProperty<QVector4D> __clearColor(*theContext,
                                                                  &QSSGRenderContext::clearColor,
                                                                  &QSSGRenderContext::setClearColor,
                                                                  QVector4D(layer.clearColor, 1.0f));
        theContext->clear(clearFlags);
    } else {
        if (clearFlags || layerPrepResult->flags.requiresTransparentClear()) {
            if (layerPrepResult->flags.requiresTransparentClear())
                clearFlags |= QSSGRenderClearValues::Color;
            QSSGRenderContextScopedProperty<QVector4D> __clearColor(*theContext,
                                                                      &QSSGRenderContext::clearColor,
                                                                      &QSSGRenderContext::setClearColor,
                                                                      QVector4D(0.0, 0.0, 0.0, 0.0f));
            theContext->clear(clearFlags);
        }
    }
    renderer->endLayerRender();
}

void QSSGLayerRenderData::renderAoPass()
{
    renderer->beginLayerDepthPassRender(*this);

    const auto &theContext = renderer->context();
    QSSGRef<QSSGDefaultAoPassShader> shader = renderer->getDefaultAoPassShader(getShaderFeatureSet());
    if (shader == nullptr)
        return;

    // Set initial state
    theContext->setBlendingEnabled(false);
    theContext->setDepthWriteEnabled(false);
    theContext->setDepthTestEnabled(false);
    theContext->setActiveShader(shader->shader);

    // Setup constants
    shader->cameraDirection.set(cameraDirection);
    shader->viewMatrix.set(camera->globalTransform);

    shader->depthTexture.set(m_layerDepthTexture.getTexture().data());
    shader->depthTextureSize.set(
                QVector2D(m_layerDepthTexture->textureDetails().width, m_layerDepthTexture->textureDetails().height));

    // Important uniforms for AO calculations
    QVector2D theCameraProps = QVector2D(camera->clipNear, camera->clipFar);
    shader->cameraProperties.set(theCameraProps);
    shader->aoShadowParams.set();

    // Draw a fullscreen quad
    renderer->renderQuad();

    renderer->endLayerDepthPassRender();
}

void QSSGLayerRenderData::renderFakeDepthMapPass(QSSGRenderTexture2D *theDepthTex, QSSGRenderTextureCube *theDepthCube)
{
    renderer->beginLayerDepthPassRender(*this);

    const auto &theContext = renderer->context();
    QSSGRef<QSSGDefaultAoPassShader> shader = theDepthTex ? renderer->getFakeDepthShader(getShaderFeatureSet())
                                                              : renderer->getFakeCubeDepthShader(getShaderFeatureSet());
    if (shader == nullptr)
        return;

    // Set initial state
    theContext->setBlendingEnabled(false);
    theContext->setDepthWriteEnabled(false);
    theContext->setDepthTestEnabled(false);
    theContext->setActiveShader(shader->shader);

    // Setup constants
    shader->cameraDirection.set(cameraDirection);
    shader->viewMatrix.set(camera->globalTransform);

    shader->depthTexture.set(theDepthTex);
    shader->cubeTexture.set(theDepthCube);
    shader->depthTextureSize.set(QVector2D(theDepthTex->textureDetails().width, theDepthTex->textureDetails().height));

    // Important uniforms for AO calculations
    QVector2D theCameraProps = QVector2D(camera->clipNear, camera->clipFar);
    shader->cameraProperties.set(theCameraProps);
    shader->aoShadowParams.set();

    // Draw a fullscreen quad
    renderer->renderQuad();
}

namespace {

void computeFrustumBounds(const QSSGRenderCamera &inCamera, const QRectF &inViewPort, QVector3D &ctrBound, QVector3D camVerts[8])
{
    QVector3D camEdges[4];

    const float *dataPtr(inCamera.globalTransform.constData());
    QVector3D camX(dataPtr[0], dataPtr[1], dataPtr[2]);
    QVector3D camY(dataPtr[4], dataPtr[5], dataPtr[6]);
    QVector3D camZ(dataPtr[8], dataPtr[9], dataPtr[10]);

    float tanFOV = tanf(inCamera.verticalFov(inViewPort) * 0.5f);
    float asTanFOV = tanFOV * inViewPort.width() / inViewPort.height();
    camEdges[0] = -asTanFOV * camX + tanFOV * camY + camZ;
    camEdges[1] = asTanFOV * camX + tanFOV * camY + camZ;
    camEdges[2] = asTanFOV * camX - tanFOV * camY + camZ;
    camEdges[3] = -asTanFOV * camX - tanFOV * camY + camZ;

    for (int i = 0; i < 4; ++i) {
        camEdges[i].setX(-camEdges[i].x());
        camEdges[i].setY(-camEdges[i].y());
    }

    camVerts[0] = inCamera.position + camEdges[0] * inCamera.clipNear;
    camVerts[1] = inCamera.position + camEdges[0] * inCamera.clipFar;
    camVerts[2] = inCamera.position + camEdges[1] * inCamera.clipNear;
    camVerts[3] = inCamera.position + camEdges[1] * inCamera.clipFar;
    camVerts[4] = inCamera.position + camEdges[2] * inCamera.clipNear;
    camVerts[5] = inCamera.position + camEdges[2] * inCamera.clipFar;
    camVerts[6] = inCamera.position + camEdges[3] * inCamera.clipNear;
    camVerts[7] = inCamera.position + camEdges[3] * inCamera.clipFar;

    ctrBound = camVerts[0];
    for (int i = 1; i < 8; ++i) {
        ctrBound += camVerts[i];
    }
    ctrBound *= 0.125f;
}

void setupCameraForShadowMap(const QVector2D &/*inCameraVec*/,
                             QSSGRenderContext & /*inContext*/,
                             const QRectF &inViewport,
                             const QSSGRenderCamera &inCamera,
                             const QSSGRenderLight *inLight,
                             QSSGRenderCamera &theCamera)
{
    // setup light matrix
    quint32 mapRes = 1 << inLight->m_shadowMapRes;
    QRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes);
    theCamera.clipNear = 1.0f;
    theCamera.clipFar = inLight->m_shadowMapFar;
    // Setup camera projection
    QVector3D inLightPos = inLight->getGlobalPos();
    QVector3D inLightDir = inLight->getDirection();

    if (inLight->flags.testFlag(QSSGRenderLight::Flag::LeftHanded))
        inLightPos.setZ(-inLightPos.z());

    inLightPos -= inLightDir * inCamera.clipNear;
    theCamera.fov = qDegreesToRadians(90.f);

    if (inLight->m_lightType == QSSGRenderLight::Type::Directional) {
        QVector3D frustBounds[8], boundCtr;
        computeFrustumBounds(inCamera, inViewport, boundCtr, frustBounds);

        QVector3D forward = inLightDir;
        forward.normalize();
        QVector3D right;
        if (!qFuzzyCompare(qAbs(forward.y()), 1.0f))
            right = QVector3D::crossProduct(forward, QVector3D(0, 1, 0));
        else
            right = QVector3D::crossProduct(forward, QVector3D(1, 0, 0));
        right.normalize();
        QVector3D up = QVector3D::crossProduct(right, forward);
        up.normalize();

        // Calculate bounding box of the scene camera frustum
        float minDistanceZ = std::numeric_limits<float>::max();
        float maxDistanceZ = -std::numeric_limits<float>::max();
        float minDistanceY = std::numeric_limits<float>::max();
        float maxDistanceY = -std::numeric_limits<float>::max();
        float minDistanceX = std::numeric_limits<float>::max();
        float maxDistanceX = -std::numeric_limits<float>::max();
        for (int i = 0; i < 8; ++i) {
            float distanceZ = QVector3D::dotProduct(frustBounds[i], forward);
            if (distanceZ < minDistanceZ)
                minDistanceZ = distanceZ;
            if (distanceZ > maxDistanceZ)
                maxDistanceZ = distanceZ;
            float distanceY = QVector3D::dotProduct(frustBounds[i], up);
            if (distanceY < minDistanceY)
                minDistanceY = distanceY;
            if (distanceY > maxDistanceY)
                maxDistanceY = distanceY;
            float distanceX = QVector3D::dotProduct(frustBounds[i], right);
            if (distanceX < minDistanceX)
                minDistanceX = distanceX;
            if (distanceX > maxDistanceX)
                maxDistanceX = distanceX;
        }

        // Apply bounding box parameters to shadow map camera projection matrix
        // so that the whole scene is fit inside the shadow map
        inLightPos = boundCtr;
        theViewport.setHeight(std::abs(maxDistanceY - minDistanceY));
        theViewport.setWidth(std::abs(maxDistanceX - minDistanceX));
        theCamera.clipNear = -std::abs(maxDistanceZ - minDistanceZ);
        theCamera.clipFar = std::abs(maxDistanceZ - minDistanceZ);
    }

    theCamera.flags.setFlag(QSSGRenderCamera::Flag::LeftHanded, false);

    theCamera.flags.setFlag(QSSGRenderCamera::Flag::Orthographic, inLight->m_lightType == QSSGRenderLight::Type::Directional);
    theCamera.parent = nullptr;
    theCamera.pivot = inLight->pivot;

    if (inLight->m_lightType != QSSGRenderLight::Type::Point) {
        theCamera.lookAt(inLightPos, QVector3D(0, 1.0, 0), inLightPos + inLightDir);
    } else {
        theCamera.lookAt(inLightPos, QVector3D(0, 1.0, 0), QVector3D(0, 0, 0));
    }

    theCamera.calculateGlobalVariables(theViewport);
}
}

void setupCubeShadowCameras(const QSSGRenderLight *inLight, QSSGRenderCamera inCameras[6])
{
    // setup light matrix
    quint32 mapRes = 1 << inLight->m_shadowMapRes;
    QRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes);
    QVector3D rotOfs[6];

    Q_ASSERT(inLight != nullptr);
    Q_ASSERT(inLight->m_lightType != QSSGRenderLight::Type::Directional);

    QVector3D inLightPos = inLight->getGlobalPos();
    if (inLight->flags.testFlag(QSSGRenderLight::Flag::LeftHanded))
        inLightPos.setZ(-inLightPos.z());

    rotOfs[0] = QVector3D(0.f, -QSSG_HALFPI, QSSG_PI);
    rotOfs[1] = QVector3D(0.f, QSSG_HALFPI, QSSG_PI);
    rotOfs[2] = QVector3D(QSSG_HALFPI, 0.f, 0.f);
    rotOfs[3] = QVector3D(-QSSG_HALFPI, 0.f, 0.f);
    rotOfs[4] = QVector3D(0.f, QSSG_PI, -QSSG_PI);
    rotOfs[5] = QVector3D(0.f, 0.f, QSSG_PI);

    for (int i = 0; i < 6; ++i) {
        inCameras[i].flags.setFlag(QSSGRenderCamera::Flag::LeftHanded, false);

        inCameras[i].flags.setFlag(QSSGRenderCamera::Flag::Orthographic, false);
        inCameras[i].parent = nullptr;
        inCameras[i].pivot = inLight->pivot;
        inCameras[i].clipNear = 1.0f;
        inCameras[i].clipFar = qMax<float>(2.0f, inLight->m_shadowMapFar);
        inCameras[i].fov = qDegreesToRadians(90.f);

        inCameras[i].position = inLightPos;
        inCameras[i].rotation = rotOfs[i];
        inCameras[i].calculateGlobalVariables(theViewport);
    }

    /*
        if ( inLight->m_LightType == RenderLightTypes::Point ) return;

        QVector3D viewDirs[6];
        QVector3D viewUp[6];
        QMatrix3x3 theDirMatrix( inLight->m_GlobalTransform.getUpper3x3() );

        viewDirs[0] = theDirMatrix.transform( QVector3D( 1.f, 0.f, 0.f ) );
        viewDirs[2] = theDirMatrix.transform( QVector3D( 0.f, -1.f, 0.f ) );
        viewDirs[4] = theDirMatrix.transform( QVector3D( 0.f, 0.f, 1.f ) );
        viewDirs[0].normalize();  viewDirs[2].normalize();  viewDirs[4].normalize();
        viewDirs[1] = -viewDirs[0];
        viewDirs[3] = -viewDirs[2];
        viewDirs[5] = -viewDirs[4];

        viewUp[0] = viewDirs[2];
        viewUp[1] = viewDirs[2];
        viewUp[2] = viewDirs[5];
        viewUp[3] = viewDirs[4];
        viewUp[4] = viewDirs[2];
        viewUp[5] = viewDirs[2];

        for (int i = 0; i < 6; ++i)
        {
                inCameras[i].LookAt( inLightPos, viewUp[i], inLightPos + viewDirs[i] );
                inCameras[i].CalculateGlobalVariables( theViewport, QVector2D( theViewport.m_Width,
        theViewport.m_Height ) );
        }
        */
}

inline void renderRenderableShadowMapPass(QSSGLayerRenderData &inData,
                                          QSSGRenderableObject &inObject,
                                          const QVector2D &inCameraProps,
                                          const ShaderFeatureSetList &,
                                          quint32 lightIndex,
                                          const QSSGRenderCamera &inCamera)
{
    QSSGShadowMapEntry *pEntry = inData.shadowMapManager->getShadowMapEntry(lightIndex);

    // If the object is marked that it doesn't cast shadows, then skip it.
    if (!inObject.renderableFlags.castsShadows())
        return;

    if (inObject.renderableFlags.isDefaultMaterialMeshSubset())
        static_cast<QSSGSubsetRenderableBase &>(inObject).renderShadowMapPass(inCameraProps, inData.globalLights[lightIndex], inCamera, pEntry);
    else if (inObject.renderableFlags.isCustomMaterialMeshSubset())
        static_cast<QSSGSubsetRenderableBase &>(inObject).renderShadowMapPass(inCameraProps, inData.globalLights[lightIndex], inCamera, pEntry);
}

void QSSGLayerRenderData::renderShadowCubeBlurPass(QSSGResourceFrameBuffer *theFB,
                                                     const QSSGRef<QSSGRenderTextureCube> &target0,
                                                     const QSSGRef<QSSGRenderTextureCube> &target1,
                                                     float filterSz,
                                                     float clipFar)
{
    const auto &theContext = renderer->context();

    QSSGRef<QSSGShadowmapPreblurShader> shaderX = renderer->getCubeShadowBlurXShader();
    QSSGRef<QSSGShadowmapPreblurShader> shaderY = renderer->getCubeShadowBlurYShader();

    if (shaderX == nullptr)
        return;
    if (shaderY == nullptr)
        return;
    // if ( theShader == nullptr ) return;

    // Enable drawing to 6 color attachment buffers for cubemap passes
    qint32 buffers[6] = { 0, 1, 2, 3, 4, 5 };
    QSSGDataView<qint32> bufferList(buffers, 6);
    theContext->setDrawBuffers(bufferList);

    // Attach framebuffer targets
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color0, target1, QSSGRenderTextureCubeFace::CubePosX);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color1, target1, QSSGRenderTextureCubeFace::CubeNegX);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color2, target1, QSSGRenderTextureCubeFace::CubePosY);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color3, target1, QSSGRenderTextureCubeFace::CubeNegY);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color4, target1, QSSGRenderTextureCubeFace::CubePosZ);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color5, target1, QSSGRenderTextureCubeFace::CubeNegZ);

    // Set initial state
    theContext->setBlendingEnabled(false);
    theContext->setDepthWriteEnabled(false);
    theContext->setDepthTestEnabled(false);
    // theContext.SetColorWritesEnabled(true);
    theContext->setActiveShader(shaderX->shader);

    shaderX->cameraProperties.set(QVector2D(filterSz, clipFar));
    shaderX->depthCube.set(target0.data());

    // Draw a fullscreen quad
    renderer->renderQuad();

    theContext->setActiveShader(shaderY->shader);

    // Lather, Rinse, and Repeat for the Y-blur pass
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color0, target0, QSSGRenderTextureCubeFace::CubePosX);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color1, target0, QSSGRenderTextureCubeFace::CubeNegX);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color2, target0, QSSGRenderTextureCubeFace::CubePosY);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color3, target0, QSSGRenderTextureCubeFace::CubeNegY);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color4, target0, QSSGRenderTextureCubeFace::CubePosZ);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color5, target0, QSSGRenderTextureCubeFace::CubeNegZ);

    shaderY->cameraProperties.set(QVector2D(filterSz, clipFar));
    shaderY->depthCube.set(target1.data());

    // Draw a fullscreen quad
    renderer->renderQuad();

    theContext->setDepthWriteEnabled(true);
    theContext->setDepthTestEnabled(true);
    // theContext.SetColorWritesEnabled(false);

    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color0,
                         QSSGRenderTextureOrRenderBuffer(),
                         QSSGRenderTextureCubeFace::CubePosX);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color1,
                         QSSGRenderTextureOrRenderBuffer(),
                         QSSGRenderTextureCubeFace::CubeNegX);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color2,
                         QSSGRenderTextureOrRenderBuffer(),
                         QSSGRenderTextureCubeFace::CubePosY);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color3,
                         QSSGRenderTextureOrRenderBuffer(),
                         QSSGRenderTextureCubeFace::CubeNegY);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color4,
                         QSSGRenderTextureOrRenderBuffer(),
                         QSSGRenderTextureCubeFace::CubePosZ);
    (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color5,
                         QSSGRenderTextureOrRenderBuffer(),
                         QSSGRenderTextureCubeFace::CubeNegZ);

    qint32 null = 0;
    theContext->setDrawBuffers(toDataView(null));
}

void QSSGLayerRenderData::renderShadowMapBlurPass(QSSGResourceFrameBuffer *theFB,
                                                    const QSSGRef<QSSGRenderTexture2D> &target0,
                                                    const QSSGRef<QSSGRenderTexture2D> &target1,
                                                    float filterSz,
                                                    float clipFar)
{
    const auto &theContext = renderer->context();

    QSSGRef<QSSGShadowmapPreblurShader> shaderX = renderer->getOrthoShadowBlurXShader();
    QSSGRef<QSSGShadowmapPreblurShader> shaderY = renderer->getOrthoShadowBlurYShader();

    if (shaderX == nullptr)
        return;
    if (shaderY == nullptr)
        return;

    // Attach framebuffer target
    (*theFB)->attach(QSSGRenderFrameBufferAttachment::Color0, target1);
    //(*theFB)->Attach( QSSGRenderFrameBufferAttachments::DepthStencil, *target1 );

    // Set initial state
    theContext->setBlendingEnabled(false);
    theContext->setDepthWriteEnabled(false);
    theContext->setDepthTestEnabled(false);
    theContext->setColorWritesEnabled(true);
    theContext->setActiveShader(shaderX->shader);

    shaderX->cameraProperties.set(QVector2D(filterSz, clipFar));
    shaderX->depthMap.set(target0.data());

    // Draw a fullscreen quad
    renderer->renderQuad();

    (*theFB)->attach(QSSGRenderFrameBufferAttachment::Color0, target0);
    //(*theFB)->Attach( QSSGRenderFrameBufferAttachments::DepthStencil, *target0 );
    theContext->setActiveShader(shaderY->shader);

    shaderY->cameraProperties.set(QVector2D(filterSz, clipFar));
    shaderY->depthMap.set(target1.data());

    // Draw a fullscreen quad
    renderer->renderQuad();

    theContext->setDepthWriteEnabled(true);
    theContext->setDepthTestEnabled(true);
    theContext->setColorWritesEnabled(false);

    //(*theFB)->Attach( QSSGRenderFrameBufferAttachments::DepthStencil,
    // QSSGRenderTextureOrRenderBuffer() );
    (*theFB)->attach(QSSGRenderFrameBufferAttachment::Color0, QSSGRenderTextureOrRenderBuffer());
}

void QSSGLayerRenderData::renderShadowMapPass(QSSGResourceFrameBuffer *theFB)
{
    QSSGStackPerfTimer ___timer(renderer->contextInterface()->performanceTimer(), Q_FUNC_INFO);

    if (!camera)
        return;

    if (!shadowMapManager)
        createShadowMapManager();

    // Check if we have anything to render
    if (opaqueObjects.size() == 0 || globalLights.size() == 0)
        return;

    renderer->beginLayerDepthPassRender(*this);

    const auto &theRenderContext = renderer->context();

    // we may change the viewport
    QSSGRenderContextScopedProperty<QRect> __viewport(*theRenderContext, &QSSGRenderContext::viewport, &QSSGRenderContext::setViewport);

    // disable color writes
    // theRenderContext.SetColorWritesEnabled( false );
    theRenderContext->setColorWritesEnabled(true);
    theRenderContext->setDepthWriteEnabled(true);
    theRenderContext->setCullingEnabled(false);
    theRenderContext->setClearColor(QVector4D(1.0, 1.0, 1.0, 1.0));

    // we render the shadow map with a slight offset to prevent shadow acne and cull the front
    // faces
    QSSGRef<QSSGRenderRasterizerState> rsdefaultstate = new QSSGRenderRasterizerState(theRenderContext, 0.0, 0.0);
    QSSGRef<QSSGRenderRasterizerState> rsstate = new QSSGRenderRasterizerState(theRenderContext, 1.5, 2.0);
    theRenderContext->setRasterizerState(rsstate);

    QSSGRenderClearFlags clearFlags(QSSGRenderClearValues::Depth | QSSGRenderClearValues::Stencil
                                      | QSSGRenderClearValues::Color);

    for (int i = 0; i < globalLights.size(); i++) {
        // don't render shadows when not casting
        if (globalLights[i]->m_castShadow == false)
            continue;
        QSSGShadowMapEntry *pEntry = shadowMapManager->getShadowMapEntry(i);
        if (pEntry && pEntry->m_depthMap && pEntry->m_depthCopy && pEntry->m_depthRender) {
            QSSGRenderCamera theCamera;

            QVector2D theCameraProps = QVector2D(camera->clipNear, camera->clipFar);
            setupCameraForShadowMap(theCameraProps, *renderer->context(), __viewport.m_initialValue, *camera, globalLights[i], theCamera);
            // we need this matrix for the final rendering
            theCamera.calculateViewProjectionMatrix(pEntry->m_lightVP);
            pEntry->m_lightView = theCamera.globalTransform.inverted();

            QSSGTextureDetails theDetails(pEntry->m_depthMap->textureDetails());
            theRenderContext->setViewport(QRect(0, 0, (quint32)theDetails.width, (quint32)theDetails.height));

            (*theFB)->attach(QSSGRenderFrameBufferAttachment::Color0, pEntry->m_depthMap);
            (*theFB)->attach(QSSGRenderFrameBufferAttachment::DepthStencil, pEntry->m_depthRender);
            theRenderContext->clear(clearFlags);

            runRenderPass(renderRenderableShadowMapPass, false, true, true, true, i, theCamera);
            renderShadowMapBlurPass(theFB, pEntry->m_depthMap, pEntry->m_depthCopy, globalLights[i]->m_shadowFilter, globalLights[i]->m_shadowMapFar);
        } else if (pEntry && pEntry->m_depthCube && pEntry->m_cubeCopy && pEntry->m_depthRender) {
            QSSGRenderCamera theCameras[6];

            setupCubeShadowCameras(globalLights[i], theCameras);

            // pEntry->m_LightView = m_Lights[i]->m_LightType == RenderLightTypes::Point ?
            // QMatrix4x4::createIdentity()
            //	: m_Lights[i]->m_GlobalTransform;
            pEntry->m_lightView = QMatrix4x4();

            QSSGTextureDetails theDetails(pEntry->m_depthCube->textureDetails());
            theRenderContext->setViewport(QRect(0, 0, (quint32)theDetails.width, (quint32)theDetails.height));

            // int passes = m_Lights[i]->m_LightType == RenderLightTypes::Point ? 6 : 5;
            int passes = 6;
            for (int k = 0; k < passes; ++k) {
                // theCameras[k].CalculateViewProjectionMatrix( pEntry->m_LightCubeVP[k] );
                pEntry->m_lightCubeView[k] = theCameras[k].globalTransform.inverted();
                theCameras[k].calculateViewProjectionMatrix(pEntry->m_lightVP);

                // Geometry shader multiplication really doesn't work unless you have a
                // 6-layered 3D depth texture...
                // Otherwise, you have no way to depth test while rendering...
                // which more or less completely defeats the purpose of having a cubemap render
                // target.
                QSSGRenderTextureCubeFace curFace = (QSSGRenderTextureCubeFace)(k + 1);
                //(*theFB)->AttachFace( QSSGRenderFrameBufferAttachments::DepthStencil,
                //*pEntry->m_DepthCube, curFace );
                (*theFB)->attach(QSSGRenderFrameBufferAttachment::DepthStencil, pEntry->m_depthRender);
                (*theFB)->attachFace(QSSGRenderFrameBufferAttachment::Color0, pEntry->m_depthCube, curFace);
                (*theFB)->isComplete();
                theRenderContext->clear(clearFlags);

                runRenderPass(renderRenderableShadowMapPass, false, true, true, true, i, theCameras[k]);
            }

            renderShadowCubeBlurPass(theFB,
                                     pEntry->m_depthCube,
                                     pEntry->m_cubeCopy,
                                     globalLights[i]->m_shadowFilter,
                                     globalLights[i]->m_shadowMapFar);
        }
    }

    (*theFB)->attach(QSSGRenderFrameBufferAttachment::Depth, QSSGRenderTextureOrRenderBuffer());
    (*theFB)->attach(QSSGRenderFrameBufferAttachment::Color0, QSSGRenderTextureOrRenderBuffer());

    // enable color writes
    theRenderContext->setColorWritesEnabled(true);
    theRenderContext->setCullingEnabled(true);
    theRenderContext->setClearColor(QVector4D(0.0, 0.0, 0.0, 0.0));
    // reset rasterizer state
    theRenderContext->setRasterizerState(rsdefaultstate);

    renderer->endLayerDepthPassRender();
}

inline void renderRenderableDepthPass(QSSGLayerRenderData &inData,
                                      QSSGRenderableObject &inObject,
                                      const QVector2D &inCameraProps,
                                      const ShaderFeatureSetList &,
                                      quint32,
                                      const QSSGRenderCamera &inCamera)
{
    if (inObject.renderableFlags.isDefaultMaterialMeshSubset())
        static_cast<QSSGSubsetRenderable &>(inObject).renderDepthPass(inCameraProps);
    else if (inObject.renderableFlags.isCustomMaterialMeshSubset())
        static_cast<QSSGCustomMaterialRenderable &>(inObject).renderDepthPass(inCameraProps, inData.layer, inData.globalLights, inCamera, nullptr);
    else
        Q_ASSERT(false);

}

void QSSGLayerRenderData::renderDepthPass(bool inEnableTransparentDepthWrite)
{
    QSSGStackPerfTimer ___timer(renderer->contextInterface()->performanceTimer(), Q_FUNC_INFO);
    if (camera == nullptr)
        return;

    // Avoid running this method if possible.
    if ((inEnableTransparentDepthWrite == false && (opaqueObjects.size() == 0 || !layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthPrePass)))
            || !layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthTest))
        return;

    renderer->beginLayerDepthPassRender(*this);

    const auto &theRenderContext = renderer->context();

    // disable color writes
    theRenderContext->setColorWritesEnabled(false);
    theRenderContext->setDepthWriteEnabled(true);

    QSSGRenderClearFlags clearFlags(QSSGRenderClearValues::Stencil | QSSGRenderClearValues::Depth);
    theRenderContext->clear(clearFlags);

    runRenderPass(renderRenderableDepthPass, false, true, false, inEnableTransparentDepthWrite, 0, *camera);

    // enable color writes
    theRenderContext->setColorWritesEnabled(true);

    renderer->endLayerDepthPassRender();
}

inline void renderRenderable(QSSGLayerRenderData &inData,
                             QSSGRenderableObject &inObject,
                             const QVector2D &inCameraProps,
                             const ShaderFeatureSetList &inFeatureSet,
                             quint32,
                             const QSSGRenderCamera &inCamera)
{
    if (inObject.renderableFlags.isDefaultMaterialMeshSubset()) {
        static_cast<QSSGSubsetRenderable &>(inObject).render(inCameraProps, inFeatureSet);
    } else if (inObject.renderableFlags.isCustomMaterialMeshSubset()) {
        // PKC : Need a better place to do this.
        QSSGCustomMaterialRenderable &theObject = static_cast<QSSGCustomMaterialRenderable &>(inObject);
        if (!inData.layer.lightProbe && theObject.material.m_iblProbe)
            inData.setShaderFeature(QSSGShaderDefines::asString(QSSGShaderDefines::LightProbe), theObject.material.m_iblProbe->m_textureData.m_texture != nullptr);
        else if (inData.layer.lightProbe)
            inData.setShaderFeature(QSSGShaderDefines::asString(QSSGShaderDefines::LightProbe), inData.layer.lightProbe->m_textureData.m_texture != nullptr);

        static_cast<QSSGCustomMaterialRenderable &>(inObject).render(inCameraProps,
                                                                       inData,
                                                                       inData.layer,
                                                                       inData.globalLights,
                                                                       inCamera,
                                                                       inData.m_layerDepthTexture,
                                                                       inData.m_layerSsaoTexture,
                                                                       inFeatureSet);
    } else {
        Q_ASSERT(false);
    }
}

void QSSGLayerRenderData::runRenderPass(TRenderRenderableFunction inRenderFn,
                                          bool inEnableBlending,
                                          bool inEnableDepthWrite,
                                          bool inEnableTransparentDepthWrite,
                                          bool inSortOpaqueRenderables,
                                          quint32 indexLight,
                                          const QSSGRenderCamera &inCamera,
                                          QSSGResourceFrameBuffer *theFB)
{
    Q_UNUSED(theFB)
    const auto &theRenderContext = renderer->context();
    theRenderContext->setDepthFunction(QSSGRenderBoolOp::LessThanOrEqual);
    theRenderContext->setBlendingEnabled(false);
    QVector2D theCameraProps = QVector2D(camera->clipNear, camera->clipFar);
    const auto &theOpaqueObjects = getOpaqueRenderableObjects(inSortOpaqueRenderables);
    bool usingDepthBuffer = layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthTest) && theOpaqueObjects.size() > 0;

    if (usingDepthBuffer) {
        theRenderContext->setDepthTestEnabled(true);
        theRenderContext->setDepthWriteEnabled(inEnableDepthWrite);
    } else {
        theRenderContext->setDepthWriteEnabled(false);
        theRenderContext->setDepthTestEnabled(false);
    }

    for (const auto &handle : theOpaqueObjects) {
        QSSGRenderableObject *theObject = handle.obj;
        QSSGScopedLightsListScope lightsScope(globalLights, lightDirections, sourceLightDirections, theObject->scopedLights);
        setShaderFeature(QSSGShaderDefines::asString(QSSGShaderDefines::CgLighting), globalLights.empty() == false);
        inRenderFn(*this, *theObject, theCameraProps, getShaderFeatureSet(), indexLight, inCamera);
    }

    // transparent objects
    if (inEnableBlending || !layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthTest)) {
        theRenderContext->setBlendingEnabled(true && inEnableBlending);
        theRenderContext->setDepthWriteEnabled(inEnableTransparentDepthWrite);

        const auto &theTransparentObjects = getTransparentRenderableObjects();
        // Assume all objects have transparency if the layer's depth test enabled flag is true.
        if (layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthTest)) {
            for (const auto &handle : theTransparentObjects) {
                QSSGRenderableObject *theObject = handle.obj;
                if (!(theObject->renderableFlags.isCompletelyTransparent())) {
                    QSSGScopedLightsListScope lightsScope(globalLights, lightDirections, sourceLightDirections, theObject->scopedLights);
                    setShaderFeature(QSSGShaderDefines::asString(QSSGShaderDefines::CgLighting), !globalLights.empty());

                    inRenderFn(*this, *theObject, theCameraProps, getShaderFeatureSet(), indexLight, inCamera);
                }
            }
        }
        // If the layer doesn't have depth enabled then we have to render via an alternate route
        // where the transparent objects vector could have both opaque and transparent objects.
        else {
            for (const auto &handle : theTransparentObjects) {
                QSSGRenderableObject *theObject = handle.obj;
                if (!(theObject->renderableFlags.isCompletelyTransparent())) {
                    QSSGScopedLightsListScope lightsScope(globalLights, lightDirections, sourceLightDirections, theObject->scopedLights);
                    setShaderFeature(QSSGShaderDefines::asString(QSSGShaderDefines::CgLighting), !globalLights.empty());
                    inRenderFn(*this, *theObject, theCameraProps, getShaderFeatureSet(), indexLight, inCamera);
                }
            }
        }
    }
}

void QSSGLayerRenderData::render(QSSGResourceFrameBuffer *theFB)
{
    QSSGStackPerfTimer ___timer(renderer->contextInterface()->performanceTimer(), Q_FUNC_INFO);
    if (camera == nullptr)
        return;

    renderer->beginLayerRender(*this);
    runRenderPass(renderRenderable, true, !layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthPrePass), false, true, 0, *camera, theFB);
    renderer->endLayerRender();
}

void QSSGLayerRenderData::createGpuProfiler()
{
    if (renderer->context()->supportsTimerQuery()) {
        m_layerProfilerGpu.reset(new QSSGRenderGPUProfiler(renderer->contextInterface(), renderer->context()));
    }
}

void QSSGLayerRenderData::startProfiling(QString &nameID, bool sync)
{
    if (m_layerProfilerGpu) {
        m_layerProfilerGpu->startTimer(nameID, false, sync);
    }
}

void QSSGLayerRenderData::endProfiling(QString &nameID)
{
    if (m_layerProfilerGpu) {
        m_layerProfilerGpu->endTimer(nameID);
    }
}

void QSSGLayerRenderData::startProfiling(const char *nameID, bool sync)
{
    if (m_layerProfilerGpu) {
        QString theStr(QString::fromLocal8Bit(nameID));
        m_layerProfilerGpu->startTimer(theStr, false, sync);
    }
}

void QSSGLayerRenderData::endProfiling(const char *nameID)
{
    if (m_layerProfilerGpu) {
        QString theStr(QString::fromLocal8Bit(nameID));
        m_layerProfilerGpu->endTimer(theStr);
    }
}

void QSSGLayerRenderData::addVertexCount(quint32 count)
{
    if (m_layerProfilerGpu) {
        m_layerProfilerGpu->addVertexCount(count);
    }
}

// These are meant to be pixel offsets, so you need to divide them by the width/height
// of the layer respectively.
const QVector2D s_VertexOffsets[QSSGLayerRenderPreparationData::MAX_AA_LEVELS] = {
    QVector2D(-0.170840f, -0.553840f), // 1x
    QVector2D(0.162960f, -0.319340f), // 2x
    QVector2D(0.360260f, -0.245840f), // 3x
    QVector2D(-0.561340f, -0.149540f), // 4x
    QVector2D(0.249460f, 0.453460f), // 5x
    QVector2D(-0.336340f, 0.378260f), // 6x
    QVector2D(0.340000f, 0.166260f), // 7x
    QVector2D(0.235760f, 0.527760f), // 8x
};

// Blend factors are in the form of (frame blend factor, accumulator blend factor)
const QVector2D s_BlendFactors[QSSGLayerRenderPreparationData::MAX_AA_LEVELS] = {
    QVector2D(0.500000f, 0.500000f), // 1x
    QVector2D(0.333333f, 0.666667f), // 2x
    QVector2D(0.250000f, 0.750000f), // 3x
    QVector2D(0.200000f, 0.800000f), // 4x
    QVector2D(0.166667f, 0.833333f), // 5x
    QVector2D(0.142857f, 0.857143f), // 6x
    QVector2D(0.125000f, 0.875000f), // 7x
    QVector2D(0.111111f, 0.888889f), // 8x
};

const QVector2D s_TemporalVertexOffsets[QSSGLayerRenderPreparationData::MAX_TEMPORAL_AA_LEVELS] = {
    QVector2D(.3f, .3f),
    QVector2D(-.3f, -.3f)
};

static inline void offsetProjectionMatrix(QMatrix4x4 &inProjectionMatrix,
                                          const QVector2D &inVertexOffsets)
{
    inProjectionMatrix(0, 3) += inProjectionMatrix(3, 3) * inVertexOffsets.x();
    inProjectionMatrix(1, 3) += inProjectionMatrix(3, 3) * inVertexOffsets.y();
}

inline bool anyCompletelyNonTransparentObjects(const QSSGLayerRenderPreparationData::TRenderableObjectList &inObjects)
{
    for (int idx = 0, end = inObjects.size(); idx < end; ++idx) {
        if (inObjects.at(idx).obj->renderableFlags.isCompletelyTransparent() == false)
            return true;
    }
    return false;
}

bool QSSGLayerRenderData::progressiveAARenderRequest() const
{
    const QSSGLayerRenderPreparationResult &thePrepResult(*layerPrepResult);
    return m_progressiveAAPassIndex && m_progressiveAAPassIndex < thePrepResult.maxAAPassIndex;
}

void QSSGLayerRenderData::runnableRenderToViewport(const QSSGRef<QSSGRenderFrameBuffer> &theFB)
{
    const auto &theContext = renderer->context();
    theContext->resetStates();

    QSSGRenderContextScopedProperty<const QSSGRef<QSSGRenderFrameBuffer> &> __fbo(*theContext,
                                                                                &QSSGRenderContext::renderTarget,
                                                                                &QSSGRenderContext::setRenderTarget);
    QSSGRenderContextScopedProperty<QRect> __viewport(*theContext, &QSSGRenderContext::viewport, &QSSGRenderContext::setViewport);
    QSSGRenderContextScopedProperty<bool> theScissorEnabled(*theContext,
                                                              &QSSGRenderContext::isScissorTestEnabled,
                                                              &QSSGRenderContext::setScissorTestEnabled);
    QSSGRenderContextScopedProperty<QRect> theScissorRect(*theContext,
                                                            &QSSGRenderContext::scissorRect,
                                                            &QSSGRenderContext::setScissorRect);
    QSSGLayerRenderPreparationResult &thePrepResult(*layerPrepResult);
    QRectF theScreenRect(thePrepResult.viewport());

    const bool isProgressiveAABlendPass = m_progressiveAAPassIndex
                    && m_progressiveAAPassIndex < thePrepResult.maxAAPassIndex;
    const bool isProgressiveAACopyPass = !isProgressiveAABlendPass
                    && layer.progressiveAAMode != QSSGRenderLayer::AAMode::NoAA;
    const bool isTemporalAABlendPass = layer.temporalAAEnabled;
    quint32 aaFactorIndex = 0;

    // here used only for temporal aa
    QSSGRef<QSSGLayerProgAABlendShader> temporalAABlendShader = nullptr;

    // progressive aa uses this one
    QSSGRef<QSSGLayerLastFrameBlendShader> progAABlendShader = nullptr;

    qint32 sampleCount = 1;
    // check multsample mode and MSAA texture support
    if (layer.multisampleAAMode != QSSGRenderLayer::AAMode::NoAA && theContext->supportsMultisampleTextures())
        sampleCount = qint32(layer.multisampleAAMode);

    if (isTemporalAABlendPass || isProgressiveAABlendPass || isProgressiveAACopyPass) {
        if (isTemporalAABlendPass)
            temporalAABlendShader = renderer->getLayerProgAABlendShader();
        if (isProgressiveAABlendPass)
            progAABlendShader = renderer->getLayerLastFrameBlendShader();

        // we use the temporal aa texture for progressive aa too
        m_temporalAATexture.ensureTexture(theScreenRect.width(), theScreenRect.height(),
                                          QSSGRenderTextureFormat::RGBA8);

        if (!isProgressiveAACopyPass) {
            QVector2D theVertexOffsets;
            if (isProgressiveAABlendPass) {
                aaFactorIndex = (m_progressiveAAPassIndex - 1);
                theVertexOffsets = s_VertexOffsets[aaFactorIndex];
            } else {
                theVertexOffsets = s_TemporalVertexOffsets[m_temporalAAPassIndex];
                ++m_temporalAAPassIndex;
                m_temporalAAPassIndex = m_temporalAAPassIndex % MAX_TEMPORAL_AA_LEVELS;
            }

            theVertexOffsets.setX(theVertexOffsets.x() / (theScreenRect.width() / 2.0f));
            theVertexOffsets.setY(theVertexOffsets.y() / (theScreenRect.height() / 2.0f));
            // Run through all models and update MVP.

            // TODO - optimize this exact matrix operation.
            for (qint32 idx = 0, end = modelContexts.size(); idx < end; ++idx) {
                QMatrix4x4 &originalProjection(modelContexts[idx]->modelViewProjection);
                offsetProjectionMatrix(originalProjection, theVertexOffsets);
            }
        }
    }

    // Shadows and SSAO require an FBO, so create one if we are using those
    if (thePrepResult.flags.requiresSsaoPass() || thePrepResult.flags.requiresShadowMapPass()) {
        QSize theLayerTextureDimensions = thePrepResult.textureDimensions();
        QSSGRef<QSSGResourceManager> theResourceManager = renderer->contextInterface()->resourceManager();
        QSSGResourceFrameBuffer theFBO(theResourceManager);
        // Allocates the frame buffer which has the side effect of setting the current render target
        // to that frame buffer.
        theFBO.ensureFrameBuffer();

        theContext->setScissorTestEnabled(false);

        if (thePrepResult.flags.requiresSsaoPass()) {
            if (m_layerSsaoTexture.ensureTexture(theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), QSSGRenderTextureFormat::RGBA8)) {
                m_layerSsaoTexture->setMinFilter(QSSGRenderTextureMinifyingOp::Linear);
                m_layerSsaoTexture->setMagFilter(QSSGRenderTextureMagnifyingOp::Linear);
                m_progressiveAAPassIndex = 0;
                m_nonDirtyTemporalAAPassIndex = 0;
            }
        }

        if (thePrepResult.flags.requiresDepthTexture()) {
            // The depth texture doesn't need to be multisample, the prepass depth does.
            if (m_layerDepthTexture.ensureTexture(theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), QSSGRenderTextureFormat::Depth24Stencil8)) {
                // Depth textures are generally not bilinear filtered.
                m_layerDepthTexture->setMinFilter(QSSGRenderTextureMinifyingOp::Nearest);
                m_layerDepthTexture->setMagFilter(QSSGRenderTextureMagnifyingOp::Nearest);
                m_progressiveAAPassIndex = 0;
                m_nonDirtyTemporalAAPassIndex = 0;
            }
        }

        QRect theNewViewport(0, 0, theLayerTextureDimensions.width(), theLayerTextureDimensions.height());
        {
            theContext->setRenderTarget(theFBO);
            QSSGRenderContextScopedProperty<QRect> __viewport(*theContext,
                                                              &QSSGRenderContext::viewport,
                                                              &QSSGRenderContext::setViewport,
                                                              theNewViewport);

            // Depth Prepass with transparent and opaque renderables (for SSAO)
            if (thePrepResult.flags.requiresDepthTexture() && m_progressiveAAPassIndex == 0) {
                // Setup FBO with single depth buffer target.
                // Note this does not use multisample.
                QSSGRenderFrameBufferAttachment theAttachment = getFramebufferDepthAttachmentFormat(QSSGRenderTextureFormat::Depth24Stencil8);
                theFBO->attach(theAttachment, m_layerDepthTexture.getTexture());

                // In this case transparent objects also may write their depth.
                renderDepthPass(true);
                theFBO->attach(theAttachment, QSSGRenderTextureOrRenderBuffer());
            }

            // SSAO
            if (thePrepResult.flags.requiresSsaoPass() && m_progressiveAAPassIndex == 0 && camera != nullptr) {
                startProfiling("AO pass", false);
                // Setup FBO with single color buffer target
                theFBO->attach(QSSGRenderFrameBufferAttachment::Color0, m_layerSsaoTexture.getTexture());
                QSSGRenderFrameBufferAttachment theAttachment = getFramebufferDepthAttachmentFormat(QSSGRenderTextureFormat::Depth24Stencil8);
                theFBO->attach(theAttachment, m_layerDepthTexture.getTexture());
                theContext->clear(QSSGRenderClearValues::Color);
                renderAoPass();
                theFBO->attach(QSSGRenderFrameBufferAttachment::Color0, QSSGRenderTextureOrRenderBuffer());
                endProfiling("AO pass");
            }

            // Shadow
            if (thePrepResult.flags.requiresShadowMapPass() && m_progressiveAAPassIndex == 0) {
                // shadow map path
                renderShadowMapPass(&theFBO);
            }
        }
    }

    theContext->setRenderTarget(theFB);

    // Multisampling
    theContext->setMultisampleEnabled(sampleCount > 1 ? true : false);

    // Start Operations on Viewport
    theContext->setViewport(layerPrepResult->viewport().toRect());
    theContext->setScissorTestEnabled(true);
    theContext->setScissorRect(layerPrepResult->scissor().toRect());

    // Depth Pre-pass
    if (layer.flags.testFlag(QSSGRenderLayer::Flag::LayerEnableDepthPrePass)) {
        startProfiling("Depth pass", false);
        renderDepthPass(false);
        endProfiling("Depth pass");
    }

    // Viewport Clear
    startProfiling("Clear pass", false);
    renderClearPass();
    endProfiling("Clear pass");

    // Render pass
    startProfiling("Render pass", false);
    render();
    endProfiling("Render pass");

    if (temporalAABlendShader && isTemporalAABlendPass) {
        theContext->copyFramebufferTexture(0, 0, theScreenRect.width(), theScreenRect.height(),
                                           0, 0,
                                           QSSGRenderTextureOrRenderBuffer(m_temporalAATexture));

        if (!m_prevTemporalAATexture.isNull()) {
            // blend temporal aa textures
            QVector2D theBlendFactors;
            theBlendFactors = QVector2D(.5f, .5f);

            theContext->setDepthTestEnabled(false);
            theContext->setBlendingEnabled(false);
            theContext->setCullingEnabled(false);
            theContext->setActiveShader(temporalAABlendShader->shader);
            temporalAABlendShader->accumSampler.set(m_prevTemporalAATexture.getTexture().data());
            temporalAABlendShader->lastFrame.set(m_temporalAATexture.getTexture().data());
            temporalAABlendShader->blendFactors.set(theBlendFactors);
            renderer->renderQuad();
        }
        m_prevTemporalAATexture.swapTexture(m_temporalAATexture);
    }
    if (isProgressiveAACopyPass || (progAABlendShader && isProgressiveAABlendPass)) {
        // first pass is just copying the frame, next passes blend the texture
        // on top of the screen
        if (m_progressiveAAPassIndex > 1) {
            theContext->setDepthTestEnabled(false);
            theContext->setBlendingEnabled(true);
            theContext->setCullingEnabled(false);
            theContext->setBlendFunction(QSSGRenderBlendFunctionArgument(
                                             QSSGRenderSrcBlendFunc::One, QSSGRenderDstBlendFunc::OneMinusSrcAlpha,
                                             QSSGRenderSrcBlendFunc::Zero, QSSGRenderDstBlendFunc::One));
            const float blendFactor = s_BlendFactors[aaFactorIndex].y();
            theContext->setActiveShader(progAABlendShader->shader);
            progAABlendShader->lastFrame.set(m_temporalAATexture.getTexture().data());
            progAABlendShader->blendFactor.set(blendFactor);
            renderer->renderQuad();
        }
        theContext->copyFramebufferTexture(0, 0, theScreenRect.width(), theScreenRect.height(),
                                           0, 0,
                                           QSSGRenderTextureOrRenderBuffer(m_temporalAATexture));
        if (m_progressiveAAPassIndex < thePrepResult.maxAAPassIndex)
            ++m_progressiveAAPassIndex;
    }

    if (m_boundingRectColor.hasValue()) {
        QSSGRenderContextScopedProperty<QRect> __viewport(*theContext, &QSSGRenderContext::viewport, &QSSGRenderContext::setViewport);
        QSSGRenderContextScopedProperty<bool> theScissorEnabled(*theContext,
                                                                  &QSSGRenderContext::isScissorTestEnabled,
                                                                  &QSSGRenderContext::setScissorTestEnabled);
        QSSGRenderContextScopedProperty<QRect> theScissorRect(*theContext,
                                                                &QSSGRenderContext::scissorRect,
                                                                &QSSGRenderContext::setScissorRect);
        renderer->setupWidgetLayer();
        // Setup a simple viewport to render to the entire presentation viewport.
        theContext->setViewport(QRect(0,
                                      0,
                                      (quint32)thePrepResult.viewport().width(),
                                      (quint32)thePrepResult.viewport().height()));

        QRectF thePresRect(thePrepResult.viewport());

        // Remove any offsetting from the presentation rect since the widget layer is a
        // stand-alone fbo.
        QRectF theWidgetScreenRect(theScreenRect.x() - thePresRect.x(),
                                   theScreenRect.y() - thePresRect.y(),
                                   theScreenRect.width(),
                                   theScreenRect.height());
        theContext->setScissorTestEnabled(false);
        renderer->drawScreenRect(theWidgetScreenRect, *m_boundingRectColor);
    }
    theContext->setBlendFunction(QSSGRenderBlendFunctionArgument(QSSGRenderSrcBlendFunc::One,
                                                                   QSSGRenderDstBlendFunc::OneMinusSrcAlpha,
                                                                   QSSGRenderSrcBlendFunc::One,
                                                                   QSSGRenderDstBlendFunc::OneMinusSrcAlpha));
    theContext->setBlendEquation(QSSGRenderBlendEquationArgument(QSSGRenderBlendEquation::Add, QSSGRenderBlendEquation::Add));
}

void QSSGLayerRenderData::prepareForRender()
{
    // When we render to the scene itself (as opposed to an offscreen buffer somewhere)
    // then we use the MVP of the layer somewhat.
    const QSize theViewportSize = renderer->contextInterface()->viewport().size();
    prepareForRender(theViewportSize);
}

void QSSGLayerRenderData::resetForFrame()
{
    QSSGLayerRenderPreparationData::resetForFrame();
    m_boundingRectColor.setEmpty();
}

void QSSGLayerRenderData::prepareAndRender(const QMatrix4x4 &inViewProjection)
{
    TRenderableObjectList theTransparentObjects(transparentObjects);
    TRenderableObjectList theOpaqueObjects(opaqueObjects);
    theTransparentObjects.clear();
    theOpaqueObjects.clear();
    modelContexts.clear();
    QSSGLayerRenderPreparationResultFlags theFlags;
    prepareRenderablesForRender(inViewProjection, QSSGEmpty(), theFlags);
    renderDepthPass(false);
    render();
}

QT_END_NAMESPACE
