//
// Copyright 2015 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.
//
// D3DTextureTest:
//   Tests of the EGL_ANGLE_d3d_texture_client_buffer extension

#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

#include <d3d11.h>
#include <windows.h>

#include "util/EGLWindow.h"
#include "util/com_utils.h"

namespace angle
{

class D3DTextureTest : public ANGLETest
{
  protected:
    D3DTextureTest()
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
        setConfigStencilBits(8);
    }

    void testSetUp() override
    {
        constexpr char kVS[] =
            R"(precision highp float;
            attribute vec4 position;
            varying vec2 texcoord;

            void main()
            {
                gl_Position = position;
                texcoord = (position.xy * 0.5) + 0.5;
                texcoord.y = 1.0 - texcoord.y;
            })";

        constexpr char kTextureFS[] =
            R"(precision highp float;
            uniform sampler2D tex;
            varying vec2 texcoord;

            void main()
            {
                gl_FragColor = texture2D(tex, texcoord);
            })";

        constexpr char kTextureFSNoSampling[] =
            R"(precision highp float;

            void main()
            {
                gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
            })";

        mTextureProgram = CompileProgram(kVS, kTextureFS);
        ASSERT_NE(0u, mTextureProgram) << "shader compilation failed.";

        mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
        ASSERT_NE(-1, mTextureUniformLocation);

        mTextureProgramNoSampling = CompileProgram(kVS, kTextureFSNoSampling);
        ASSERT_NE(0u, mTextureProgramNoSampling) << "shader compilation failed.";

        mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));
        ASSERT_NE(nullptr, mD3D11Module);

        PFN_D3D11_CREATE_DEVICE createDeviceFunc = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
            GetProcAddress(mD3D11Module, "D3D11CreateDevice"));

        EGLWindow *window  = getEGLWindow();
        EGLDisplay display = window->getDisplay();
        if (IsEGLDisplayExtensionEnabled(display, "EGL_EXT_device_query"))
        {
            PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT =
                reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
                    eglGetProcAddress("eglQueryDisplayAttribEXT"));
            PFNEGLQUERYDEVICEATTRIBEXTPROC eglQueryDeviceAttribEXT =
                reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
                    eglGetProcAddress("eglQueryDeviceAttribEXT"));

            EGLDeviceEXT device = 0;
            {
                EGLAttrib result = 0;
                EXPECT_EGL_TRUE(eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, &result));
                device = reinterpret_cast<EGLDeviceEXT>(result);
            }

            if (IsEGLDeviceExtensionEnabled(device, "EGL_ANGLE_device_d3d"))
            {
                EGLAttrib result = 0;
                if (eglQueryDeviceAttribEXT(device, EGL_D3D11_DEVICE_ANGLE, &result))
                {
                    mD3D11Device = reinterpret_cast<ID3D11Device *>(result);
                    mD3D11Device->AddRef();
                }
                else if (eglQueryDeviceAttribEXT(device, EGL_D3D9_DEVICE_ANGLE, &result))
                {
                    mD3D9Device = reinterpret_cast<IDirect3DDevice9 *>(result);
                    mD3D9Device->AddRef();
                }
            }
        }
        else
        {
            ASSERT_TRUE(
                SUCCEEDED(createDeviceFunc(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr,
                                           0, D3D11_SDK_VERSION, &mD3D11Device, nullptr, nullptr)));
        }
    }

    void testTearDown() override
    {
        glDeleteProgram(mTextureProgram);

        if (mD3D11Device)
        {
            mD3D11Device->Release();
            mD3D11Device = nullptr;
        }

        FreeLibrary(mD3D11Module);
        mD3D11Module = nullptr;

        if (mD3D9Device)
        {
            mD3D9Device->Release();
            mD3D9Device = nullptr;
        }
    }

    EGLSurface createD3D11PBuffer(size_t width,
                                  size_t height,
                                  UINT sampleCount,
                                  UINT sampleQuality,
                                  UINT bindFlags,
                                  DXGI_FORMAT format,
                                  const EGLint *attribs)
    {
        EGLWindow *window  = getEGLWindow();
        EGLDisplay display = window->getDisplay();
        EGLConfig config   = window->getConfig();

        EXPECT_TRUE(mD3D11Device != nullptr);
        ID3D11Texture2D *texture = nullptr;
        CD3D11_TEXTURE2D_DESC desc(format, static_cast<UINT>(width), static_cast<UINT>(height), 1,
                                   1, bindFlags);
        desc.SampleDesc.Count   = sampleCount;
        desc.SampleDesc.Quality = sampleQuality;
        EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));

        EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
                                                              texture, config, attribs);

        texture->Release();

        return pbuffer;
    }

    EGLSurface createD3D11PBuffer(size_t width,
                                  size_t height,
                                  EGLint eglTextureFormat,
                                  EGLint eglTextureTarget,
                                  UINT sampleCount,
                                  UINT sampleQuality,
                                  UINT bindFlags,
                                  DXGI_FORMAT format)
    {
        EGLint attribs[] = {
            EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET,
            eglTextureTarget,   EGL_NONE,         EGL_NONE,
        };
        return createD3D11PBuffer(width, height, sampleCount, sampleQuality, bindFlags, format,
                                  attribs);
    }

    EGLSurface createPBuffer(size_t width,
                             size_t height,
                             EGLint eglTextureFormat,
                             EGLint eglTextureTarget,
                             UINT sampleCount,
                             UINT sampleQuality)
    {
        if (mD3D11Device)
        {
            return createD3D11PBuffer(
                width, height, eglTextureFormat, eglTextureTarget, sampleCount, sampleQuality,
                D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);
        }

        if (mD3D9Device)
        {
            EGLWindow *window  = getEGLWindow();
            EGLDisplay display = window->getDisplay();
            EGLConfig config   = window->getConfig();

            EGLint attribs[] = {
                EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET,
                eglTextureTarget,   EGL_NONE,         EGL_NONE,
            };

            // Multisampled textures are not supported on D3D9.
            EXPECT_TRUE(sampleCount <= 1);
            EXPECT_TRUE(sampleQuality == 0);

            IDirect3DTexture9 *texture = nullptr;
            EXPECT_TRUE(SUCCEEDED(mD3D9Device->CreateTexture(
                static_cast<UINT>(width), static_cast<UINT>(height), 1, D3DUSAGE_RENDERTARGET,
                D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, nullptr)));

            EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
                                                                  texture, config, attribs);

            texture->Release();

            return pbuffer;
        }
        else
        {
            return EGL_NO_SURFACE;
        }
    }

    bool valid() const
    {
        EGLWindow *window  = getEGLWindow();
        EGLDisplay display = window->getDisplay();
        if (!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_d3d_texture_client_buffer"))
        {
            std::cout << "Test skipped due to missing EGL_ANGLE_d3d_texture_client_buffer"
                      << std::endl;
            return false;
        }

        if (!mD3D11Device && !mD3D9Device)
        {
            std::cout << "Test skipped due to no D3D devices being available." << std::endl;
            return false;
        }

        if (IsWindows() && IsAMD() && IsOpenGL())
        {
            std::cout << "Test skipped on Windows AMD OpenGL." << std::endl;
            return false;
        }

        if (IsWindows() && IsIntel() && IsOpenGL())
        {
            std::cout << "Test skipped on Windows Intel OpenGL." << std::endl;
            return false;
        }
        return true;
    }

    void testTextureSamplesAs50PercentGreen(GLuint texture)
    {
        GLFramebuffer scratchFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, scratchFbo);
        GLTexture scratchTexture;
        glBindTexture(GL_TEXTURE_2D, scratchTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, scratchTexture,
                               0);

        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(mTextureProgram);
        glUniform1i(mTextureUniformLocation, 0);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        drawQuad(mTextureProgram, "position", 0.5f);
        ASSERT_GL_NO_ERROR();

        EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);
    }

    GLuint mTextureProgram;
    GLuint mTextureProgramNoSampling;
    GLint mTextureUniformLocation;

    HMODULE mD3D11Module       = nullptr;
    ID3D11Device *mD3D11Device = nullptr;

    IDirect3DDevice9 *mD3D9Device = nullptr;
};

