// 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); }
EGLSurface createD3D11PBuffer(size_t width, size_t height, EGLint eglTextureFormat, EGLint eglTextureTarget, UINT sampleCount, UINT sampleQuality, UINT bindFlags, DXGI_FORMAT format) { 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, }; ASSERT(mD3D11Device); 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; }
// 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); }
bool valid() const { EGLWindow *window = getEGLWindow(); EGLDisplay display = window->getDisplay(); if (!eglDisplayExtensionEnabled(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; }
RenderWindow* X11EGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams) { EGLWindow* window = new X11EGLWindow(this); window->create(name, width, height, fullScreen, miscParams); return window; }
void EGLWindowBase::execSyncV( FieldContainer &oFrom, ConstFieldMaskArg whichField, AspectOffsetStore &oOffsets, ConstFieldMaskArg syncMode, const UInt32 uiSyncInfo) { EGLWindow *pThis = static_cast<EGLWindow *>(this); pThis->execSync(static_cast<EGLWindow *>(&oFrom), whichField, oOffsets, syncMode, uiSyncInfo); }
// 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); }
// 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); }
int main() { std::cout << "Pre window init" << std::endl; window.init(); std::cout << "Pre render init" << std::endl; render.init(); input.init(); bool shouldExit = false; input.onExit([&shouldExit](){shouldExit=true;}); std::cout << "pre loop" << std::endl; #ifdef EMSCRIPTEN emscripten_set_main_loop(loop_body, 15, true); #else while( !shouldExit) { loop_body(); } #endif // EMSCRIPTEN return 0; }
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. ASSERT(sampleCount <= 1); ASSERT(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; } }
void loop_body() { input.handleInput(); render.paint(); window.render(); std::cout << "frame: " << ++frame << std::endl; }
// Test creating pbuffer from textures with several // different DXGI formats. TEST_P(D3DTextureTest, TestD3D11SupportedFormats) { ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11()); 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) { EGLSurface pbuffer = createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0, D3D11_BIND_RENDER_TARGET, formats[i]); 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(); window->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); }
bool IsPlatformAvailable(const PlatformParameters ¶m) { switch (param.getRenderer()) { case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: break; case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: #ifndef ANGLE_ENABLE_D3D9 return false; #endif break; case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: #ifndef ANGLE_ENABLE_D3D11 return false; #endif break; case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: #ifndef ANGLE_ENABLE_OPENGL return false; #endif break; default: UNREACHABLE(); break; } static std::map<PlatformParameters, bool> paramAvailabilityCache; auto iter = paramAvailabilityCache.find(param); if (iter != paramAvailabilityCache.end()) { return iter->second; } else { OSWindow *osWindow = CreateOSWindow(); bool result = osWindow->initialize("CONFIG_TESTER", 1, 1); if (result) { EGLWindow *eglWindow = new EGLWindow(1, 1, param.majorVersion, param.eglParameters); result = eglWindow->initializeGL(osWindow); eglWindow->destroyGL(); SafeDelete(eglWindow); } osWindow->destroy(); SafeDelete(osWindow); paramAvailabilityCache[param] = result; if (!result) { std::cout << "Skipping tests using configuration " << param << " because it is not available." << std::endl; } return result; } }
// Tests timer queries operating under multiple EGL contexts with mid-query switching TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest) { if (!extensionEnabled("GL_EXT_disjoint_timer_query")) { std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." << std::endl; return; } GLint queryTimeElapsedBits = 0; glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits); ASSERT_GL_NO_ERROR(); std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl; // Skip test if the number of bits is 0 if (queryTimeElapsedBits == 0) { std::cout << "Test skipped because of 0 counter bits" << std::endl; return; } // Without a glClear, the first draw call on GL takes a huge amount of time when run after the // D3D test on certain NVIDIA drivers glDepthMask(GL_TRUE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); EGLint contextAttributes[] = { EGL_CONTEXT_MAJOR_VERSION_KHR, GetParam().majorVersion, EGL_CONTEXT_MINOR_VERSION_KHR, GetParam().minorVersion, EGL_NONE, }; EGLWindow *window = getEGLWindow(); EGLDisplay display = window->getDisplay(); EGLConfig config = window->getConfig(); EGLSurface surface = window->getSurface(); struct ContextInfo { EGLContext context; GLuint program; GLuint query; EGLDisplay display; ContextInfo() : context(EGL_NO_CONTEXT), program(0), query(0), display(EGL_NO_DISPLAY) {} ~ContextInfo() { if (context != EGL_NO_CONTEXT && display != EGL_NO_DISPLAY) { eglDestroyContext(display, context); } } }; ContextInfo contexts[2]; // Shaders const std::string cheapVS = "attribute highp vec4 position; void main(void)\n" "{\n" " gl_Position = position;\n" "}\n"; const std::string cheapPS = "precision highp float; void main(void)\n" "{\n" " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" "}\n"; const std::string costlyVS = "attribute highp vec4 position; varying highp vec4 testPos; void main(void)\n" "{\n" " testPos = position;\n" " gl_Position = position;\n" "}\n"; const std::string costlyPS = "precision highp float; varying highp vec4 testPos; void main(void)\n" "{\n" " vec4 test = testPos;\n" " for (int i = 0; i < 500; i++)\n" " {\n" " test = sqrt(test);\n" " }\n" " gl_FragColor = test;\n" "}\n"; // Setup the first context with a cheap shader contexts[0].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); contexts[0].display = display; ASSERT_NE(contexts[0].context, EGL_NO_CONTEXT); eglMakeCurrent(display, surface, surface, contexts[0].context); contexts[0].program = CompileProgram(cheapVS, cheapPS); glGenQueriesEXT(1, &contexts[0].query); ASSERT_GL_NO_ERROR(); // Setup the second context with an expensive shader contexts[1].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); contexts[1].display = display; ASSERT_NE(contexts[1].context, EGL_NO_CONTEXT); eglMakeCurrent(display, surface, surface, contexts[1].context); contexts[1].program = CompileProgram(costlyVS, costlyPS); glGenQueriesEXT(1, &contexts[1].query); ASSERT_GL_NO_ERROR(); // Start the query and draw a quad on the first context without ending the query eglMakeCurrent(display, surface, surface, contexts[0].context); glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[0].query); drawQuad(contexts[0].program, "position", 0.8f); ASSERT_GL_NO_ERROR(); // Switch contexts, draw the expensive quad and end its query eglMakeCurrent(display, surface, surface, contexts[1].context); glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[1].query); drawQuad(contexts[1].program, "position", 0.8f); glEndQueryEXT(GL_TIME_ELAPSED_EXT); ASSERT_GL_NO_ERROR(); // Go back to the first context, end its query, and get the result eglMakeCurrent(display, surface, surface, contexts[0].context); glEndQueryEXT(GL_TIME_ELAPSED_EXT); GLuint64 result1 = 0; GLuint64 result2 = 0; glGetQueryObjectui64vEXT(contexts[0].query, GL_QUERY_RESULT_EXT, &result1); glDeleteQueriesEXT(1, &contexts[0].query); glDeleteProgram(contexts[0].program); ASSERT_GL_NO_ERROR(); // Get the 2nd context's results eglMakeCurrent(display, surface, surface, contexts[1].context); glGetQueryObjectui64vEXT(contexts[1].query, GL_QUERY_RESULT_EXT, &result2); glDeleteQueriesEXT(1, &contexts[1].query); glDeleteProgram(contexts[1].program); ASSERT_GL_NO_ERROR(); // Switch back to main context eglMakeCurrent(display, surface, surface, window->getContext()); // Compare the results. The cheap quad should be smaller than the expensive one if // virtualization is working correctly std::cout << "Elapsed time: " << result1 << " cheap quad" << std::endl; std::cout << "Elapsed time: " << result2 << " costly quad" << std::endl; EXPECT_LT(0ul, result1); EXPECT_LT(0ul, result2); EXPECT_LT(result1, result2); }
// 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); }
void SetUp() override { ANGLETest::SetUp(); const std::string vsSource = 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; })"; const std::string textureFSSource = R"(precision highp float; uniform sampler2D tex; varying vec2 texcoord; void main() { gl_FragColor = texture2D(tex, texcoord); })"; const std::string textureFSSourceNoSampling = R"(precision highp float; void main() { gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); })"; mTextureProgram = CompileProgram(vsSource, textureFSSource); ASSERT_NE(0u, mTextureProgram) << "shader compilation failed."; mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); ASSERT_NE(-1, mTextureUniformLocation); mTextureProgramNoSampling = CompileProgram(vsSource, textureFSSourceNoSampling); 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 (eglDisplayExtensionEnabled(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 (eglDeviceExtensionEnabled(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))); } }