Path: blob/main_old/src/tests/gl_tests/D3DTextureTest.cpp
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// D3DTextureTest:6// Tests of the EGL_ANGLE_d3d_texture_client_buffer extension78#include "test_utils/ANGLETest.h"9#include "test_utils/gl_raii.h"1011#include <d3d11.h>12#include <windows.h>1314#include "util/EGLWindow.h"15#include "util/com_utils.h"1617namespace angle18{1920class D3DTextureTest : public ANGLETest21{22protected:23D3DTextureTest()24{25setWindowWidth(128);26setWindowHeight(128);27setConfigRedBits(8);28setConfigGreenBits(8);29setConfigBlueBits(8);30setConfigAlphaBits(8);31setConfigDepthBits(24);32setConfigStencilBits(8);33}3435void testSetUp() override36{37constexpr char kVS[] =38R"(precision highp float;39attribute vec4 position;40varying vec2 texcoord;4142void main()43{44gl_Position = position;45texcoord = (position.xy * 0.5) + 0.5;46texcoord.y = 1.0 - texcoord.y;47})";4849constexpr char kTextureFS[] =50R"(precision highp float;51uniform sampler2D tex;52varying vec2 texcoord;5354void main()55{56gl_FragColor = texture2D(tex, texcoord);57})";5859constexpr char kTextureFSNoSampling[] =60R"(precision highp float;6162void main()63{64gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);65})";6667mTextureProgram = CompileProgram(kVS, kTextureFS);68ASSERT_NE(0u, mTextureProgram) << "shader compilation failed.";6970mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");71ASSERT_NE(-1, mTextureUniformLocation);7273mTextureProgramNoSampling = CompileProgram(kVS, kTextureFSNoSampling);74ASSERT_NE(0u, mTextureProgramNoSampling) << "shader compilation failed.";7576mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));77ASSERT_NE(nullptr, mD3D11Module);7879PFN_D3D11_CREATE_DEVICE createDeviceFunc = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(80GetProcAddress(mD3D11Module, "D3D11CreateDevice"));8182EGLWindow *window = getEGLWindow();83EGLDisplay display = window->getDisplay();84EGLDeviceEXT device = EGL_NO_DEVICE_EXT;85if (IsEGLClientExtensionEnabled("EGL_EXT_device_query"))86{87EGLAttrib result = 0;88EXPECT_EGL_TRUE(eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, &result));89device = reinterpret_cast<EGLDeviceEXT>(result);90}9192ASSERT_NE(EGL_NO_DEVICE_EXT, device);9394if (IsEGLDeviceExtensionEnabled(device, "EGL_ANGLE_device_d3d"))95{96EGLAttrib result = 0;97if (eglQueryDeviceAttribEXT(device, EGL_D3D11_DEVICE_ANGLE, &result))98{99mD3D11Device = reinterpret_cast<ID3D11Device *>(result);100mD3D11Device->AddRef();101}102else if (eglQueryDeviceAttribEXT(device, EGL_D3D9_DEVICE_ANGLE, &result))103{104mD3D9Device = reinterpret_cast<IDirect3DDevice9 *>(result);105mD3D9Device->AddRef();106}107}108else109{110ASSERT_TRUE(111SUCCEEDED(createDeviceFunc(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr,1120, D3D11_SDK_VERSION, &mD3D11Device, nullptr, nullptr)));113}114}115116void testTearDown() override117{118glDeleteProgram(mTextureProgram);119glDeleteProgram(mTextureProgramNoSampling);120121if (mD3D11Device)122{123mD3D11Device->Release();124mD3D11Device = nullptr;125}126127FreeLibrary(mD3D11Module);128mD3D11Module = nullptr;129130if (mD3D9Device)131{132mD3D9Device->Release();133mD3D9Device = nullptr;134}135}136137EGLSurface createD3D11PBuffer(size_t width,138size_t height,139UINT sampleCount,140UINT sampleQuality,141UINT bindFlags,142DXGI_FORMAT format,143const EGLint *attribs)144{145EGLWindow *window = getEGLWindow();146EGLDisplay display = window->getDisplay();147EGLConfig config = window->getConfig();148149EXPECT_TRUE(mD3D11Device != nullptr);150ID3D11Texture2D *texture = nullptr;151CD3D11_TEXTURE2D_DESC desc(format, static_cast<UINT>(width), static_cast<UINT>(height), 1,1521, bindFlags);153desc.SampleDesc.Count = sampleCount;154desc.SampleDesc.Quality = sampleQuality;155EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));156157EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,158texture, config, attribs);159160texture->Release();161162return pbuffer;163}164165EGLSurface createD3D11PBuffer(size_t width,166size_t height,167EGLint eglTextureFormat,168EGLint eglTextureTarget,169UINT sampleCount,170UINT sampleQuality,171UINT bindFlags,172DXGI_FORMAT format)173{174EGLint attribs[] = {175EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET,176eglTextureTarget, EGL_NONE, EGL_NONE,177};178return createD3D11PBuffer(width, height, sampleCount, sampleQuality, bindFlags, format,179attribs);180}181182EGLSurface createPBuffer(size_t width,183size_t height,184EGLint eglTextureFormat,185EGLint eglTextureTarget,186UINT sampleCount,187UINT sampleQuality)188{189if (mD3D11Device)190{191return createD3D11PBuffer(192width, height, eglTextureFormat, eglTextureTarget, sampleCount, sampleQuality,193D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);194}195196if (mD3D9Device)197{198EGLWindow *window = getEGLWindow();199EGLDisplay display = window->getDisplay();200EGLConfig config = window->getConfig();201202EGLint attribs[] = {203EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET,204eglTextureTarget, EGL_NONE, EGL_NONE,205};206207// Multisampled textures are not supported on D3D9.208EXPECT_TRUE(sampleCount <= 1);209EXPECT_TRUE(sampleQuality == 0);210211IDirect3DTexture9 *texture = nullptr;212EXPECT_TRUE(SUCCEEDED(mD3D9Device->CreateTexture(213static_cast<UINT>(width), static_cast<UINT>(height), 1, D3DUSAGE_RENDERTARGET,214D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, nullptr)));215216EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,217texture, config, attribs);218219texture->Release();220221return pbuffer;222}223else224{225return EGL_NO_SURFACE;226}227}228229bool valid() const230{231EGLWindow *window = getEGLWindow();232EGLDisplay display = window->getDisplay();233if (!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_d3d_texture_client_buffer"))234{235std::cout << "Test skipped due to missing EGL_ANGLE_d3d_texture_client_buffer"236<< std::endl;237return false;238}239240if (!mD3D11Device && !mD3D9Device)241{242std::cout << "Test skipped due to no D3D devices being available." << std::endl;243return false;244}245246if (IsWindows() && IsAMD() && IsOpenGL())247{248std::cout << "Test skipped on Windows AMD OpenGL." << std::endl;249return false;250}251252if (IsWindows() && IsIntel() && IsOpenGL())253{254std::cout << "Test skipped on Windows Intel OpenGL." << std::endl;255return false;256}257return true;258}259260void testTextureSamplesAs50PercentGreen(GLuint texture)261{262GLFramebuffer scratchFbo;263glBindFramebuffer(GL_FRAMEBUFFER, scratchFbo);264GLTexture scratchTexture;265glBindTexture(GL_TEXTURE_2D, scratchTexture);266glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);267glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, scratchTexture,2680);269270glClearColor(1.0f, 0.0f, 0.0f, 1.0f);271glClear(GL_COLOR_BUFFER_BIT);272273glUseProgram(mTextureProgram);274glUniform1i(mTextureUniformLocation, 0);275glActiveTexture(GL_TEXTURE0);276glBindTexture(GL_TEXTURE_2D, texture);277glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);278glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);279glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);280glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);281282drawQuad(mTextureProgram, "position", 0.5f);283ASSERT_GL_NO_ERROR();284285EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);286}287288GLuint mTextureProgram;289GLuint mTextureProgramNoSampling;290GLint mTextureUniformLocation;291292HMODULE mD3D11Module = nullptr;293ID3D11Device *mD3D11Device = nullptr;294295IDirect3DDevice9 *mD3D9Device = nullptr;296};297298// Test creating pbuffer from textures with several different DXGI formats.299TEST_P(D3DTextureTest, TestD3D11SupportedFormatsSurface)300{301bool srgbSupported = IsGLExtensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3;302ANGLE_SKIP_TEST_IF(!valid() || !mD3D11Device || !srgbSupported);303304const DXGI_FORMAT formats[] = {DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,305DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB};306for (size_t i = 0; i < 4; ++i)307{308if (formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)309{310if (IsOpenGL())311{312// This generates an invalid format error when calling wglDXRegisterObjectNV().313// Reproducible at least on NVIDIA driver 390.65 on Windows 10.314std::cout << "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB subtest skipped: IsOpenGL().\n";315continue;316}317}318319EGLSurface pbuffer = createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,320D3D11_BIND_RENDER_TARGET, formats[i]);321ASSERT_EGL_SUCCESS();322ASSERT_NE(EGL_NO_SURFACE, pbuffer);323324EGLWindow *window = getEGLWindow();325EGLDisplay display = window->getDisplay();326327EGLint colorspace = EGL_NONE;328eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);329330if (formats[i] == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ||331formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)332{333EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);334}335else336{337EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);338}339340eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());341ASSERT_EGL_SUCCESS();342window->makeCurrent();343eglDestroySurface(display, pbuffer);344}345}346347// Test binding a pbuffer created from a D3D texture as a texture image with several different DXGI348// formats. The test renders to and samples from the pbuffer.349TEST_P(D3DTextureTest, TestD3D11SupportedFormatsTexture)350{351bool srgb8alpha8TextureAttachmentSupported = getClientMajorVersion() >= 3;352ANGLE_SKIP_TEST_IF(!valid() || !mD3D11Device || !srgb8alpha8TextureAttachmentSupported);353354bool srgbWriteControlSupported =355IsGLExtensionEnabled("GL_EXT_sRGB_write_control") && !IsOpenGL();356357const DXGI_FORMAT formats[] = {DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM,358DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,359DXGI_FORMAT_B8G8R8A8_UNORM_SRGB};360for (size_t i = 0; i < 4; ++i)361{362if (formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)363{364if (IsOpenGL())365{366// This generates an invalid format error when calling wglDXRegisterObjectNV().367// Reproducible at least on NVIDIA driver 390.65 on Windows 10.368std::cout << "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB subtest skipped: IsOpenGL().\n";369continue;370}371}372373SCOPED_TRACE(std::string("Test case:") + std::to_string(i));374EGLWindow *window = getEGLWindow();375EGLDisplay display = window->getDisplay();376377EGLSurface pbuffer =378createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,379D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, formats[i]);380ASSERT_EGL_SUCCESS();381ASSERT_NE(EGL_NO_SURFACE, pbuffer);382383EGLint colorspace = EGL_NONE;384eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);385386GLuint texture = 0u;387glGenTextures(1, &texture);388glBindTexture(GL_TEXTURE_2D, texture);389EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);390ASSERT_EGL_SUCCESS();391ASSERT_EGL_TRUE(result);392393GLuint fbo = 0u;394glGenFramebuffers(1, &fbo);395glBindFramebuffer(GL_FRAMEBUFFER, fbo);396glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);397glViewport(0, 0, 32, 32);398399GLint colorEncoding = 0;400glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,401GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,402&colorEncoding);403404if (formats[i] == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ||405formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)406{407EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);408EXPECT_EQ(GL_SRGB_EXT, colorEncoding);409}410else411{412EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);413EXPECT_EQ(GL_LINEAR, colorEncoding);414}415416// Clear the texture with 50% green and check that the color value written is correct.417glClearColor(0.0f, 0.5f, 0.0f, 1.0f);418419if (colorEncoding == GL_SRGB_EXT)420{421glClear(GL_COLOR_BUFFER_BIT);422EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 188u, 0u, 255u), 2);423// Disable SRGB and run the non-sRGB test case.424if (srgbWriteControlSupported)425glDisable(GL_FRAMEBUFFER_SRGB_EXT);426}427428if (colorEncoding == GL_LINEAR || srgbWriteControlSupported)429{430glClear(GL_COLOR_BUFFER_BIT);431EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);432}433434// Draw with the texture to a linear framebuffer and check that the color value written is435// correct.436testTextureSamplesAs50PercentGreen(texture);437438glBindFramebuffer(GL_FRAMEBUFFER, 0u);439glBindTexture(GL_TEXTURE_2D, 0u);440glDeleteTextures(1, &texture);441glDeleteFramebuffers(1, &fbo);442eglDestroySurface(display, pbuffer);443}444}445446// Test binding a pbuffer created from a D3D texture as a texture image with typeless texture447// formats.448TEST_P(D3DTextureTest, TestD3D11TypelessTexture)449{450EGLWindow *window = getEGLWindow();451EGLDisplay display = window->getDisplay();452453ANGLE_SKIP_TEST_IF(!valid());454455// Typeless formats are optional in the spec and currently only supported on D3D11 backend.456ANGLE_SKIP_TEST_IF(!IsD3D11());457458// GL_SRGB8_ALPHA8 texture attachment support is required.459ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);460461const std::array<EGLint, 2> eglGlColorspaces = {EGL_GL_COLORSPACE_LINEAR,462EGL_GL_COLORSPACE_SRGB};463const std::array<DXGI_FORMAT, 2> dxgiFormats = {DXGI_FORMAT_R8G8B8A8_TYPELESS,464DXGI_FORMAT_B8G8R8A8_TYPELESS};465for (auto eglGlColorspace : eglGlColorspaces)466{467for (auto dxgiFormat : dxgiFormats)468{469SCOPED_TRACE(std::string("Test case:") + std::to_string(eglGlColorspace) + " / " +470std::to_string(dxgiFormat));471472EGLint attribs[] = {473EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,474EGL_GL_COLORSPACE, eglGlColorspace, EGL_NONE, EGL_NONE,475};476477EGLSurface pbuffer = createD3D11PBuffer(47832, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, dxgiFormat,479attribs);480481ASSERT_EGL_SUCCESS();482ASSERT_NE(EGL_NO_SURFACE, pbuffer);483484EGLint colorspace = EGL_NONE;485eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);486487GLuint texture = 0u;488glGenTextures(1, &texture);489glBindTexture(GL_TEXTURE_2D, texture);490EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);491ASSERT_EGL_SUCCESS();492ASSERT_EGL_TRUE(result);493494GLuint fbo = 0u;495glGenFramebuffers(1, &fbo);496glBindFramebuffer(GL_FRAMEBUFFER, fbo);497glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);498glViewport(0, 0, 32, 32);499500GLint colorEncoding = 0;501glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,502GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,503&colorEncoding);504505if (eglGlColorspace == EGL_GL_COLORSPACE_LINEAR)506{507EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);508EXPECT_EQ(GL_LINEAR, colorEncoding);509}510else511{512EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);513EXPECT_EQ(GL_SRGB_EXT, colorEncoding);514}515516// Clear the texture with 50% green and check that the color value written is correct.517glClearColor(0.0f, 0.5f, 0.0f, 1.0f);518519if (colorEncoding == GL_SRGB_EXT)520{521glClear(GL_COLOR_BUFFER_BIT);522EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 188u, 0u, 255u), 2);523}524if (colorEncoding == GL_LINEAR)525{526glClear(GL_COLOR_BUFFER_BIT);527EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);528}529530// Draw with the texture to a linear framebuffer and check that the color value written531// is correct.532testTextureSamplesAs50PercentGreen(texture);533534glBindFramebuffer(GL_FRAMEBUFFER, 0u);535glBindTexture(GL_TEXTURE_2D, 0u);536glDeleteTextures(1, &texture);537glDeleteFramebuffers(1, &fbo);538eglDestroySurface(display, pbuffer);539}540}541}542543class D3DTextureTestES3 : public D3DTextureTest544{545protected:546D3DTextureTestES3() : D3DTextureTest() {}547};548549// Test swizzling a pbuffer created from a D3D texture as a texture image with typeless texture550// formats.551TEST_P(D3DTextureTestES3, TestD3D11TypelessTextureSwizzle)552{553EGLWindow *window = getEGLWindow();554EGLDisplay display = window->getDisplay();555556ANGLE_SKIP_TEST_IF(!valid());557558// Typeless formats are optional in the spec and currently only supported on D3D11 backend.559ANGLE_SKIP_TEST_IF(!IsD3D11());560561const std::array<EGLint, 2> eglGlColorspaces = {EGL_GL_COLORSPACE_LINEAR,562EGL_GL_COLORSPACE_SRGB};563const std::array<DXGI_FORMAT, 2> dxgiFormats = {DXGI_FORMAT_R8G8B8A8_TYPELESS,564DXGI_FORMAT_B8G8R8A8_TYPELESS};565for (auto eglGlColorspace : eglGlColorspaces)566{567for (auto dxgiFormat : dxgiFormats)568{569SCOPED_TRACE(std::string("Test case:") + std::to_string(eglGlColorspace) + " / " +570std::to_string(dxgiFormat));571572EGLint attribs[] = {573EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,574EGL_GL_COLORSPACE, eglGlColorspace, EGL_NONE, EGL_NONE,575};576577EGLSurface pbuffer = createD3D11PBuffer(57832, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, dxgiFormat,579attribs);580581ASSERT_EGL_SUCCESS();582ASSERT_NE(EGL_NO_SURFACE, pbuffer);583584EGLint colorspace = EGL_NONE;585eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);586587GLuint texture = 0u;588glGenTextures(1, &texture);589glBindTexture(GL_TEXTURE_2D, texture);590EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);591ASSERT_EGL_SUCCESS();592ASSERT_EGL_TRUE(result);593594GLuint fbo = 0u;595glGenFramebuffers(1, &fbo);596glBindFramebuffer(GL_FRAMEBUFFER, fbo);597glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);598glViewport(0, 0, 32, 32);599600GLint colorEncoding = 0;601glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,602GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,603&colorEncoding);604605// Clear the texture with 50% blue and check that the color value written is correct.606glClearColor(0.0f, 0.0f, 0.5f, 1.0f);607608if (colorEncoding == GL_SRGB_EXT)609{610glClear(GL_COLOR_BUFFER_BIT);611EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 0u, 188u, 255u), 2);612}613if (colorEncoding == GL_LINEAR)614{615glClear(GL_COLOR_BUFFER_BIT);616EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 0u, 127u, 255u), 2);617}618619// Swizzle the green channel to be sampled from the blue channel of the texture and vice620// versa.621glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);622glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_GREEN);623ASSERT_GL_NO_ERROR();624625// Draw with the texture to a linear framebuffer and check that the color value written626// is correct.627testTextureSamplesAs50PercentGreen(texture);628629glBindFramebuffer(GL_FRAMEBUFFER, 0u);630glBindTexture(GL_TEXTURE_2D, 0u);631glDeleteTextures(1, &texture);632glDeleteFramebuffers(1, &fbo);633eglDestroySurface(display, pbuffer);634}635}636}637638// Test that EGL_GL_COLORSPACE attrib is not allowed for typed D3D textures.639TEST_P(D3DTextureTest, GlColorspaceNotAllowedForTypedD3DTexture)640{641ANGLE_SKIP_TEST_IF(!valid());642643// D3D11 device is required to be able to create the texture.644ANGLE_SKIP_TEST_IF(!mD3D11Device);645646// SRGB support is required.647ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3);648649EGLint attribsExplicitColorspace[] = {650EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,651EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, EGL_NONE, EGL_NONE,652};653EGLSurface pbuffer =654createD3D11PBuffer(32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,655DXGI_FORMAT_R8G8B8A8_UNORM, attribsExplicitColorspace);656657ASSERT_EGL_ERROR(EGL_BAD_MATCH);658ASSERT_EQ(EGL_NO_SURFACE, pbuffer);659}660661// Test that trying to create a pbuffer from a typeless texture fails as expected on the backends662// where they are known not to be supported.663TEST_P(D3DTextureTest, TypelessD3DTextureNotSupported)664{665ANGLE_SKIP_TEST_IF(!valid());666667// D3D11 device is required to be able to create the texture.668ANGLE_SKIP_TEST_IF(!mD3D11Device);669670// Currently typeless textures are supported on the D3D11 backend. We're testing the backends671// where there is no support.672ANGLE_SKIP_TEST_IF(IsD3D11());673674// SRGB support is required.675ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3);676677EGLint attribs[] = {678EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET,679EGL_TEXTURE_2D, EGL_NONE, EGL_NONE,680};681EGLSurface pbuffer =682createD3D11PBuffer(32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,683DXGI_FORMAT_R8G8B8A8_TYPELESS, attribs);684ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);685ASSERT_EQ(EGL_NO_SURFACE, pbuffer);686}687688// Test creating a pbuffer with unnecessary EGL_WIDTH and EGL_HEIGHT attributes because that's what689// Chromium does. This is a regression test for crbug.com/794086690TEST_P(D3DTextureTest, UnnecessaryWidthHeightAttributes)691{692ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());693ASSERT_TRUE(mD3D11Device != nullptr);694ID3D11Texture2D *texture = nullptr;695CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET);696desc.SampleDesc.Count = 1;697desc.SampleDesc.Quality = 0;698EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));699700EGLint attribs[] = {701EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,702EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,703EGL_WIDTH, 1,704EGL_HEIGHT, 1,705EGL_NONE, EGL_NONE,706};707708EGLWindow *window = getEGLWindow();709EGLDisplay display = window->getDisplay();710EGLConfig config = window->getConfig();711712EGLSurface pbuffer =713eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE, texture, config, attribs);714715ASSERT_EGL_SUCCESS();716ASSERT_NE(pbuffer, EGL_NO_SURFACE);717718texture->Release();719720// Make current with fixture EGL to ensure the Surface can be released immediately.721getEGLWindow()->makeCurrent();722eglDestroySurface(display, pbuffer);723}724725// Test creating a pbuffer from a d3d surface and clearing it726TEST_P(D3DTextureTest, Clear)727{728if (!valid())729{730return;731}732733EGLWindow *window = getEGLWindow();734EGLDisplay display = window->getDisplay();735736const size_t bufferSize = 32;737738EGLSurface pbuffer =739createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);740ASSERT_EGL_SUCCESS();741ASSERT_NE(pbuffer, EGL_NO_SURFACE);742743// Apply the Pbuffer and clear it to purple and verify744eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());745ASSERT_EGL_SUCCESS();746747glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));748glClearColor(1.0f, 0.0f, 1.0f, 1.0f);749glClear(GL_COLOR_BUFFER_BIT);750ASSERT_GL_NO_ERROR();751752EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,753255, 255);754755// Make current with fixture EGL to ensure the Surface can be released immediately.756getEGLWindow()->makeCurrent();757eglDestroySurface(display, pbuffer);758}759760// Test creating a pbuffer with a D3D texture and depth stencil bits in the EGL config creates keeps761// its depth stencil buffer762TEST_P(D3DTextureTest, DepthStencil)763{764if (!valid())765{766return;767}768769EGLWindow *window = getEGLWindow();770EGLDisplay display = window->getDisplay();771772const size_t bufferSize = 32;773774EGLSurface pbuffer =775createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);776ASSERT_EGL_SUCCESS();777ASSERT_NE(pbuffer, EGL_NO_SURFACE);778779// Apply the Pbuffer and clear it to purple and verify780eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());781ASSERT_EGL_SUCCESS();782783glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));784glClearColor(0.0f, 1.0f, 1.0f, 1.0f);785glClearDepthf(0.5f);786glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);787ASSERT_GL_NO_ERROR();788789glEnable(GL_DEPTH_TEST);790glDepthMask(GL_FALSE);791792glUseProgram(mTextureProgram);793glUniform1i(mTextureUniformLocation, 0);794795glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);796797// Draw a quad that will fail the depth test and verify that the buffer is unchanged798drawQuad(mTextureProgram, "position", 1.0f);799EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,800GLColor::cyan);801802// Draw a quad that will pass the depth test and verify that the buffer is green803drawQuad(mTextureProgram, "position", -1.0f);804EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,805GLColor::green);806807// Make current with fixture EGL to ensure the Surface can be released immediately.808getEGLWindow()->makeCurrent();809eglDestroySurface(display, pbuffer);810}811812// Test creating a pbuffer from a d3d surface and binding it to a texture813TEST_P(D3DTextureTest, BindTexImage)814{815if (!valid())816{817return;818}819820EGLWindow *window = getEGLWindow();821EGLDisplay display = window->getDisplay();822823const size_t bufferSize = 32;824825EGLSurface pbuffer =826createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0);827ASSERT_EGL_SUCCESS();828ASSERT_NE(pbuffer, EGL_NO_SURFACE);829830// Apply the Pbuffer and clear it to purple831eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());832ASSERT_EGL_SUCCESS();833834glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));835glClearColor(1.0f, 0.0f, 1.0f, 1.0f);836glClear(GL_COLOR_BUFFER_BIT);837ASSERT_GL_NO_ERROR();838839EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,840255, 255);841842// Apply the window surface843eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());844845// Create a texture and bind the Pbuffer to it846GLuint texture = 0;847glGenTextures(1, &texture);848glBindTexture(GL_TEXTURE_2D, texture);849glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);850glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);851glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);852glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);853EXPECT_GL_NO_ERROR();854855eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);856glViewport(0, 0, getWindowWidth(), getWindowHeight());857ASSERT_EGL_SUCCESS();858859// Draw a quad and verify that it is purple860glUseProgram(mTextureProgram);861glUniform1i(mTextureUniformLocation, 0);862863drawQuad(mTextureProgram, "position", 0.5f);864EXPECT_GL_NO_ERROR();865866// Unbind the texture867eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER);868ASSERT_EGL_SUCCESS();869870// Verify that purple was drawn871EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);872873glDeleteTextures(1, &texture);874875// Make current with fixture EGL to ensure the Surface can be released immediately.876getEGLWindow()->makeCurrent();877eglDestroySurface(display, pbuffer);878}879880// Verify that creating a pbuffer with a multisampled texture will fail on a non-multisampled881// window.882TEST_P(D3DTextureTest, CheckSampleMismatch)883{884if (!valid())885{886return;887}888889// Multisampling is not supported on D3D9 or OpenGL.890ANGLE_SKIP_TEST_IF(IsD3D9() || IsOpenGL());891892constexpr size_t bufferSize = 32;893894EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,895static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));896EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);897EXPECT_EQ(pbuffer, nullptr);898}899900// Tests what happens when we make a PBuffer that isn't shader-readable.901TEST_P(D3DTextureTest, NonReadablePBuffer)902{903ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());904905constexpr size_t bufferSize = 32;906907EGLSurface pbuffer =908createD3D11PBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,909D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);910911ASSERT_EGL_SUCCESS();912ASSERT_NE(pbuffer, EGL_NO_SURFACE);913914EGLWindow *window = getEGLWindow();915EGLDisplay display = window->getDisplay();916917eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());918ASSERT_EGL_SUCCESS();919920glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));921922// Clear to green.923glClearColor(0.0f, 1.0f, 0.0f, 1.0f);924glClear(GL_COLOR_BUFFER_BIT);925ASSERT_GL_NO_ERROR();926EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);927928// Copy the green color to a texture.929GLTexture tex;930glBindTexture(GL_TEXTURE_2D, tex);931glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);932glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);933glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, bufferSize, bufferSize, 0);934ASSERT_GL_NO_ERROR();935936// Clear to red.937glClearColor(1.0f, 0.0f, 0.0f, 1.0f);938glClear(GL_COLOR_BUFFER_BIT);939ASSERT_GL_NO_ERROR();940EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);941942// Draw with the texture and expect green.943draw2DTexturedQuad(0.5f, 1.0f, false);944EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);945946// Make current with fixture EGL to ensure the Surface can be released immediately.947getEGLWindow()->makeCurrent();948eglDestroySurface(display, pbuffer);949}950951class D3DTextureTestMS : public D3DTextureTest952{953protected:954D3DTextureTestMS() : D3DTextureTest()955{956setSamples(4);957setMultisampleEnabled(true);958}959};960961// Test creating a pbuffer from a multisampled d3d surface and clearing it.962TEST_P(D3DTextureTestMS, Clear)963{964EGLWindow *window = getEGLWindow();965EGLDisplay display = window->getDisplay();966967constexpr size_t bufferSize = 32;968constexpr UINT testpoint = bufferSize / 2;969970EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,971static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));972ASSERT_EGL_SUCCESS();973ASSERT_NE(pbuffer, EGL_NO_SURFACE);974975// Apply the Pbuffer and clear it to magenta and verify976eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());977ASSERT_EGL_SUCCESS();978979glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));980glClearColor(1.0f, 0.0f, 1.0f, 1.0f);981glClear(GL_COLOR_BUFFER_BIT);982ASSERT_GL_NO_ERROR();983EXPECT_PIXEL_COLOR_EQ(testpoint, testpoint, GLColor::magenta);984985// Make current with fixture EGL to ensure the Surface can be released immediately.986getEGLWindow()->makeCurrent();987eglDestroySurface(display, pbuffer);988}989990// Test creating a pbuffer from a multisampled d3d surface and drawing with a program.991TEST_P(D3DTextureTestMS, DrawProgram)992{993EGLWindow *window = getEGLWindow();994EGLDisplay display = window->getDisplay();995996constexpr size_t bufferSize = 32;997998EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,999static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));1000ASSERT_EGL_SUCCESS();1001ASSERT_NE(pbuffer, EGL_NO_SURFACE);10021003// Apply the Pbuffer and clear it to magenta1004eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());1005ASSERT_EGL_SUCCESS();10061007glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));1008glClearColor(1.0f, 0.0f, 1.0f, 1.0f);1009glClear(GL_COLOR_BUFFER_BIT);1010ASSERT_GL_NO_ERROR();10111012constexpr GLint testPoint = bufferSize / 2;1013EXPECT_PIXEL_COLOR_EQ(testPoint, testPoint, GLColor::magenta);10141015// Apply the window surface1016eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());1017ASSERT_EGL_SUCCESS();10181019glViewport(0, 0, getWindowWidth(), getWindowHeight());1020ASSERT_EGL_SUCCESS();10211022// Draw a quad and verify that it is magenta1023glUseProgram(mTextureProgramNoSampling);1024EXPECT_GL_NO_ERROR();10251026drawQuad(mTextureProgramNoSampling, "position", 0.5f);1027EXPECT_GL_NO_ERROR();10281029// Verify that magenta was drawn1030EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::magenta);10311032// Make current with fixture EGL to ensure the Surface can be released immediately.1033getEGLWindow()->makeCurrent();1034eglDestroySurface(display, pbuffer);1035}10361037// Test for failure when creating a pbuffer from a multisampled d3d surface to bind to a texture.1038TEST_P(D3DTextureTestMS, BindTexture)1039{1040constexpr size_t bufferSize = 32;10411042EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 4,1043static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));10441045EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1046EXPECT_EQ(pbuffer, nullptr);1047}10481049// Verify that creating a pbuffer from a multisampled texture with a multisampled window will fail1050// when the sample counts do not match.1051TEST_P(D3DTextureTestMS, CheckSampleMismatch)1052{1053constexpr size_t bufferSize = 32;10541055EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,1056static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));10571058EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);1059EXPECT_EQ(pbuffer, nullptr);1060}10611062// Test creating a pbuffer with a D3D texture and depth stencil bits in the EGL config creates keeps1063// its depth stencil buffer1064TEST_P(D3DTextureTestMS, DepthStencil)1065{1066EGLWindow *window = getEGLWindow();1067EGLDisplay display = window->getDisplay();10681069const size_t bufferSize = 32;10701071EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,1072static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));1073ASSERT_EGL_SUCCESS();1074ASSERT_NE(EGL_NO_SURFACE, pbuffer);10751076// Apply the Pbuffer and clear it to purple and verify1077eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());1078ASSERT_EGL_SUCCESS();10791080glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));1081glClearColor(0.0f, 1.0f, 1.0f, 1.0f);1082glClearDepthf(0.5f);1083glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);1084ASSERT_GL_NO_ERROR();10851086glEnable(GL_DEPTH_TEST);1087glDepthMask(GL_FALSE);10881089glUseProgram(mTextureProgram);1090glUniform1i(mTextureUniformLocation, 0);10911092glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);10931094// Draw a quad that will fail the depth test and verify that the buffer is unchanged1095drawQuad(mTextureProgram, "position", 1.0f);1096EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,1097GLColor::cyan);10981099// Draw a quad that will pass the depth test and verify that the buffer is green1100drawQuad(mTextureProgram, "position", -1.0f);1101EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,1102GLColor::green);11031104// Make current with fixture EGL to ensure the Surface can be released immediately.1105getEGLWindow()->makeCurrent();1106eglDestroySurface(display, pbuffer);1107}11081109// Test copyTexImage2D with a multisampled resource1110TEST_P(D3DTextureTestMS, CopyTexImage2DTest)1111{1112EGLWindow *window = getEGLWindow();1113EGLDisplay display = window->getDisplay();11141115constexpr size_t bufferSize = 32;11161117EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,1118static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));1119ASSERT_EGL_SUCCESS();1120ASSERT_NE(EGL_NO_SURFACE, pbuffer);11211122// Apply the Pbuffer and clear it to magenta and verify1123eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());1124ASSERT_EGL_SUCCESS();11251126glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));1127glClearColor(1.0f, 0.0f, 1.0f, 1.0f);1128glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);1129ASSERT_GL_NO_ERROR();11301131glUseProgram(mTextureProgram);1132glUniform1i(mTextureUniformLocation, 0);11331134// Specify a 2D texture and set it to green1135glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);11361137// Copy from the multisampled framebuffer to the 2D texture1138glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);11391140// Draw a quad and verify the color is magenta, not green1141drawQuad(mTextureProgram, "position", 1.0f);1142EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,1143GLColor::magenta);1144ASSERT_GL_NO_ERROR();11451146// Make current with fixture EGL to ensure the Surface can be released immediately.1147getEGLWindow()->makeCurrent();1148eglDestroySurface(display, pbuffer);1149}11501151// Test copyTexSubImage2D with a multisampled resource1152TEST_P(D3DTextureTestMS, CopyTexSubImage2DTest)1153{1154EGLWindow *window = getEGLWindow();1155EGLDisplay display = window->getDisplay();11561157constexpr size_t bufferSize = 32;11581159EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,1160static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));1161ASSERT_EGL_SUCCESS();1162ASSERT_NE(EGL_NO_SURFACE, pbuffer);11631164// Apply the Pbuffer and clear it to magenta and verify1165eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());1166ASSERT_EGL_SUCCESS();11671168glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));1169glClearColor(1.0f, 0.0f, 1.0f, 1.0f);1170glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);1171ASSERT_GL_NO_ERROR();11721173glUseProgram(mTextureProgram);1174glUniform1i(mTextureUniformLocation, 0);11751176// Specify a 2D texture and set it to green1177glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);11781179// Copy from the multisampled framebuffer to the 2D texture1180glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);11811182// Draw a quad and verify the color is magenta, not green1183drawQuad(mTextureProgram, "position", 1.0f);1184EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,1185GLColor::magenta);1186ASSERT_GL_NO_ERROR();11871188// Make current with fixture EGL to ensure the Surface can be released immediately.1189getEGLWindow()->makeCurrent();1190eglDestroySurface(display, pbuffer);1191}11921193TEST_P(D3DTextureTest, ClearTextureImage)1194{1195ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());11961197EGLWindow *window = getEGLWindow();1198EGLDisplay display = window->getDisplay();11991200window->makeCurrent();12011202const UINT bufferSize = 32;1203EXPECT_TRUE(mD3D11Device != nullptr);1204ID3D11Texture2D *d3d11_texture = nullptr;1205CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,1206D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);1207EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));12081209const EGLint attribs[] = {EGL_NONE};12101211EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,1212static_cast<EGLClientBuffer>(d3d11_texture), attribs);1213ASSERT_EGL_SUCCESS();1214ASSERT_NE(image, EGL_NO_IMAGE_KHR);12151216GLuint texture;1217glGenTextures(1, &texture);1218glBindTexture(GL_TEXTURE_2D, texture);1219glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1220glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1221glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1222glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1223ASSERT_GL_NO_ERROR();12241225glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);1226ASSERT_GL_NO_ERROR();12271228GLuint fbo;1229glGenFramebuffers(1, &fbo);1230glBindFramebuffer(GL_FRAMEBUFFER, fbo);1231glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);1232EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),1233static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));1234ASSERT_GL_NO_ERROR();12351236glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));1237glClearColor(1.0f, 0.0f, 1.0f, 1.0f);1238glClear(GL_COLOR_BUFFER_BIT);1239ASSERT_GL_NO_ERROR();1240EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,1241255, 255);12421243glDeleteFramebuffers(1, &fbo);1244glDeleteTextures(1, &texture);1245eglDestroyImageKHR(display, image);12461247d3d11_texture->Release();1248}12491250TEST_P(D3DTextureTest, NonRenderableTextureImage)1251{1252ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());12531254EGLWindow *window = getEGLWindow();1255EGLDisplay display = window->getDisplay();12561257window->makeCurrent();12581259const UINT bufferSize = 32;1260EXPECT_TRUE(mD3D11Device != nullptr);1261ID3D11Texture2D *d3d11_texture = nullptr;1262CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,1263D3D11_BIND_SHADER_RESOURCE);1264EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));12651266const EGLint attribs[] = {EGL_NONE};12671268EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,1269static_cast<EGLClientBuffer>(d3d11_texture), attribs);1270ASSERT_EGL_SUCCESS();1271ASSERT_NE(image, EGL_NO_IMAGE_KHR);12721273GLuint texture;1274glGenTextures(1, &texture);1275glBindTexture(GL_TEXTURE_2D, texture);1276glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1277glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1278glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1279glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1280ASSERT_GL_NO_ERROR();12811282glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);1283ASSERT_GL_NO_ERROR();12841285GLuint fbo;1286glGenFramebuffers(1, &fbo);1287glBindFramebuffer(GL_FRAMEBUFFER, fbo);1288glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);1289EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),1290static_cast<unsigned>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT));1291ASSERT_GL_NO_ERROR();12921293glDeleteFramebuffers(1, &fbo);1294glDeleteTextures(1, &texture);1295eglDestroyImageKHR(display, image);12961297d3d11_texture->Release();1298}12991300TEST_P(D3DTextureTest, RGBEmulationTextureImage)1301{1302ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());13031304EGLWindow *window = getEGLWindow();1305EGLDisplay display = window->getDisplay();13061307window->makeCurrent();13081309const UINT bufferSize = 32;1310EXPECT_TRUE(mD3D11Device != nullptr);1311ID3D11Texture2D *d3d11_texture = nullptr;1312CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,1313D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);1314EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));13151316const EGLint attribs[] = {EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RGB, EGL_NONE};13171318EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,1319static_cast<EGLClientBuffer>(d3d11_texture), attribs);1320ASSERT_EGL_SUCCESS();1321ASSERT_NE(image, EGL_NO_IMAGE_KHR);13221323GLuint texture;1324glGenTextures(1, &texture);1325glBindTexture(GL_TEXTURE_2D, texture);1326glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1327glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1328glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1329glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1330ASSERT_GL_NO_ERROR();13311332glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);1333ASSERT_GL_NO_ERROR();13341335GLuint fbo;1336glGenFramebuffers(1, &fbo);1337glBindFramebuffer(GL_FRAMEBUFFER, fbo);1338glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);1339EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),1340static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));1341ASSERT_GL_NO_ERROR();13421343// Although we are writing 0.5 to the alpha channel it should have the same1344// side effects as if alpha were 1.0.1345glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));1346glClearColor(1.0f, 0.0f, 1.0f, 0.5f);1347glClear(GL_COLOR_BUFFER_BIT);1348ASSERT_GL_NO_ERROR();1349EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,1350255, 255);13511352GLuint rgbaRbo;1353glGenRenderbuffers(1, &rgbaRbo);1354glBindRenderbuffer(GL_RENDERBUFFER, rgbaRbo);1355glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, bufferSize, bufferSize);13561357GLuint rgbaFbo;1358glGenFramebuffers(1, &rgbaFbo);1359glBindFramebuffer(GL_FRAMEBUFFER, rgbaFbo);1360glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rgbaRbo);1361EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),1362static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));1363ASSERT_GL_NO_ERROR();13641365// BlitFramebuffer from/to RGBA framebuffer fails.1366glBindFramebuffer(GL_READ_FRAMEBUFFER, rgbaFbo);1367glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);1368glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,1369GL_COLOR_BUFFER_BIT, GL_NEAREST);1370ASSERT_GL_ERROR(GL_INVALID_OPERATION);1371ASSERT_GL_NO_ERROR();13721373glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1374glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rgbaFbo);1375glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,1376GL_COLOR_BUFFER_BIT, GL_NEAREST);1377ASSERT_GL_ERROR(GL_INVALID_OPERATION);1378ASSERT_GL_NO_ERROR();13791380GLuint rgbRbo;1381glGenRenderbuffers(1, &rgbRbo);1382glBindRenderbuffer(GL_RENDERBUFFER, rgbRbo);1383glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, bufferSize, bufferSize);13841385GLuint rgbFbo;1386glGenFramebuffers(1, &rgbFbo);1387glBindFramebuffer(GL_FRAMEBUFFER, rgbFbo);1388glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rgbRbo);1389EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),1390static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));1391ASSERT_GL_NO_ERROR();1392glClearColor(1.0f, 0.0f, 1.0f, 0.5f);1393glClear(GL_COLOR_BUFFER_BIT);1394ASSERT_GL_NO_ERROR();13951396// Clear texture framebuffer.1397glBindFramebuffer(GL_FRAMEBUFFER, fbo);1398glClearColor(0.0f, 0.0f, 0.0f, 0.0f);1399glClear(GL_COLOR_BUFFER_BIT);1400ASSERT_GL_NO_ERROR();1401EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 0, 0, 0,1402255);14031404// BlitFramebuffer from/to RGB framebuffer succeeds.1405glBindFramebuffer(GL_READ_FRAMEBUFFER, rgbFbo);1406glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);1407glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,1408GL_COLOR_BUFFER_BIT, GL_NEAREST);1409ASSERT_GL_NO_ERROR();1410EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,1411255, 255);14121413glClearColor(0.0f, 0.0f, 0.0f, 0.0f);1414glClear(GL_COLOR_BUFFER_BIT);1415glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1416glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rgbFbo);1417glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,1418GL_COLOR_BUFFER_BIT, GL_NEAREST);1419ASSERT_GL_NO_ERROR();1420glBindFramebuffer(GL_FRAMEBUFFER, rgbFbo);1421EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 0, 0, 0,1422255);14231424glDeleteFramebuffers(1, &rgbFbo);1425glDeleteRenderbuffers(1, &rgbRbo);1426glDeleteFramebuffers(1, &rgbaFbo);1427glDeleteRenderbuffers(1, &rgbaRbo);1428glDeleteFramebuffers(1, &fbo);1429glDeleteTextures(1, &texture);1430eglDestroyImageKHR(display, image);14311432d3d11_texture->Release();1433}14341435TEST_P(D3DTextureTest, TextureArrayImage)1436{1437ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());14381439EGLWindow *window = getEGLWindow();1440EGLDisplay display = window->getDisplay();14411442window->makeCurrent();14431444const UINT bufferSize = 32;1445const UINT arraySize = 4;14461447ID3D11Texture2D *d3d11_texture = nullptr;1448CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, arraySize, 1,1449D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);1450EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));14511452const unsigned char kRFill = 0x12;1453const unsigned char kGFill = 0x23;1454const unsigned char kBFill = 0x34;1455const unsigned char kAFill = 0x45;14561457std::vector<unsigned char> imageData(bufferSize * bufferSize * 4, 0);1458for (size_t i = 0; i < imageData.size(); i += 4)1459{1460imageData[i] = kRFill;1461imageData[i + 1] = kGFill;1462imageData[i + 2] = kBFill;1463imageData[i + 3] = kAFill;1464}14651466ID3D11DeviceContext *context = nullptr;1467mD3D11Device->GetImmediateContext(&context);1468ASSERT_NE(context, nullptr);14691470D3D11_BOX dstBox = {0, 0, 0, bufferSize, bufferSize, 1};1471context->UpdateSubresource(d3d11_texture, arraySize - 1, &dstBox, imageData.data(),1472bufferSize * 4, imageData.size());14731474const EGLint attribs[] = {EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE, arraySize - 1, EGL_NONE};1475EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,1476static_cast<EGLClientBuffer>(d3d11_texture), attribs);1477ASSERT_EGL_SUCCESS();1478ASSERT_NE(image, EGL_NO_IMAGE_KHR);14791480GLuint texture;1481glGenTextures(1, &texture);1482glBindTexture(GL_TEXTURE_2D, texture);1483glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1484glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1485glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1486glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1487ASSERT_GL_NO_ERROR();14881489glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);1490ASSERT_GL_NO_ERROR();14911492GLuint fbo;1493glGenFramebuffers(1, &fbo);1494glBindFramebuffer(GL_FRAMEBUFFER, fbo);1495glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);1496EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),1497static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));1498ASSERT_GL_NO_ERROR();14991500EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, kRFill,1501kGFill, kBFill, kAFill);15021503glDeleteFramebuffers(1, &fbo);1504glDeleteTextures(1, &texture);1505eglDestroyImageKHR(display, image);15061507d3d11_texture->Release();1508}15091510class D3DTextureYUVTest : public D3DTextureTest1511{1512protected:1513D3DTextureYUVTest() : D3DTextureTest() {}15141515void RunYUVTest(DXGI_FORMAT format)1516{1517ASSERT_TRUE(format == DXGI_FORMAT_NV12 || format == DXGI_FORMAT_P010 ||1518format == DXGI_FORMAT_P016);1519UINT formatSupport;1520ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11() ||1521FAILED(mD3D11Device->CheckFormatSupport(format, &formatSupport)));1522ASSERT_TRUE(formatSupport &1523(D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE));15241525constexpr char kVS[] =1526R"(precision highp float;1527attribute vec4 position;1528varying vec2 texcoord;15291530void main()1531{1532gl_Position = position;1533texcoord = (position.xy * 0.5) + 0.5;1534texcoord.y = 1.0 - texcoord.y;1535})";15361537constexpr char kTextureExternalOESFS[] =1538R"(#extension GL_OES_EGL_image_external : require1539precision highp float;1540uniform samplerExternalOES tex;1541varying vec2 texcoord;15421543void main()1544{1545gl_FragColor = texture2D(tex, texcoord);1546})";15471548GLuint textureExternalOESProgram = CompileProgram(kVS, kTextureExternalOESFS);1549ASSERT_NE(0u, textureExternalOESProgram) << "shader compilation failed.";15501551GLint textureExternalOESUniformLocation =1552glGetUniformLocation(textureExternalOESProgram, "tex");1553ASSERT_NE(-1, textureExternalOESUniformLocation);15541555EGLWindow *window = getEGLWindow();1556EGLDisplay display = window->getDisplay();15571558window->makeCurrent();15591560const UINT bufferSize = 32;1561EXPECT_TRUE(mD3D11Device != nullptr);1562ID3D11Texture2D *d3d11_texture = nullptr;1563CD3D11_TEXTURE2D_DESC desc(format, bufferSize, bufferSize, 1, 1,1564D3D11_BIND_SHADER_RESOURCE);15651566const bool isNV12 = (format == DXGI_FORMAT_NV12);1567const unsigned kYFillValue = isNV12 ? 0x12 : 0x1234;1568const unsigned kUFillValue = isNV12 ? 0x23 : 0x2345;1569const unsigned kVFillValue = isNV12 ? 0x34 : 0x3456;15701571std::vector<unsigned char> imageData;15721573if (isNV12)1574{1575imageData.resize(bufferSize * bufferSize * 3 / 2);1576memset(imageData.data(), kYFillValue, bufferSize * bufferSize);1577const size_t kUVOffset = bufferSize * bufferSize;1578for (size_t i = 0; i < bufferSize * bufferSize / 2; i += 2)1579{1580imageData[kUVOffset + i] = kUFillValue;1581imageData[kUVOffset + i + 1] = kVFillValue;1582}1583}1584else1585{1586imageData.resize(bufferSize * bufferSize * 3);1587const size_t kUVOffset = bufferSize * bufferSize * 2;1588for (size_t i = 0; i < kUVOffset; i += 2)1589{1590imageData[i] = kYFillValue & 0xff;1591imageData[i + 1] = (kYFillValue >> 8) & 0xff;1592if (kUVOffset + i < imageData.size())1593{1594// Interleave U & V samples.1595const unsigned fill = (i % 4 == 0) ? kUFillValue : kVFillValue;1596imageData[kUVOffset + i] = fill & 0xff;1597imageData[kUVOffset + i + 1] = (fill >> 8) & 0xff;1598}1599}1600}16011602D3D11_SUBRESOURCE_DATA data = {};1603data.pSysMem = static_cast<const void *>(imageData.data());1604data.SysMemPitch = isNV12 ? bufferSize : bufferSize * 2;16051606EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, &data, &d3d11_texture)));16071608const EGLint yAttribs[] = {EGL_D3D11_TEXTURE_PLANE_ANGLE, 0, EGL_NONE};1609EGLImage yImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,1610static_cast<EGLClientBuffer>(d3d11_texture), yAttribs);1611ASSERT_EGL_SUCCESS();1612ASSERT_NE(yImage, EGL_NO_IMAGE_KHR);16131614// Create and bind Y plane texture to image.1615GLuint yTexture;1616glGenTextures(1, &yTexture);1617glActiveTexture(GL_TEXTURE0);1618glBindTexture(GL_TEXTURE_EXTERNAL_OES, yTexture);1619glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1620glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1621glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1622glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1623ASSERT_GL_NO_ERROR();16241625glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, yImage);1626ASSERT_GL_NO_ERROR();16271628GLuint rbo;1629glGenRenderbuffers(1, &rbo);1630glBindRenderbuffer(GL_RENDERBUFFER, rbo);1631glRenderbufferStorage(GL_RENDERBUFFER, isNV12 ? GL_RGBA8_OES : GL_RGBA16_EXT, bufferSize,1632bufferSize);1633ASSERT_GL_NO_ERROR();16341635GLuint fbo;1636glGenFramebuffers(1, &fbo);1637glBindFramebuffer(GL_FRAMEBUFFER, fbo);1638glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);1639EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),1640static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));1641ASSERT_GL_NO_ERROR();16421643// Draw the Y plane using a shader.1644glUseProgram(textureExternalOESProgram);1645glUniform1i(textureExternalOESUniformLocation, 0);1646ASSERT_GL_NO_ERROR();16471648glViewport(0, 0, bufferSize, bufferSize);1649drawQuad(textureExternalOESProgram, "position", 1.0f);1650ASSERT_GL_NO_ERROR();16511652if (isNV12)1653{16541655EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,1656kYFillValue, 0, 0, 0xff);1657}1658else1659{1660EXPECT_PIXEL_16UI(static_cast<GLint>(bufferSize) / 2,1661static_cast<GLint>(bufferSize) / 2, kYFillValue, 0, 0, 0xffff);1662}1663ASSERT_GL_NO_ERROR();16641665const EGLint uvAttribs[] = {EGL_D3D11_TEXTURE_PLANE_ANGLE, 1, EGL_NONE};1666EGLImage uvImage =1667eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,1668static_cast<EGLClientBuffer>(d3d11_texture), uvAttribs);1669ASSERT_EGL_SUCCESS();1670ASSERT_NE(uvImage, EGL_NO_IMAGE_KHR);16711672// Create and bind UV plane texture to image.1673GLuint uvTexture;1674glGenTextures(1, &uvTexture);1675glActiveTexture(GL_TEXTURE0);1676glBindTexture(GL_TEXTURE_EXTERNAL_OES, uvTexture);1677glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1678glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1679glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1680glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1681ASSERT_GL_NO_ERROR();16821683glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, uvImage);1684ASSERT_GL_NO_ERROR();16851686// Draw the UV plane using a shader.1687glUseProgram(textureExternalOESProgram);1688glUniform1i(textureExternalOESUniformLocation, 0);1689ASSERT_GL_NO_ERROR();16901691// Use only half of the framebuffer to match UV plane dimensions.1692glViewport(0, 0, bufferSize / 2, bufferSize / 2);1693drawQuad(textureExternalOESProgram, "position", 1.0f);1694ASSERT_GL_NO_ERROR();16951696if (isNV12)1697{16981699EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 4, static_cast<GLint>(bufferSize) / 4,1700kUFillValue, kVFillValue, 0, 0xff);1701}1702else1703{1704EXPECT_PIXEL_16UI(static_cast<GLint>(bufferSize) / 4,1705static_cast<GLint>(bufferSize) / 4, kUFillValue, kVFillValue, 0,17060xffff);1707}1708ASSERT_GL_NO_ERROR();17091710glDeleteProgram(textureExternalOESProgram);1711glDeleteTextures(1, &yTexture);1712glDeleteTextures(1, &uvTexture);1713glDeleteFramebuffers(1, &fbo);1714glDeleteRenderbuffers(1, &rbo);1715eglDestroyImageKHR(display, yImage);1716eglDestroyImageKHR(display, uvImage);17171718d3d11_texture->Release();1719}1720};17211722TEST_P(D3DTextureYUVTest, NV12TextureImage)1723{1724RunYUVTest(DXGI_FORMAT_NV12);1725}17261727// Reading back from RGBA16_EXT renderbuffer needs GL_EXT_texture_norm16 which is ES3 only.1728class D3DTextureYUVTestES3 : public D3DTextureYUVTest1729{1730protected:1731D3DTextureYUVTestES3() : D3DTextureYUVTest() {}1732};17331734TEST_P(D3DTextureYUVTestES3, P010TextureImage)1735{1736RunYUVTest(DXGI_FORMAT_P010);1737}17381739TEST_P(D3DTextureYUVTestES3, P016TextureImage)1740{1741RunYUVTest(DXGI_FORMAT_P016);1742}17431744// Use this to select which configurations (e.g. which renderer, which GLES major version) these1745// tests should be run against.1746ANGLE_INSTANTIATE_TEST_ES2(D3DTextureTest);1747ANGLE_INSTANTIATE_TEST_ES2(D3DTextureYUVTest);1748ANGLE_INSTANTIATE_TEST_ES3(D3DTextureTestES3);1749ANGLE_INSTANTIATE_TEST_ES3(D3DTextureYUVTestES3);1750// D3D Debug device reports an error. http://anglebug.com/35131751// ANGLE_INSTANTIATE_TEST(D3DTextureTestMS, ES2_D3D11());1752GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(D3DTextureTestMS);1753} // namespace angle175417551756