// Test creating pbuffer from textures with several different DXGI formats.
TEST_P(D3DTextureTest, TestD3D11SupportedFormatsSurface)
{
    bool srgbSupported = IsGLExtensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3;
    ANGLE_SKIP_TEST_IF(!valid() || !mD3D11Device || !srgbSupported);

    const DXGI_FORMAT formats[] = {DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                   DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB};
    for (size_t i = 0; i < 4; ++i)
    {
        if (formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
        {
            if (IsOpenGL())
            {
                // This generates an invalid format error when calling wglDXRegisterObjectNV().
                // Reproducible at least on NVIDIA driver 390.65 on Windows 10.
                std::cout << "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB subtest skipped: IsOpenGL().\n";
                continue;
            }
        }

        EGLSurface pbuffer = createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
                                                D3D11_BIND_RENDER_TARGET, formats[i]);
        ASSERT_EGL_SUCCESS();
        ASSERT_NE(EGL_NO_SURFACE, pbuffer);

        EGLWindow *window  = getEGLWindow();
        EGLDisplay display = window->getDisplay();

        EGLint colorspace = EGL_NONE;
        eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);

        if (formats[i] == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ||
            formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
        {
            EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);
        }
        else
        {
            EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);
        }

        eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
        ASSERT_EGL_SUCCESS();
        window->makeCurrent();
        eglDestroySurface(display, pbuffer);
    }
}

