//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// MultisampledRenderToTextureBenchmark:
//   Performance test for rendering to multisampled-render-to-texture attachments.
//

#include "ANGLEPerfTest.h"

#include <iostream>
#include <random>
#include <sstream>

#include "test_utils/gl_raii.h"
#include "util/shader_utils.h"

using namespace angle;

namespace
{
constexpr uint32_t kMultipassPassCount = 5;

struct MultisampledRenderToTextureParams final : public RenderTestParams
{
    MultisampledRenderToTextureParams()
    {
        iterationsPerStep = 1;
        trackGpuTime      = true;

        textureWidth  = 1920;
        textureHeight = 1080;

        multiplePasses   = false;
        withDepthStencil = false;
    }

    std::string story() const override;

    GLsizei textureWidth;
    GLsizei textureHeight;

    bool multiplePasses;
    bool withDepthStencil;
};

std::ostream &operator<<(std::ostream &os, const MultisampledRenderToTextureParams &params)
{
    return os << params.backendAndStory().substr(1);
}

std::string MultisampledRenderToTextureParams::story() const
{
    std::stringstream strstr;

    strstr << RenderTestParams::story();

    if (multiplePasses)
    {
        strstr << "_multipass";
    }

    if (withDepthStencil)
    {
        strstr << "_ds";
    }

    return strstr.str();
}

class MultisampledRenderToTextureBenchmark
    : public ANGLERenderTest,
      public ::testing::WithParamInterface<MultisampledRenderToTextureParams>
{
  public:
    MultisampledRenderToTextureBenchmark();

    void initializeBenchmark() override;
    void destroyBenchmark() override;
    void drawBenchmark() override;

  protected:
    void initShaders();

    GLuint mFramebuffer              = 0;
    GLuint mProgram                  = 0;
    GLuint mColorTexture             = 0;
    GLuint mDepthStencilRenderbuffer = 0;

    std::vector<uint8_t> mTextureData;
};

MultisampledRenderToTextureBenchmark::MultisampledRenderToTextureBenchmark()
    : ANGLERenderTest("MultisampledRenderToTexture", GetParam())
{
    // Crashes on nvidia+d3d11. http://crbug.com/945415
    if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
    {
        mSkipTest = true;
    }

    // Fails on Windows7 NVIDIA Vulkan, presumably due to old drivers. http://crbug.com/1096510
    if (IsWindows7() && IsNVIDIA() &&
        GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
    {
        mSkipTest = true;
    }

    // Fails on Pixel 4 GLES: http://anglebug.com/5120
    if (IsPixel4() && GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
    {
        mSkipTest = true;
    }

    // http://anglebug.com/5380
    if (IsLinux() && IsAMD() &&
        GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE &&
        GetParam().multiplePasses && GetParam().withDepthStencil)
    {
        mSkipTest = true;
    }

    // http://anglebug.com/6319
    if (IsLinux() && IsIntel() &&
        GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
    {
        mSkipTest = true;
    }
}

void MultisampledRenderToTextureBenchmark::initializeBenchmark()
{
    if (!IsGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"))
    {
        mSkipTest = true;
        return;
    }

    const auto &params = GetParam();

    initShaders();
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());

    glGenFramebuffers(1, &mFramebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);

    glGenTextures(1, &mColorTexture);
    glBindTexture(GL_TEXTURE_2D, mColorTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, params.textureWidth, params.textureHeight, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         mColorTexture, 0, 4);

    if (params.withDepthStencil)
    {
        glGenRenderbuffers(1, &mDepthStencilRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, mDepthStencilRenderbuffer);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8,
                                            params.textureWidth, params.textureHeight);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                  mDepthStencilRenderbuffer);
    }

    ASSERT_GL_NO_ERROR();
}

void MultisampledRenderToTextureBenchmark::initShaders()
{
    constexpr char kVS[] = R"(void main()
{
    gl_Position = vec4(0, 0, 0, 1);
})";

    constexpr char kFS[] = R"(precision mediump float;
void main()
{
    gl_FragColor = vec4(0);
})";

    mProgram = CompileProgram(kVS, kFS);
    ASSERT_NE(0u, mProgram);

    glUseProgram(mProgram);

    ASSERT_GL_NO_ERROR();
}

void MultisampledRenderToTextureBenchmark::destroyBenchmark()
{
    glDeleteFramebuffers(1, &mFramebuffer);
    glDeleteRenderbuffers(1, &mDepthStencilRenderbuffer);
    glDeleteTextures(1, &mColorTexture);
    glDeleteProgram(mProgram);
}

void MultisampledRenderToTextureBenchmark::drawBenchmark()
{
    const auto &params = GetParam();

    GLTexture mMockTexture;
    glBindTexture(GL_TEXTURE_2D, mMockTexture);

    startGpuTimer();

    // Initially clear the color attachment to avoid having to load from the resolved image.  The
    // depth/stencil attachment doesn't need this as it's contents are always undefined between
    // render passes.
    glClear(GL_COLOR_BUFFER_BIT);

    const uint32_t passCount = params.multiplePasses ? kMultipassPassCount : 1;
    for (uint32_t pass = 0; pass < passCount; ++pass)
    {
        // Perform a draw just to have something in the render pass.  With the position attributes
        // not set, a constant default value is used, resulting in a very cheap draw.
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Force the render pass to break by cheaply reading back from the color attachment.
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
    }
    stopGpuTimer();

    ASSERT_GL_NO_ERROR();
}

MultisampledRenderToTextureParams D3D11Params(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::D3D11();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

MultisampledRenderToTextureParams OpenGLOrGLESParams(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::OPENGL_OR_GLES();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

MultisampledRenderToTextureParams VulkanParams(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::VULKAN();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

}  // anonymous namespace

TEST_P(MultisampledRenderToTextureBenchmark, Run)
{
    run();
}

using namespace params;

ANGLE_INSTANTIATE_TEST(MultisampledRenderToTextureBenchmark,
                       D3D11Params(false, false),
                       D3D11Params(true, true),
                       OpenGLOrGLESParams(false, false),
                       OpenGLOrGLESParams(true, true),
                       VulkanParams(false, false),
                       VulkanParams(true, false),
                       VulkanParams(false, true),
                       VulkanParams(true, true));
