summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp')
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp452
1 files changed, 452 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp
new file mode 100644
index 0000000000..8b1d010cfc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp
@@ -0,0 +1,452 @@
+//
+// Copyright 2014 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.
+//
+
+// DisplayD3D.cpp: D3D implementation of egl::Display
+
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+
+#include <EGL/eglext.h>
+
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/renderer/d3d/DeviceD3D.h"
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+
+#if !defined(ANGLE_DEFAULT_D3D11)
+// Enables use of the Direct3D 11 API for a default display, when available
+# define ANGLE_DEFAULT_D3D11 1
+#endif
+
+namespace rx
+{
+
+using CreateRendererD3DFunction = RendererD3D *(*)(egl::Display *);
+
+egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer)
+{
+ ASSERT(outRenderer != nullptr);
+
+ std::vector<CreateRendererD3DFunction> rendererCreationFunctions;
+
+ if (display->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE)
+ {
+ const auto &attribMap = display->getAttributeMap();
+ EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId();
+
+ EGLint requestedDisplayType = static_cast<EGLint>(
+ attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE));
+
+#if defined(ANGLE_ENABLE_D3D11)
+ const auto addD3D11 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
+#endif
+
+#if defined(ANGLE_ENABLE_D3D9)
+ const auto addD3D9 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
+#endif
+
+#if ANGLE_DEFAULT_D3D11
+# if defined(ANGLE_ENABLE_D3D11)
+ if (addD3D11)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer11);
+ }
+# endif
+
+# if defined(ANGLE_ENABLE_D3D9)
+ if (addD3D9)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer9);
+ }
+# endif
+#else
+# if defined(ANGLE_ENABLE_D3D9)
+ if (addD3D9)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer9);
+ }
+# endif
+
+# if defined(ANGLE_ENABLE_D3D11)
+ if (addD3D11)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer11);
+ }
+# endif
+#endif
+
+ if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE &&
+ nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE &&
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
+ {
+ // The default display is requested, try the D3D9 and D3D11 renderers, order them using
+ // the definition of ANGLE_DEFAULT_D3D11
+#if ANGLE_DEFAULT_D3D11
+# if defined(ANGLE_ENABLE_D3D11)
+ rendererCreationFunctions.push_back(CreateRenderer11);
+# endif
+# if defined(ANGLE_ENABLE_D3D9)
+ rendererCreationFunctions.push_back(CreateRenderer9);
+# endif
+#else
+# if defined(ANGLE_ENABLE_D3D9)
+ rendererCreationFunctions.push_back(CreateRenderer9);
+# endif
+# if defined(ANGLE_ENABLE_D3D11)
+ rendererCreationFunctions.push_back(CreateRenderer11);
+# endif
+#endif
+ }
+ }
+ else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
+ {
+#if defined(ANGLE_ENABLE_D3D11)
+ if (display->getDevice()->getType() == EGL_D3D11_DEVICE_ANGLE)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer11);
+ }
+#endif
+ }
+ else
+ {
+ UNIMPLEMENTED();
+ }
+
+ for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
+ {
+ RendererD3D *renderer = rendererCreationFunctions[i](display);
+ egl::Error result = renderer->initialize();
+
+#if defined(ANGLE_ENABLE_D3D11)
+ if (renderer->getRendererClass() == RENDERER_D3D11)
+ {
+ ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D11_INIT_ERRORS);
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11InitializeResult", result.getID(),
+ NUM_D3D11_INIT_ERRORS);
+ }
+#endif
+
+#if defined(ANGLE_ENABLE_D3D9)
+ if (renderer->getRendererClass() == RENDERER_D3D9)
+ {
+ ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D9_INIT_ERRORS);
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D9InitializeResult", result.getID(),
+ NUM_D3D9_INIT_ERRORS);
+ }
+#endif
+
+ if (!result.isError())
+ {
+ *outRenderer = renderer;
+ return result;
+ }
+
+ // Failed to create the renderer, try the next
+ SafeDelete(renderer);
+ ERR() << "Failed to create D3D renderer: " << result.getMessage();
+ }
+
+ return egl::EglNotInitialized() << "No available renderers.";
+}
+
+DisplayD3D::DisplayD3D(const egl::DisplayState &state) : DisplayImpl(state), mRenderer(nullptr) {}
+
+SurfaceImpl *DisplayD3D::createWindowSurface(const egl::SurfaceState &state,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return new WindowSurfaceD3D(state, mRenderer, mDisplay, window, attribs);
+}
+
+SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return new PbufferSurfaceD3D(state, mRenderer, mDisplay, 0, nullptr, attribs);
+}
+
+SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return new PbufferSurfaceD3D(state, mRenderer, mDisplay, buftype, clientBuffer, attribs);
+}
+
+SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+ImageImpl *DisplayD3D::createImage(const egl::ImageState &state,
+ const gl::Context *context,
+ EGLenum target,
+ const egl::AttributeMap &attribs)
+{
+ return new EGLImageD3D(state, target, attribs, mRenderer);
+}
+
+DeviceImpl *DisplayD3D::createDevice()
+{
+ return mRenderer->createEGLDevice();
+}
+
+rx::ContextImpl *DisplayD3D::createContext(const gl::State &state,
+ gl::ErrorSet *errorSet,
+ const egl::Config *configuration,
+ const gl::Context *shareContext,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->createContext(state, errorSet);
+}
+
+StreamProducerImpl *DisplayD3D::createStreamProducerD3DTexture(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->createStreamProducerD3DTexture(consumerType, attribs);
+}
+
+ExternalImageSiblingImpl *DisplayD3D::createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->createExternalImageSibling(context, target, buffer, attribs);
+}
+
+ShareGroupImpl *DisplayD3D::createShareGroup()
+{
+ return new ShareGroupD3D();
+}
+
+egl::Error DisplayD3D::makeCurrent(egl::Display *display,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface,
+ gl::Context *context)
+{
+ // Ensure the appropriate global DebugAnnotator is used
+ ASSERT(mRenderer != nullptr);
+ mRenderer->setGlobalDebugAnnotator();
+
+ return egl::NoError();
+}
+
+egl::Error DisplayD3D::initialize(egl::Display *display)
+{
+ ASSERT(mRenderer == nullptr && display != nullptr);
+ mDisplay = display;
+ ANGLE_TRY(CreateRendererD3D(display, &mRenderer));
+ return egl::NoError();
+}
+
+void DisplayD3D::terminate()
+{
+ SafeDelete(mRenderer);
+}
+
+egl::ConfigSet DisplayD3D::generateConfigs()
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->generateConfigs();
+}
+
+bool DisplayD3D::testDeviceLost()
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->testDeviceLost();
+}
+
+egl::Error DisplayD3D::restoreLostDevice(const egl::Display *display)
+{
+ // Release surface resources to make the Reset() succeed
+ for (egl::Surface *surface : mState.surfaceSet)
+ {
+ ASSERT(!surface->getBoundTexture());
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ surfaceD3D->releaseSwapChain();
+ }
+
+ if (!mRenderer->resetDevice())
+ {
+ return egl::EglBadAlloc();
+ }
+
+ // Restore any surfaces that may have been lost
+ for (const egl::Surface *surface : mState.surfaceSet)
+ {
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+
+ ANGLE_TRY(surfaceD3D->resetSwapChain(display));
+ }
+
+ return egl::NoError();
+}
+
+bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return mRenderer->isValidNativeWindow(window);
+}
+
+egl::Error DisplayD3D::validateClientBuffer(const egl::Config *config,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ switch (buftype)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ return mRenderer->validateShareHandle(config, static_cast<HANDLE>(clientBuffer),
+ attribs);
+
+ case EGL_D3D_TEXTURE_ANGLE:
+ return mRenderer->getD3DTextureInfo(config, static_cast<IUnknown *>(clientBuffer),
+ attribs, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr);
+
+ default:
+ return DisplayImpl::validateClientBuffer(config, buftype, clientBuffer, attribs);
+ }
+}
+
+egl::Error DisplayD3D::validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ switch (target)
+ {
+ case EGL_D3D11_TEXTURE_ANGLE:
+ {
+ return mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(clientBuffer),
+ attribs, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr);
+ }
+
+ default:
+ return DisplayImpl::validateImageClientBuffer(context, target, clientBuffer, attribs);
+ }
+}
+
+void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ mRenderer->generateDisplayExtensions(outExtensions);
+}
+
+std::string DisplayD3D::getRendererDescription()
+{
+ if (mRenderer)
+ {
+ return mRenderer->getRendererDescription();
+ }
+ return std::string();
+}
+
+std::string DisplayD3D::getVendorString()
+{
+ if (mRenderer)
+ {
+ return mRenderer->getVendorString();
+ }
+ return std::string();
+}
+
+std::string DisplayD3D::getVersionString()
+{
+ if (mRenderer)
+ {
+ return mRenderer->getVersionString();
+ }
+ return std::string();
+}
+
+void DisplayD3D::generateCaps(egl::Caps *outCaps) const
+{
+ // Display must be initialized to generate caps
+ ASSERT(mRenderer != nullptr);
+
+ outCaps->textureNPOT = mRenderer->getNativeExtensions().textureNPOTOES;
+}
+
+egl::Error DisplayD3D::waitClient(const gl::Context *context)
+{
+ for (egl::Surface *surface : mState.surfaceSet)
+ {
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ ANGLE_TRY(surfaceD3D->checkForOutOfDateSwapChain(this));
+ }
+
+ return egl::NoError();
+}
+
+egl::Error DisplayD3D::waitNative(const gl::Context *context, EGLint engine)
+{
+ egl::Surface *drawSurface = context->getCurrentDrawSurface();
+ egl::Surface *readSurface = context->getCurrentReadSurface();
+
+ if (drawSurface != nullptr)
+ {
+ SurfaceD3D *drawSurfaceD3D = GetImplAs<SurfaceD3D>(drawSurface);
+ ANGLE_TRY(drawSurfaceD3D->checkForOutOfDateSwapChain(this));
+ }
+
+ if (readSurface != nullptr)
+ {
+ SurfaceD3D *readSurfaceD3D = GetImplAs<SurfaceD3D>(readSurface);
+ ANGLE_TRY(readSurfaceD3D->checkForOutOfDateSwapChain(this));
+ }
+
+ return egl::NoError();
+}
+
+gl::Version DisplayD3D::getMaxSupportedESVersion() const
+{
+ return mRenderer->getMaxSupportedESVersion();
+}
+
+gl::Version DisplayD3D::getMaxConformantESVersion() const
+{
+ return mRenderer->getMaxConformantESVersion();
+}
+
+void DisplayD3D::handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line)
+{
+ ASSERT(FAILED(hr));
+
+ std::stringstream errorStream;
+ errorStream << "Internal D3D11 error: " << gl::FmtHR(hr) << ", in " << file << ", " << function
+ << ":" << line << ". " << message;
+
+ mStoredErrorString = errorStream.str();
+}
+
+void DisplayD3D::populateFeatureList(angle::FeatureList *features)
+{
+ mRenderer->getFeatures().populateFeatureList(features);
+}
+
+} // namespace rx