// Test binding a pbuffer created from a D3D texture as a texture image with several different DXGI
// formats. The test renders to and samples from the pbuffer.
TEST_P(D3DTextureTest, TestD3D11SupportedFormatsTexture)
{
    bool srgb8alpha8TextureAttachmentSupported = getClientMajorVersion() >= 3;
    ANGLE_SKIP_TEST_IF(!valid() || !mD3D11Device || !srgb8alpha8TextureAttachmentSupported);

    bool srgbWriteControlSupported =
        IsGLExtensionEnabled("GL_EXT_sRGB_write_control") && !IsOpenGL();

    const DXGI_FORMAT formats[] = {DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM,
                                   DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
                                   DXGI_FORMAT_B8G8R8A8_UNORM_SRGB};
    for (size_t i = 0; i < 4; ++i)
    {
        if (formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
        {
            if (IsOpenGL())
            {
                // This generates an invalid format error when calling wglDXRegisterObjectNV().
                // Reproducible at least on NVIDIA driver 390.65 on Windows 10.
                std::cout << "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB subtest skipped: IsOpenGL().\n";
                continue;
            }
        }

        SCOPED_TRACE(std::string("Test case:") + std::to_string(i));
        EGLWindow *window  = getEGLWindow();
        EGLDisplay display = window->getDisplay();

        EGLSurface pbuffer =
            createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
                               D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, formats[i]);
        ASSERT_EGL_SUCCESS();
        ASSERT_NE(EGL_NO_SURFACE, pbuffer);

        EGLint colorspace = EGL_NONE;
        eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);

        GLuint texture = 0u;
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
        ASSERT_EGL_SUCCESS();
        ASSERT_EGL_TRUE(result);

        GLuint fbo = 0u;
        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        glViewport(0, 0, 32, 32);

        GLint colorEncoding = 0;
        glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                              GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,
                                              &colorEncoding);

        if (formats[i] == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ||
            formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
        {
            EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);
            EXPECT_EQ(GL_SRGB_EXT, colorEncoding);
        }
        else
        {
            EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);
            EXPECT_EQ(GL_LINEAR, colorEncoding);
        }

        // Clear the texture with 50% green and check that the color value written is correct.
        glClearColor(0.0f, 0.5f, 0.0f, 1.0f);

        if (colorEncoding == GL_SRGB_EXT)
        {
            glClear(GL_COLOR_BUFFER_BIT);
            EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 188u, 0u, 255u), 2);
            // Disable SRGB and run the non-sRGB test case.
            if (srgbWriteControlSupported)
                glDisable(GL_FRAMEBUFFER_SRGB_EXT);
        }

        if (colorEncoding == GL_LINEAR || srgbWriteControlSupported)
        {
            glClear(GL_COLOR_BUFFER_BIT);
            EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);
        }

        // Draw with the texture to a linear framebuffer and check that the color value written is
        // correct.
        testTextureSamplesAs50PercentGreen(texture);

        glBindFramebuffer(GL_FRAMEBUFFER, 0u);
        glBindTexture(GL_TEXTURE_2D, 0u);
        glDeleteTextures(1, &texture);
        glDeleteFramebuffers(1, &fbo);
        eglDestroySurface(display, pbuffer);
    }
}

