Path: blob/main_old/src/tests/egl_tests/EGLPresentPathD3D11Test.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//56#include "test_utils/ANGLETest.h"78#include <d3d11.h>9#include <cstdint>1011#include "util/OSWindow.h"12#include "util/com_utils.h"1314using namespace angle;1516class EGLPresentPathD3D11 : public ANGLETest17{18protected:19EGLPresentPathD3D11()20: mDisplay(EGL_NO_DISPLAY),21mContext(EGL_NO_CONTEXT),22mSurface(EGL_NO_SURFACE),23mOffscreenSurfaceD3D11Texture(nullptr),24mConfig(0),25mOSWindow(nullptr),26mWindowWidth(0)27{}2829void testSetUp() override30{31mOSWindow = OSWindow::New();32mWindowWidth = 64;33mOSWindow->initialize("EGLPresentPathD3D11", mWindowWidth, mWindowWidth);34}3536void initializeEGL(bool usePresentPathFast)37{38int clientVersion = GetParam().majorVersion;3940// Set up EGL Display41EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,42GetParam().getRenderer(),43EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,44GetParam().eglParameters.majorVersion,45EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,46GetParam().eglParameters.majorVersion,47EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,48usePresentPathFast ? EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE49: EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE,50EGL_NONE};51mDisplay =52eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttribs);53ASSERT_TRUE(EGL_NO_DISPLAY != mDisplay);54ASSERT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));5556// Choose the EGL config57EGLint numConfigs;58EGLint configAttribs[] = {EGL_RED_SIZE,598,60EGL_GREEN_SIZE,618,62EGL_BLUE_SIZE,638,64EGL_ALPHA_SIZE,658,66EGL_RENDERABLE_TYPE,67clientVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT,68EGL_SURFACE_TYPE,69EGL_PBUFFER_BIT,70EGL_NONE};71ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttribs, &mConfig, 1, &numConfigs));72ASSERT_EQ(1, numConfigs);7374// Set up the EGL context75EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, clientVersion, EGL_NONE};76mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttribs);77ASSERT_TRUE(EGL_NO_CONTEXT != mContext);78}7980void createWindowSurface()81{82mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);83}8485void createPbufferFromClientBufferSurface()86{87EGLAttrib device = 0;88EGLAttrib angleDevice = 0;8990EXPECT_TRUE(IsEGLClientExtensionEnabled("EGL_EXT_device_query"));9192ASSERT_EGL_TRUE(eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, &angleDevice));93ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),94EGL_D3D11_DEVICE_ANGLE, &device));95ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);9697D3D11_TEXTURE2D_DESC textureDesc = {0};98textureDesc.Width = mWindowWidth;99textureDesc.Height = mWindowWidth;100textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;101textureDesc.MipLevels = 1;102textureDesc.ArraySize = 1;103textureDesc.SampleDesc.Count = 1;104textureDesc.SampleDesc.Quality = 0;105textureDesc.Usage = D3D11_USAGE_DEFAULT;106textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;107textureDesc.CPUAccessFlags = 0;108textureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;109110ASSERT_TRUE(SUCCEEDED(111d3d11Device->CreateTexture2D(&textureDesc, nullptr, &mOffscreenSurfaceD3D11Texture)));112113IDXGIResource *dxgiResource =114DynamicCastComObject<IDXGIResource>(mOffscreenSurfaceD3D11Texture);115ASSERT_NE(nullptr, dxgiResource);116117HANDLE sharedHandle = 0;118ASSERT_TRUE(SUCCEEDED(dxgiResource->GetSharedHandle(&sharedHandle)));119SafeRelease(dxgiResource);120121EGLint pBufferAttributes[] = {EGL_WIDTH, mWindowWidth, EGL_HEIGHT,122mWindowWidth, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,123EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_NONE};124125mSurface = eglCreatePbufferFromClientBuffer(mDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,126sharedHandle, mConfig, pBufferAttributes);127ASSERT_TRUE(EGL_NO_SURFACE != mSurface);128}129130void makeCurrent() { ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)); }131132void testTearDown() override133{134SafeRelease(mOffscreenSurfaceD3D11Texture);135136if (mDisplay != EGL_NO_DISPLAY)137{138eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);139140if (mSurface != EGL_NO_SURFACE)141{142eglDestroySurface(mDisplay, mSurface);143mSurface = EGL_NO_SURFACE;144}145146if (mContext != EGL_NO_CONTEXT)147{148ASSERT_EGL_TRUE(149eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));150eglDestroyContext(mDisplay, mContext);151mContext = EGL_NO_CONTEXT;152}153154eglTerminate(mDisplay);155mDisplay = EGL_NO_DISPLAY;156}157158mOSWindow->destroy();159OSWindow::Delete(&mOSWindow);160}161162void drawQuadUsingGL()163{164GLuint m2DProgram;165GLint mTexture2DUniformLocation;166167constexpr char kVS[] =168R"(precision highp float;169attribute vec4 position;170varying vec2 texcoord;171172void main()173{174gl_Position = vec4(position.xy, 0.0, 1.0);175texcoord = (position.xy * 0.5) + 0.5;176})";177178constexpr char kFS[] =179R"(precision highp float;180uniform sampler2D tex;181varying vec2 texcoord;182183void main()184{185gl_FragColor = texture2D(tex, texcoord);186})";187188m2DProgram = CompileProgram(kVS, kFS);189mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");190191uint8_t textureInitData[16] = {192255, 0, 0, 255, // Red1930, 255, 0, 255, // Green1940, 0, 255, 255, // Blue195255, 255, 0, 255 // Red + Green196};197198// Create a simple RGBA texture199GLuint tex = 0;200glGenTextures(1, &tex);201glBindTexture(GL_TEXTURE_2D, tex);202glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,203textureInitData);204glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);205glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);206ASSERT_GL_NO_ERROR();207208// Draw a quad using the texture209glClear(GL_COLOR_BUFFER_BIT);210glUseProgram(m2DProgram);211glUniform1i(mTexture2DUniformLocation, 0);212213GLint positionLocation = glGetAttribLocation(m2DProgram, "position");214glUseProgram(m2DProgram);215const GLfloat vertices[] = {216-1.0f, 1.0f, 0.5f, -1.0f, -1.0f, 0.5f, 1.0f, -1.0f, 0.5f,217-1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, 1.0f, 1.0f, 0.5f,218};219220glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);221glEnableVertexAttribArray(positionLocation);222223glDrawArrays(GL_TRIANGLES, 0, 6);224ASSERT_GL_NO_ERROR();225226glDeleteProgram(m2DProgram);227}228229void checkPixelsUsingGL()230{231// Note that the texture is in BGRA format232EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); // Red233EXPECT_PIXEL_EQ(mWindowWidth - 1, 0, 0, 255, 0, 255); // Green234EXPECT_PIXEL_EQ(0, mWindowWidth - 1, 0, 0, 255, 255); // Blue235EXPECT_PIXEL_EQ(mWindowWidth - 1, mWindowWidth - 1, 255, 255, 0, 255); // Red + green236}237238void checkPixelsUsingD3D(bool usingPresentPathFast)239{240ASSERT_NE(nullptr, mOffscreenSurfaceD3D11Texture);241242D3D11_TEXTURE2D_DESC textureDesc = {0};243ID3D11Device *device;244ID3D11DeviceContext *context;245mOffscreenSurfaceD3D11Texture->GetDesc(&textureDesc);246mOffscreenSurfaceD3D11Texture->GetDevice(&device);247device->GetImmediateContext(&context);248ASSERT_NE(nullptr, device);249ASSERT_NE(nullptr, context);250251textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;252textureDesc.Usage = D3D11_USAGE_STAGING;253textureDesc.BindFlags = 0;254textureDesc.MiscFlags = 0;255ID3D11Texture2D *cpuTexture = nullptr;256ASSERT_TRUE(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &cpuTexture)));257258context->CopyResource(cpuTexture, mOffscreenSurfaceD3D11Texture);259260D3D11_MAPPED_SUBRESOURCE mappedSubresource;261context->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mappedSubresource);262ASSERT_EQ(static_cast<UINT>(mWindowWidth * 4), mappedSubresource.RowPitch);263ASSERT_EQ(static_cast<UINT>(mWindowWidth * mWindowWidth * 4), mappedSubresource.DepthPitch);264265angle::GLColor *byteData = reinterpret_cast<angle::GLColor *>(mappedSubresource.pData);266267// Note that the texture is in BGRA format, although the GLColor struct is RGBA268GLColor expectedTopLeftPixel = GLColor(0, 0, 255, 255); // Red269GLColor expectedTopRightPixel = GLColor(0, 255, 0, 255); // Green270GLColor expectedBottomLeftPixel = GLColor(255, 0, 0, 255); // Blue271GLColor expectedBottomRightPixel = GLColor(0, 255, 255, 255); // Red + Green272273if (usingPresentPathFast)274{275// Invert the expected values276GLColor tempTopLeft = expectedTopLeftPixel;277GLColor tempTopRight = expectedTopRightPixel;278expectedTopLeftPixel = expectedBottomLeftPixel;279expectedTopRightPixel = expectedBottomRightPixel;280expectedBottomLeftPixel = tempTopLeft;281expectedBottomRightPixel = tempTopRight;282}283284EXPECT_EQ(expectedTopLeftPixel, byteData[0]);285EXPECT_EQ(expectedTopRightPixel, byteData[(mWindowWidth - 1)]);286EXPECT_EQ(expectedBottomLeftPixel, byteData[(mWindowWidth - 1) * mWindowWidth]);287EXPECT_EQ(expectedBottomRightPixel,288byteData[(mWindowWidth - 1) * mWindowWidth + (mWindowWidth - 1)]);289290context->Unmap(cpuTexture, 0);291SafeRelease(cpuTexture);292SafeRelease(device);293SafeRelease(context);294}295296EGLDisplay mDisplay;297EGLContext mContext;298EGLSurface mSurface;299ID3D11Texture2D *mOffscreenSurfaceD3D11Texture;300EGLConfig mConfig;301OSWindow *mOSWindow;302GLint mWindowWidth;303};304305// Test that rendering basic content onto a window surface when present path fast306// is enabled works as expected307TEST_P(EGLPresentPathD3D11, WindowPresentPathFast)308{309initializeEGL(true);310createWindowSurface();311makeCurrent();312313drawQuadUsingGL();314315checkPixelsUsingGL();316}317318// Test that rendering basic content onto a client buffer surface when present path fast319// works as expected, and is also oriented the correct way around320TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathFast)321{322initializeEGL(true);323createPbufferFromClientBufferSurface();324makeCurrent();325326drawQuadUsingGL();327328checkPixelsUsingGL();329checkPixelsUsingD3D(true);330}331332// Test that rendering basic content onto a window surface when present path fast333// is disabled works as expected334TEST_P(EGLPresentPathD3D11, WindowPresentPathCopy)335{336initializeEGL(false);337createWindowSurface();338makeCurrent();339340drawQuadUsingGL();341342checkPixelsUsingGL();343}344345// Test that rendering basic content onto a client buffer surface when present path346// fast is disabled works as expected, and is also oriented the correct way around347TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathCopy)348{349initializeEGL(false);350createPbufferFromClientBufferSurface();351makeCurrent();352353drawQuadUsingGL();354355checkPixelsUsingGL();356checkPixelsUsingD3D(false);357}358359ANGLE_INSTANTIATE_TEST(EGLPresentPathD3D11, WithNoFixture(ES2_D3D11()));360361362