// Test binding a pbuffer created from a D3D texture as a texture image with typeless texture
// formats.
TEST_P(D3DTextureTest, TestD3D11TypelessTexture)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    ANGLE_SKIP_TEST_IF(!valid());

    // Typeless formats are optional in the spec and currently only supported on D3D11 backend.
    ANGLE_SKIP_TEST_IF(!IsD3D11());

    // GL_SRGB8_ALPHA8 texture attachment support is required.
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);

    const std::array<EGLint, 2> eglGlColorspaces = {EGL_GL_COLORSPACE_LINEAR,
                                                    EGL_GL_COLORSPACE_SRGB};
    const std::array<DXGI_FORMAT, 2> dxgiFormats = {DXGI_FORMAT_R8G8B8A8_TYPELESS,
                                                    DXGI_FORMAT_B8G8R8A8_TYPELESS};
    for (auto eglGlColorspace : eglGlColorspaces)
    {
        for (auto dxgiFormat : dxgiFormats)
        {
            SCOPED_TRACE(std::string("Test case:") + std::to_string(eglGlColorspace) + " / " +
                         std::to_string(dxgiFormat));

            EGLint attribs[] = {
                EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
                EGL_GL_COLORSPACE,  eglGlColorspace,  EGL_NONE,           EGL_NONE,
            };

            EGLSurface pbuffer = createD3D11PBuffer(
                32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, dxgiFormat,
                attribs);

            ASSERT_EGL_SUCCESS();
            ASSERT_NE(EGL_NO_SURFACE, pbuffer);

            EGLint colorspace = EGL_NONE;
            eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);

            GLuint texture = 0u;
            glGenTextures(1, &texture);
            glBindTexture(GL_TEXTURE_2D, texture);
            EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
            ASSERT_EGL_SUCCESS();
            ASSERT_EGL_TRUE(result);

            GLuint fbo = 0u;
            glGenFramebuffers(1, &fbo);
            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
            glViewport(0, 0, 32, 32);

            GLint colorEncoding = 0;
            glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                  GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,
                                                  &colorEncoding);

            if (eglGlColorspace == EGL_GL_COLORSPACE_LINEAR)
            {
                EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);
                EXPECT_EQ(GL_LINEAR, colorEncoding);
            }
            else
            {
                EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);
                EXPECT_EQ(GL_SRGB_EXT, colorEncoding);
            }

            // Clear the texture with 50% green and check that the color value written is correct.
            glClearColor(0.0f, 0.5f, 0.0f, 1.0f);

            if (colorEncoding == GL_SRGB_EXT)
            {
                glClear(GL_COLOR_BUFFER_BIT);
                EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 188u, 0u, 255u), 2);
            }
            if (colorEncoding == GL_LINEAR)
            {
                glClear(GL_COLOR_BUFFER_BIT);
                EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);
            }

            // Draw with the texture to a linear framebuffer and check that the color value written
            // is correct.
            testTextureSamplesAs50PercentGreen(texture);

            glBindFramebuffer(GL_FRAMEBUFFER, 0u);
            glBindTexture(GL_TEXTURE_2D, 0u);
            glDeleteTextures(1, &texture);
            glDeleteFramebuffers(1, &fbo);
            eglDestroySurface(display, pbuffer);
        }
    }
}

class D3DTextureTestES3 : public D3DTextureTest
{
  protected:
    D3DTextureTestES3() : D3DTextureTest() {}
};

// Test swizzling a pbuffer created from a D3D texture as a texture image with typeless texture
// formats.
TEST_P(D3DTextureTestES3, TestD3D11TypelessTextureSwizzle)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    ANGLE_SKIP_TEST_IF(!valid());

    // Typeless formats are optional in the spec and currently only supported on D3D11 backend.
    ANGLE_SKIP_TEST_IF(!IsD3D11());

    const std::array<EGLint, 2> eglGlColorspaces = {EGL_GL_COLORSPACE_LINEAR,
                                                    EGL_GL_COLORSPACE_SRGB};
    const std::array<DXGI_FORMAT, 2> dxgiFormats = {DXGI_FORMAT_R8G8B8A8_TYPELESS,
                                                    DXGI_FORMAT_B8G8R8A8_TYPELESS};
    for (auto eglGlColorspace : eglGlColorspaces)
    {
        for (auto dxgiFormat : dxgiFormats)
        {
            SCOPED_TRACE(std::string("Test case:") + std::to_string(eglGlColorspace) + " / " +
                         std::to_string(dxgiFormat));

            EGLint attribs[] = {
                EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
                EGL_GL_COLORSPACE,  eglGlColorspace,  EGL_NONE,           EGL_NONE,
            };

            EGLSurface pbuffer = createD3D11PBuffer(
                32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, dxgiFormat,
                attribs);

            ASSERT_EGL_SUCCESS();
            ASSERT_NE(EGL_NO_SURFACE, pbuffer);

            EGLint colorspace = EGL_NONE;
            eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);

            GLuint texture = 0u;
            glGenTextures(1, &texture);
            glBindTexture(GL_TEXTURE_2D, texture);
            EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
            ASSERT_EGL_SUCCESS();
            ASSERT_EGL_TRUE(result);

            GLuint fbo = 0u;
            glGenFramebuffers(1, &fbo);
            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
            glViewport(0, 0, 32, 32);

            GLint colorEncoding = 0;
            glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                  GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,
                                                  &colorEncoding);

            // Clear the texture with 50% blue and check that the color value written is correct.
            glClearColor(0.0f, 0.0f, 0.5f, 1.0f);

            if (colorEncoding == GL_SRGB_EXT)
            {
                glClear(GL_COLOR_BUFFER_BIT);
                EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 0u, 188u, 255u), 2);
            }
            if (colorEncoding == GL_LINEAR)
            {
                glClear(GL_COLOR_BUFFER_BIT);
                EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 0u, 127u, 255u), 2);
            }

            // Swizzle the green channel to be sampled from the blue channel of the texture and vice
            // versa.
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_GREEN);
            ASSERT_GL_NO_ERROR();

            // Draw with the texture to a linear framebuffer and check that the color value written
            // is correct.
            testTextureSamplesAs50PercentGreen(texture);

            glBindFramebuffer(GL_FRAMEBUFFER, 0u);
            glBindTexture(GL_TEXTURE_2D, 0u);
            glDeleteTextures(1, &texture);
            glDeleteFramebuffers(1, &fbo);
            eglDestroySurface(display, pbuffer);
        }
    }
}

// Test that EGL_GL_COLORSPACE attrib is not allowed for typed D3D textures.
TEST_P(D3DTextureTest, GlColorspaceNotAllowedForTypedD3DTexture)
{
    ANGLE_SKIP_TEST_IF(!valid());

    // D3D11 device is required to be able to create the texture.
    ANGLE_SKIP_TEST_IF(!mD3D11Device);

    // SRGB support is required.
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3);

    EGLint attribsExplicitColorspace[] = {
        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,       EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
        EGL_GL_COLORSPACE,  EGL_GL_COLORSPACE_SRGB, EGL_NONE,           EGL_NONE,
    };
    EGLSurface pbuffer =
        createD3D11PBuffer(32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
                           DXGI_FORMAT_R8G8B8A8_UNORM, attribsExplicitColorspace);

    ASSERT_EGL_ERROR(EGL_BAD_MATCH);
    ASSERT_EQ(EGL_NO_SURFACE, pbuffer);
}

// Test that trying to create a pbuffer from a typeless texture fails as expected on the backends
// where they are known not to be supported.
TEST_P(D3DTextureTest, TypelessD3DTextureNotSupported)
{
    ANGLE_SKIP_TEST_IF(!valid());

    // D3D11 device is required to be able to create the texture.
    ANGLE_SKIP_TEST_IF(!mD3D11Device);

    // Currently typeless textures are supported on the D3D11 backend. We're testing the backends
    // where there is no support.
    ANGLE_SKIP_TEST_IF(IsD3D11());

    // SRGB support is required.
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3);

    EGLint attribs[] = {
        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET,
        EGL_TEXTURE_2D,     EGL_NONE,         EGL_NONE,
    };
    EGLSurface pbuffer =
        createD3D11PBuffer(32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
                           DXGI_FORMAT_R8G8B8A8_TYPELESS, attribs);
    ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
    ASSERT_EQ(EGL_NO_SURFACE, pbuffer);
}

// Test creating a pbuffer with unnecessary EGL_WIDTH and EGL_HEIGHT attributes because that's what
// Chromium does. This is a regression test for crbug.com/794086
TEST_P(D3DTextureTest, UnnecessaryWidthHeightAttributes)
{
    ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
    ASSERT_TRUE(mD3D11Device != nullptr);
    ID3D11Texture2D *texture = nullptr;
    CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET);
    desc.SampleDesc.Count   = 1;
    desc.SampleDesc.Quality = 0;
    EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));

    EGLint attribs[] = {
        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
        EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
        EGL_WIDTH,          1,
        EGL_HEIGHT,         1,
        EGL_NONE,           EGL_NONE,
    };

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();
    EGLConfig config   = window->getConfig();

    EGLSurface pbuffer =
        eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE, texture, config, attribs);

    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    texture->Release();

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Test creating a pbuffer from a d3d surface and clearing it
TEST_P(D3DTextureTest, Clear)
{
    if (!valid())
    {
        return;
    }

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    const size_t bufferSize = 32;

    EGLSurface pbuffer =
        createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    // Apply the Pbuffer and clear it to purple and verify
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
                    255, 255);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Test creating a pbuffer with a D3D texture and depth stencil bits in the EGL config creates keeps
// its depth stencil buffer
TEST_P(D3DTextureTest, DepthStencil)
{
    if (!valid())
    {
        return;
    }

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    const size_t bufferSize = 32;

    EGLSurface pbuffer =
        createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    // Apply the Pbuffer and clear it to purple and verify
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
    glClearDepthf(0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);

    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);

    // Draw a quad that will fail the depth test and verify that the buffer is unchanged
    drawQuad(mTextureProgram, "position", 1.0f);
    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
                          GLColor::cyan);

    // Draw a quad that will pass the depth test and verify that the buffer is green
    drawQuad(mTextureProgram, "position", -1.0f);
    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
                          GLColor::green);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Test creating a pbuffer from a d3d surface and binding it to a texture
TEST_P(D3DTextureTest, BindTexImage)
{
    if (!valid())
    {
        return;
    }

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    const size_t bufferSize = 32;

    EGLSurface pbuffer =
        createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0);
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    // Apply the Pbuffer and clear it to purple
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
                    255, 255);

    // Apply the window surface
    eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());

    // Create a texture and bind the Pbuffer to it
    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_EGL_SUCCESS();

    // Draw a quad and verify that it is purple
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Unbind the texture
    eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    // Verify that purple was drawn
    EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);

    glDeleteTextures(1, &texture);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Verify that creating a pbuffer with a multisampled texture will fail on a non-multisampled
// window.
TEST_P(D3DTextureTest, CheckSampleMismatch)
{
    if (!valid())
    {
        return;
    }

    // Multisampling is not supported on D3D9 or OpenGL.
    ANGLE_SKIP_TEST_IF(IsD3D9() || IsOpenGL());

    constexpr size_t bufferSize = 32;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    EXPECT_EQ(pbuffer, nullptr);
}

// Tests what happens when we make a PBuffer that isn't shader-readable.
TEST_P(D3DTextureTest, NonReadablePBuffer)
{
    ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());

    constexpr size_t bufferSize = 32;

    EGLSurface pbuffer =
        createD3D11PBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
                           D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);

    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));

    // Clear to green.
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Copy the green color to a texture.
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, bufferSize, bufferSize, 0);
    ASSERT_GL_NO_ERROR();

    // Clear to red.
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Draw with the texture and expect green.
    draw2DTexturedQuad(0.5f, 1.0f, false);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

class D3DTextureTestMS : public D3DTextureTest
{
  protected:
    D3DTextureTestMS() : D3DTextureTest()
    {
        setSamples(4);
        setMultisampleEnabled(true);
    }
};

// Test creating a pbuffer from a multisampled d3d surface and clearing it.
TEST_P(D3DTextureTestMS, Clear)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    constexpr size_t bufferSize = 32;
    constexpr UINT testpoint    = bufferSize / 2;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    // Apply the Pbuffer and clear it to magenta and verify
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(testpoint, testpoint, GLColor::magenta);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Test creating a pbuffer from a multisampled d3d surface and drawing with a program.
TEST_P(D3DTextureTestMS, DrawProgram)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    constexpr size_t bufferSize = 32;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    // Apply the Pbuffer and clear it to magenta
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    constexpr GLint testPoint = bufferSize / 2;
    EXPECT_PIXEL_COLOR_EQ(testPoint, testPoint, GLColor::magenta);

    // Apply the window surface
    eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_EGL_SUCCESS();

    // Draw a quad and verify that it is magenta
    glUseProgram(mTextureProgramNoSampling);
    EXPECT_GL_NO_ERROR();

    drawQuad(mTextureProgramNoSampling, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Verify that magenta was drawn
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::magenta);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Test for failure when creating a pbuffer from a multisampled d3d surface to bind to a texture.
TEST_P(D3DTextureTestMS, BindTexture)
{
    constexpr size_t bufferSize = 32;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 4,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));

    EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
    EXPECT_EQ(pbuffer, nullptr);
}

// Verify that creating a pbuffer from a multisampled texture with a multisampled window will fail
// when the sample counts do not match.
TEST_P(D3DTextureTestMS, CheckSampleMismatch)
{
    constexpr size_t bufferSize = 32;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));

    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    EXPECT_EQ(pbuffer, nullptr);
}

// Test creating a pbuffer with a D3D texture and depth stencil bits in the EGL config creates keeps
// its depth stencil buffer
TEST_P(D3DTextureTestMS, DepthStencil)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    const size_t bufferSize = 32;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(EGL_NO_SURFACE, pbuffer);

    // Apply the Pbuffer and clear it to purple and verify
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
    glClearDepthf(0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);

    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);

    // Draw a quad that will fail the depth test and verify that the buffer is unchanged
    drawQuad(mTextureProgram, "position", 1.0f);
    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
                          GLColor::cyan);

    // Draw a quad that will pass the depth test and verify that the buffer is green
    drawQuad(mTextureProgram, "position", -1.0f);
    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
                          GLColor::green);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Test copyTexImage2D with a multisampled resource
TEST_P(D3DTextureTestMS, CopyTexImage2DTest)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    constexpr size_t bufferSize = 32;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(EGL_NO_SURFACE, pbuffer);

    // Apply the Pbuffer and clear it to magenta and verify
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    // Specify a 2D texture and set it to green
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);

    // Copy from the multisampled framebuffer to the 2D texture
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);

    // Draw a quad and verify the color is magenta, not green
    drawQuad(mTextureProgram, "position", 1.0f);
    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
                          GLColor::magenta);
    ASSERT_GL_NO_ERROR();

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

// Test copyTexSubImage2D with a multisampled resource
TEST_P(D3DTextureTestMS, CopyTexSubImage2DTest)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    constexpr size_t bufferSize = 32;

    EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
                                       static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(EGL_NO_SURFACE, pbuffer);

    // Apply the Pbuffer and clear it to magenta and verify
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    // Specify a 2D texture and set it to green
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);

    // Copy from the multisampled framebuffer to the 2D texture
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);

    // Draw a quad and verify the color is magenta, not green
    drawQuad(mTextureProgram, "position", 1.0f);
    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
                          GLColor::magenta);
    ASSERT_GL_NO_ERROR();

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}

TEST_P(D3DTextureTest, ClearTextureImage)
{
    ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    window->makeCurrent();

    const UINT bufferSize = 32;
    EXPECT_TRUE(mD3D11Device != nullptr);
    ID3D11Texture2D *d3d11_texture = nullptr;
    CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,
                               D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
    EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));

    const EGLint attribs[] = {EGL_NONE};

    EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
                                       static_cast<EGLClientBuffer>(d3d11_texture), attribs);
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(image, EGL_NO_IMAGE_KHR);

    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    ASSERT_GL_NO_ERROR();

    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    ASSERT_GL_NO_ERROR();

    GLuint fbo;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
              static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
    ASSERT_GL_NO_ERROR();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
                    255, 255);

    glDeleteFramebuffers(1, &fbo);
    glDeleteTextures(1, &texture);

    d3d11_texture->Release();
}

TEST_P(D3DTextureTest, NonRenderableTextureImage)
{
    ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    window->makeCurrent();

    const UINT bufferSize = 32;
    EXPECT_TRUE(mD3D11Device != nullptr);
    ID3D11Texture2D *d3d11_texture = nullptr;
    CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,
                               D3D11_BIND_SHADER_RESOURCE);
    EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));

    const EGLint attribs[] = {EGL_NONE};

    EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
                                       static_cast<EGLClientBuffer>(d3d11_texture), attribs);
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(image, EGL_NO_IMAGE_KHR);

    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    ASSERT_GL_NO_ERROR();

    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    ASSERT_GL_NO_ERROR();

    GLuint fbo;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
              static_cast<unsigned>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT));
    ASSERT_GL_NO_ERROR();

    glDeleteFramebuffers(1, &fbo);
    glDeleteTextures(1, &texture);

    d3d11_texture->Release();
}

TEST_P(D3DTextureTest, RGBEmulationTextureImage)
{
    ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());

    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    window->makeCurrent();

    const UINT bufferSize = 32;
    EXPECT_TRUE(mD3D11Device != nullptr);
    ID3D11Texture2D *d3d11_texture = nullptr;
    CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,
                               D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
    EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));

    const EGLint attribs[] = {EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RGB, EGL_NONE};

    EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
                                       static_cast<EGLClientBuffer>(d3d11_texture), attribs);
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(image, EGL_NO_IMAGE_KHR);

    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    ASSERT_GL_NO_ERROR();

    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    ASSERT_GL_NO_ERROR();

    GLuint fbo;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
              static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
    ASSERT_GL_NO_ERROR();

    // Although we are writing 0.5 to the alpha channel it should have the same
    // side effects as if alpha were 1.0.
    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 0.5f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
                    255, 255);

    GLuint rgbaRbo;
    glGenRenderbuffers(1, &rgbaRbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rgbaRbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, bufferSize, bufferSize);

    GLuint rgbaFbo;
    glGenFramebuffers(1, &rgbaFbo);
    glBindFramebuffer(GL_FRAMEBUFFER, rgbaFbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rgbaRbo);
    EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
              static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
    ASSERT_GL_NO_ERROR();

    // BlitFramebuffer from/to RGBA framebuffer fails.
    glBindFramebuffer(GL_READ_FRAMEBUFFER, rgbaFbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
    ASSERT_GL_ERROR(GL_INVALID_OPERATION);
    ASSERT_GL_NO_ERROR();

    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rgbaFbo);
    glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
    ASSERT_GL_ERROR(GL_INVALID_OPERATION);
    ASSERT_GL_NO_ERROR();

    GLuint rgbRbo;
    glGenRenderbuffers(1, &rgbRbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rgbRbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, bufferSize, bufferSize);

    GLuint rgbFbo;
    glGenFramebuffers(1, &rgbFbo);
    glBindFramebuffer(GL_FRAMEBUFFER, rgbFbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rgbRbo);
    EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
              static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
    ASSERT_GL_NO_ERROR();
    glClearColor(1.0f, 0.0f, 1.0f, 0.5f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Clear texture framebuffer.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 0, 0, 0,
                    255);

    // BlitFramebuffer from/to RGB framebuffer succeeds.
    glBindFramebuffer(GL_READ_FRAMEBUFFER, rgbFbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
                    255, 255);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rgbFbo);
    glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    glBindFramebuffer(GL_FRAMEBUFFER, rgbFbo);
    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 0, 0, 0,
                    255);

    glDeleteFramebuffers(1, &rgbFbo);
    glDeleteRenderbuffers(1, &rgbRbo);
    glDeleteFramebuffers(1, &rgbaFbo);
    glDeleteRenderbuffers(1, &rgbaRbo);
    glDeleteFramebuffers(1, &fbo);
    glDeleteTextures(1, &texture);

    d3d11_texture->Release();
}

// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2(D3DTextureTest);
ANGLE_INSTANTIATE_TEST_ES3(D3DTextureTestES3);
// D3D Debug device reports an error. http://anglebug.com/3513
// ANGLE_INSTANTIATE_TEST(D3DTextureTestMS, ES2_D3D11());
}  // namespace angle
