Commit 6dacaff4 by Cooper Partin Committed by Geoff Lang

Add extension EGL_ANGLE_device_d3d

Access to the D3D device is needed for some advanced scenarios. New entry points eglQueryDisplayAttribANGLE and eglQueryDeviceAttribANGLE have been added in this change to implement this extension. BUG=angleproject:935 Change-Id: Id1560b0887fa5882b9858af7bad9043ada67038d Reviewed-on: https://chromium-review.googlesource.com/251610Tested-by: 's avatarCooper Partin <coopp@microsoft.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 72ed20d4
...@@ -464,6 +464,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu ...@@ -464,6 +464,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E #define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
#endif /* EGL_ANGLE_platform_angle_opengl */ #endif /* EGL_ANGLE_platform_angle_opengl */
#ifndef EGL_ANGLE_device_d3d
#define EGL_ANGLE_device_d3d 1
#define EGL_D3D9_DEVICE_ANGLE 0x33A0
#define EGL_D3D11_DEVICE_ANGLE 0x33A1
#endif /* EGL_ANGLE_device_d3d */
#ifndef EGL_ARM_pixmap_multisample_discard #ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1 #define EGL_ARM_pixmap_multisample_discard 1
#define EGL_DISCARD_SAMPLES_ARM 0x3286 #define EGL_DISCARD_SAMPLES_ARM 0x3286
...@@ -504,6 +510,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a ...@@ -504,6 +510,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a
#endif #endif
#endif /* EGL_EXT_device_base */ #endif /* EGL_EXT_device_base */
#ifndef EGL_EXT_device_query
#define EGL_EXT_device_query 1
#endif /* EGL_EXT_device_query */
#ifndef EGL_EXT_image_dma_buf_import #ifndef EGL_EXT_image_dma_buf_import
#define EGL_EXT_image_dma_buf_import 1 #define EGL_EXT_image_dma_buf_import 1
#define EGL_LINUX_DMA_BUF_EXT 0x3270 #define EGL_LINUX_DMA_BUF_EXT 0x3270
......
...@@ -482,7 +482,8 @@ DisplayExtensions::DisplayExtensions() ...@@ -482,7 +482,8 @@ DisplayExtensions::DisplayExtensions()
querySurfacePointer(false), querySurfacePointer(false),
windowFixedSize(false), windowFixedSize(false),
postSubBuffer(false), postSubBuffer(false),
createContext(false) createContext(false),
deviceQuery(false)
{ {
} }
...@@ -498,10 +499,25 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -498,10 +499,25 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings); InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings);
return extensionStrings; return extensionStrings;
} }
DeviceExtensions::DeviceExtensions()
: deviceD3D(false)
{
}
std::vector<std::string> DeviceExtensions::getStrings() const
{
std::vector<std::string> extensionStrings;
// | Extension name | Supported flag | Output vector |
InsertExtensionString("EGL_ANGLE_device_d3d", deviceD3D, &extensionStrings);
return extensionStrings;
}
ClientExtensions::ClientExtensions() ClientExtensions::ClientExtensions()
: clientExtensions(false), : clientExtensions(false),
......
...@@ -347,6 +347,20 @@ struct DisplayExtensions ...@@ -347,6 +347,20 @@ struct DisplayExtensions
// EGL_KHR_create_context // EGL_KHR_create_context
bool createContext; bool createContext;
// EGL_EXT_device_query
bool deviceQuery;
};
struct DeviceExtensions
{
DeviceExtensions();
// Generate a vector of supported extension strings
std::vector<std::string> getStrings() const;
// EGL_ANGLE_device_d3d
bool deviceD3D;
}; };
struct ClientExtensions struct ClientExtensions
......
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Device.cpp: Implements the egl::Device class, representing the abstract
// device. Implements EGLDevice.
#include "libANGLE/Device.h"
#include <platform/Platform.h>
#include <EGL/eglext.h>
#include "common/debug.h"
#include "common/platform.h"
#include "libANGLE/Renderer/DeviceImpl.h"
namespace egl
{
template <typename T>
static std::string GenerateExtensionsString(const T &extensions)
{
std::vector<std::string> extensionsVector = extensions.getStrings();
std::ostringstream stream;
std::copy(extensionsVector.begin(), extensionsVector.end(), std::ostream_iterator<std::string>(stream, " "));
return stream.str();
}
Device::Device(Display *display, rx::DeviceImpl *impl)
: mDisplay(display),
mImplementation(impl)
{
initDeviceExtensions();
}
Device::~Device()
{
}
Error Device::getDevice(EGLAttrib *value)
{
return getImplementation()->getDevice(value);
}
EGLint Device::getType()
{
return getImplementation()->getType();
}
void Device::initDeviceExtensions()
{
mImplementation->generateExtensions(&mDeviceExtensions);
mDeviceExtensionString = GenerateExtensionsString(mDeviceExtensions);
}
const DeviceExtensions &Device::getExtensions() const
{
return mDeviceExtensions;
}
const std::string &Device::getExtensionString() const
{
return mDeviceExtensionString;
}
}
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Device.h: Implements the egl::Device class, representing the abstract
// device. Implements EGLDevice.
#ifndef LIBANGLE_DEVICE_H_
#define LIBANGLE_DEVICE_H_
#include "common/angleutils.h"
#include "libANGLE/Error.h"
#include "libANGLE/Display.h"
namespace rx
{
class DeviceImpl;
}
namespace egl
{
class Device final : angle::NonCopyable
{
public:
Device(Display *display, rx::DeviceImpl *impl);
virtual ~Device();
Error getDevice(EGLAttrib *value);
Display *getDisplay() { return mDisplay; };
EGLint getType();
const DeviceExtensions &getExtensions() const;
const std::string &getExtensionString() const;
rx::DeviceImpl *getImplementation() { return mImplementation; }
private:
void initDeviceExtensions();
Display *mDisplay;
rx::DeviceImpl *mImplementation;
DeviceExtensions mDeviceExtensions;
std::string mDeviceExtensionString;
};
}
#endif // LIBANGLE_DEVICE_H_
...@@ -190,7 +190,8 @@ Display::Display(EGLNativeDisplayType displayId) ...@@ -190,7 +190,8 @@ Display::Display(EGLNativeDisplayType displayId)
mCaps(), mCaps(),
mDisplayExtensions(), mDisplayExtensions(),
mDisplayExtensionString(), mDisplayExtensionString(),
mVendorString() mVendorString(),
mDevice(nullptr)
{ {
} }
...@@ -205,6 +206,7 @@ Display::~Display() ...@@ -205,6 +206,7 @@ Display::~Display()
displays->erase(iter); displays->erase(iter);
} }
SafeDelete(mDevice);
SafeDelete(mImplementation); SafeDelete(mImplementation);
} }
...@@ -246,6 +248,21 @@ Error Display::initialize() ...@@ -246,6 +248,21 @@ Error Display::initialize()
initDisplayExtensions(); initDisplayExtensions();
initVendorString(); initVendorString();
if (mDisplayExtensions.deviceQuery)
{
rx::DeviceImpl *impl = nullptr;
error = mImplementation->getDevice(&impl);
if (error.isError())
{
return error;
}
mDevice = new Device(this, impl);
}
else
{
mDevice = nullptr;
}
mInitialized = true; mInitialized = true;
return Error(EGL_SUCCESS); return Error(EGL_SUCCESS);
} }
...@@ -262,6 +279,7 @@ void Display::terminate() ...@@ -262,6 +279,7 @@ void Display::terminate()
mConfigSet.clear(); mConfigSet.clear();
mImplementation->terminate(); mImplementation->terminate();
mInitialized = false; mInitialized = false;
// De-init default platform // De-init default platform
...@@ -672,4 +690,9 @@ const std::string &Display::getVendorString() const ...@@ -672,4 +690,9 @@ const std::string &Display::getVendorString() const
return mVendorString; return mVendorString;
} }
Device *Display::getDevice() const
{
return mDevice;
}
} }
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/Config.h" #include "libANGLE/Config.h"
#include "libANGLE/AttributeMap.h" #include "libANGLE/AttributeMap.h"
#include "libANGLE/renderer/renderer.h"
namespace gl namespace gl
{ {
...@@ -32,6 +33,7 @@ class DisplayImpl; ...@@ -32,6 +33,7 @@ class DisplayImpl;
namespace egl namespace egl
{ {
class Surface; class Surface;
class Device;
class Display final : angle::NonCopyable class Display final : angle::NonCopyable
{ {
...@@ -88,6 +90,7 @@ class Display final : angle::NonCopyable ...@@ -88,6 +90,7 @@ class Display final : angle::NonCopyable
EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; } EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; }
rx::DisplayImpl *getImplementation() { return mImplementation; } rx::DisplayImpl *getImplementation() { return mImplementation; }
Device *getDevice() const;
private: private:
Display(EGLNativeDisplayType displayId); Display(EGLNativeDisplayType displayId);
...@@ -117,6 +120,8 @@ class Display final : angle::NonCopyable ...@@ -117,6 +120,8 @@ class Display final : angle::NonCopyable
std::string mDisplayExtensionString; std::string mDisplayExtensionString;
std::string mVendorString; std::string mVendorString;
Device* mDevice;
}; };
} }
......
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DeviceImpl.cpp: Implementation methods of egl::Device
#include "libANGLE/renderer/DeviceImpl.h"
namespace rx
{
DeviceImpl::DeviceImpl()
{
}
DeviceImpl::~DeviceImpl()
{
}
}
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DeviceImpl.h: Implementation methods of egl::Device
#ifndef LIBANGLE_RENDERER_DEVICEIMPL_H_
#define LIBANGLE_RENDERER_DEVICEIMPL_H_
#include "common/angleutils.h"
#include "libANGLE/Error.h"
#include "libANGLE/Caps.h"
namespace egl
{
class Device;
}
namespace rx
{
class DeviceImpl : angle::NonCopyable
{
public:
DeviceImpl();
virtual ~DeviceImpl();
virtual egl::Error getDevice(EGLAttrib *value) = 0;
virtual EGLint getType() = 0;
virtual void generateExtensions(egl::DeviceExtensions *outExtensions) const = 0;
};
}
#endif // LIBANGLE_RENDERER_DEVICEIMPL_H_
...@@ -35,6 +35,7 @@ namespace rx ...@@ -35,6 +35,7 @@ namespace rx
{ {
class SurfaceImpl; class SurfaceImpl;
struct ConfigDesc; struct ConfigDesc;
class DeviceImpl;
class DisplayImpl : angle::NonCopyable class DisplayImpl : angle::NonCopyable
{ {
...@@ -68,6 +69,8 @@ class DisplayImpl : angle::NonCopyable ...@@ -68,6 +69,8 @@ class DisplayImpl : angle::NonCopyable
virtual std::string getVendorString() const = 0; virtual std::string getVendorString() const = 0;
virtual egl::Error getDevice(DeviceImpl **device) = 0;
const egl::Caps &getCaps() const; const egl::Caps &getCaps() const;
typedef std::set<egl::Surface*> SurfaceSet; typedef std::set<egl::Surface*> SurfaceSet;
......
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DeviceD3D.cpp: D3D implementation of egl::Device
#include "libANGLE/renderer/d3d/DeviceD3D.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/Device.h"
#include "libANGLE/Display.h"
#include <EGL/eglext.h>
namespace rx
{
DeviceD3D::DeviceD3D(rx::RendererD3D *renderer)
: mRenderer(renderer)
{
}
egl::Error DeviceD3D::getDevice(EGLAttrib *value)
{
*value = reinterpret_cast<EGLAttrib>(mRenderer->getD3DDevice());
if (*value == 0)
{
return egl::Error(EGL_BAD_DEVICE_EXT);
}
return egl::Error(EGL_SUCCESS);
}
EGLint DeviceD3D::getType()
{
switch (mRenderer->getRendererClass())
{
case RENDERER_D3D11:
return EGL_D3D11_DEVICE_ANGLE;
case RENDERER_D3D9:
return EGL_D3D9_DEVICE_ANGLE;
default:
UNREACHABLE();
return EGL_NONE;
}
}
void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const
{
outExtensions->deviceD3D = true;
}
}
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DeviceD3D.h: D3D implementation of egl::Device
#ifndef LIBANGLE_RENDERER_D3D_DEVICED3D_H_
#define LIBANGLE_RENDERER_D3D_DEVICED3D_H_
#include "libANGLE/Device.h"
#include "libANGLE/renderer/DeviceImpl.h"
#include "libANGLE/renderer/d3d/rendererd3d.h"
namespace rx
{
class DeviceD3D : public DeviceImpl
{
public:
DeviceD3D(RendererD3D *renderer);
egl::Error getDevice(EGLAttrib *value) override;
EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
private:
RendererD3D *mRenderer;
};
}
#endif // LIBANGLE_RENDERER_D3D_DEVICED3D_H_
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h"
#include "libANGLE/renderer/d3d/SwapChainD3D.h" #include "libANGLE/renderer/d3d/SwapChainD3D.h"
#include "platform/Platform.h" #include "platform/Platform.h"
#include "libANGLE/renderer/d3d/deviced3d.h"
#include <EGL/eglext.h> #include <EGL/eglext.h>
...@@ -142,7 +143,8 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) ...@@ -142,7 +143,8 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer)
} }
DisplayD3D::DisplayD3D() DisplayD3D::DisplayD3D()
: mRenderer(nullptr) : mRenderer(nullptr),
mDevice(nullptr)
{ {
} }
...@@ -225,6 +227,13 @@ egl::Error DisplayD3D::createPixmapSurface(const egl::Config *configuration, Nat ...@@ -225,6 +227,13 @@ egl::Error DisplayD3D::createPixmapSurface(const egl::Config *configuration, Nat
return egl::Error(EGL_BAD_DISPLAY); return egl::Error(EGL_BAD_DISPLAY);
} }
egl::Error DisplayD3D::getDevice(DeviceImpl **device)
{
*device = reinterpret_cast<DeviceImpl*>(mDevice);
ASSERT(*device != nullptr);
return egl::Error(EGL_SUCCESS);
}
egl::Error DisplayD3D::createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs, egl::Error DisplayD3D::createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
gl::Context **outContext) gl::Context **outContext)
{ {
...@@ -247,11 +256,20 @@ egl::Error DisplayD3D::initialize(egl::Display *display) ...@@ -247,11 +256,20 @@ egl::Error DisplayD3D::initialize(egl::Display *display)
{ {
ASSERT(mRenderer == nullptr && display != nullptr); ASSERT(mRenderer == nullptr && display != nullptr);
mDisplay = display; mDisplay = display;
return CreateRendererD3D(display, &mRenderer); egl::Error error = CreateRendererD3D(display, &mRenderer);
if (error.isError())
{
return error;
}
ASSERT(mDevice == nullptr);
mDevice = new DeviceD3D(mRenderer);
return error;
} }
void DisplayD3D::terminate() void DisplayD3D::terminate()
{ {
SafeDelete(mDevice);
SafeDelete(mRenderer); SafeDelete(mRenderer);
} }
...@@ -331,6 +349,8 @@ void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -331,6 +349,8 @@ void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
} }
outExtensions->createContext = true; outExtensions->createContext = true;
outExtensions->deviceQuery = true;
} }
std::string DisplayD3D::getVendorString() const std::string DisplayD3D::getVendorString() const
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_ #define LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
#include "libANGLE/renderer/DisplayImpl.h" #include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/Device.h"
namespace rx namespace rx
{ {
...@@ -45,6 +46,8 @@ class DisplayD3D : public DisplayImpl ...@@ -45,6 +46,8 @@ class DisplayD3D : public DisplayImpl
bool isValidNativeWindow(EGLNativeWindowType window) const override; bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error getDevice(DeviceImpl **device) override;
std::string getVendorString() const override; std::string getVendorString() const override;
private: private:
...@@ -54,6 +57,8 @@ class DisplayD3D : public DisplayImpl ...@@ -54,6 +57,8 @@ class DisplayD3D : public DisplayImpl
egl::Display *mDisplay; egl::Display *mDisplay;
rx::RendererD3D *mRenderer; rx::RendererD3D *mRenderer;
DeviceImpl *mDevice;
}; };
} }
......
...@@ -51,7 +51,7 @@ enum ShaderType ...@@ -51,7 +51,7 @@ enum ShaderType
enum RendererClass enum RendererClass
{ {
RENDERER_D3D11, RENDERER_D3D11,
RENDERER_D3D9, RENDERER_D3D9
}; };
// Useful for unit testing // Useful for unit testing
...@@ -177,8 +177,8 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -177,8 +177,8 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
// Device lost // Device lost
void notifyDeviceLost() override; void notifyDeviceLost() override;
virtual bool resetDevice() = 0; virtual bool resetDevice() = 0;
virtual RendererClass getRendererClass() const = 0; virtual RendererClass getRendererClass() const = 0;
virtual void *getD3DDevice() = 0;
gl::Error getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut); gl::Error getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut);
......
...@@ -671,6 +671,11 @@ SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shar ...@@ -671,6 +671,11 @@ SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shar
return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
} }
void *Renderer11::getD3DDevice()
{
return reinterpret_cast<void*>(mDevice);
}
gl::Error Renderer11::generateSwizzle(gl::Texture *texture) gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
{ {
if (texture) if (texture)
......
...@@ -199,6 +199,7 @@ class Renderer11 : public RendererD3D ...@@ -199,6 +199,7 @@ class Renderer11 : public RendererD3D
// D3D11-renderer specific methods // D3D11-renderer specific methods
ID3D11Device *getDevice() { return mDevice; } ID3D11Device *getDevice() { return mDevice; }
void *getD3DDevice() override;
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; }; ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; };
DXGIFactory *getDxgiFactory() { return mDxgiFactory; }; DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "third_party/trace_event/trace_event.h" #include "third_party/trace_event/trace_event.h"
#include <sstream> #include <sstream>
#include <EGL/eglext.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
...@@ -641,6 +642,11 @@ SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE share ...@@ -641,6 +642,11 @@ SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE share
return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
} }
void *Renderer9::getD3DDevice()
{
return reinterpret_cast<void*>(mDevice);
}
gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery)
{ {
if (mEventQueryPool.empty()) if (mEventQueryPool.empty())
......
...@@ -133,6 +133,7 @@ class Renderer9 : public RendererD3D ...@@ -133,6 +133,7 @@ class Renderer9 : public RendererD3D
GUID getAdapterIdentifier() const override; GUID getAdapterIdentifier() const override;
IDirect3DDevice9 *getDevice() { return mDevice; } IDirect3DDevice9 *getDevice() { return mDevice; }
void *getD3DDevice() override;
virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const;
......
...@@ -394,6 +394,12 @@ static int QueryWGLFormatAttrib(HDC dc, int format, int attribName, const Functi ...@@ -394,6 +394,12 @@ static int QueryWGLFormatAttrib(HDC dc, int format, int attribName, const Functi
return result; return result;
} }
egl::Error DisplayWGL::getDevice(DeviceImpl **device)
{
UNIMPLEMENTED();
return egl::Error(EGL_BAD_DISPLAY);
}
egl::ConfigSet DisplayWGL::generateConfigs() const egl::ConfigSet DisplayWGL::generateConfigs() const
{ {
egl::ConfigSet configs; egl::ConfigSet configs;
......
...@@ -44,6 +44,8 @@ class DisplayWGL : public DisplayGL ...@@ -44,6 +44,8 @@ class DisplayWGL : public DisplayGL
bool isValidNativeWindow(EGLNativeWindowType window) const override; bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error getDevice(DeviceImpl **device) override;
std::string getVendorString() const override; std::string getVendorString() const override;
private: private:
......
...@@ -242,6 +242,21 @@ EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_d ...@@ -242,6 +242,21 @@ EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_d
return egl::GetPlatformDisplayEXT(platform, native_display, attrib_list); return egl::GetPlatformDisplayEXT(platform, native_display, attrib_list);
} }
EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value)
{
return egl::QueryDisplayAttribEXT(dpy, attribute, value);
}
EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribute, EGLAttrib *value)
{
return egl::QueryDeviceAttribEXT(device, attribute, value);
}
const char * EGLAPIENTRY eglQueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
{
return egl::QueryDeviceStringEXT(device, name);
}
__eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
{ {
return egl::GetProcAddress(procname); return egl::GetProcAddress(procname);
......
...@@ -39,6 +39,9 @@ EXPORTS ...@@ -39,6 +39,9 @@ EXPORTS
eglGetPlatformDisplayEXT @35 eglGetPlatformDisplayEXT @35
eglQuerySurfacePointerANGLE @36 eglQuerySurfacePointerANGLE @36
eglPostSubBufferNV @37 eglPostSubBufferNV @37
eglQueryDisplayAttribEXT @48
eglQueryDeviceAttribEXT @49
eglQueryDeviceStringEXT @50
; 1.5 entry points ; 1.5 entry points
eglCreateSync @38 eglCreateSync @38
......
...@@ -62,6 +62,8 @@ ...@@ -62,6 +62,8 @@
'libANGLE/Context.h', 'libANGLE/Context.h',
'libANGLE/Data.cpp', 'libANGLE/Data.cpp',
'libANGLE/Data.h', 'libANGLE/Data.h',
'libANGLE/Device.cpp',
'libANGLE/Device.h',
'libANGLE/Display.cpp', 'libANGLE/Display.cpp',
'libANGLE/Display.h', 'libANGLE/Display.h',
'libANGLE/Error.cpp', 'libANGLE/Error.cpp',
...@@ -116,6 +118,8 @@ ...@@ -116,6 +118,8 @@
'libANGLE/queryconversions.h', 'libANGLE/queryconversions.h',
'libANGLE/renderer/BufferImpl.h', 'libANGLE/renderer/BufferImpl.h',
'libANGLE/renderer/CompilerImpl.h', 'libANGLE/renderer/CompilerImpl.h',
'libANGLE/renderer/DeviceImpl.cpp',
'libANGLE/renderer/DeviceImpl.h',
'libANGLE/renderer/DisplayImpl.cpp', 'libANGLE/renderer/DisplayImpl.cpp',
'libANGLE/renderer/DisplayImpl.h', 'libANGLE/renderer/DisplayImpl.h',
'libANGLE/renderer/FenceNVImpl.h', 'libANGLE/renderer/FenceNVImpl.h',
...@@ -158,6 +162,8 @@ ...@@ -158,6 +162,8 @@
'libANGLE/renderer/d3d/copyimage.cpp', 'libANGLE/renderer/d3d/copyimage.cpp',
'libANGLE/renderer/d3d/copyimage.h', 'libANGLE/renderer/d3d/copyimage.h',
'libANGLE/renderer/d3d/copyimage.inl', 'libANGLE/renderer/d3d/copyimage.inl',
'libANGLE/renderer/d3d/DeviceD3D.cpp',
'libANGLE/renderer/d3d/DeviceD3D.h',
'libANGLE/renderer/d3d/DisplayD3D.cpp', 'libANGLE/renderer/d3d/DisplayD3D.cpp',
'libANGLE/renderer/d3d/DisplayD3D.h', 'libANGLE/renderer/d3d/DisplayD3D.h',
'libANGLE/renderer/d3d/DynamicHLSL.cpp', 'libANGLE/renderer/d3d/DynamicHLSL.cpp',
......
...@@ -1084,6 +1084,9 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char * ...@@ -1084,6 +1084,9 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *
static const Extension extensions[] = static const Extension extensions[] =
{ {
{ "eglQueryDeviceAttribEXT", (__eglMustCastToProperFunctionPointerType)QueryDeviceAttribEXT },
{ "eglQueryDeviceStringEXT", (__eglMustCastToProperFunctionPointerType)QueryDeviceStringEXT },
{ "eglQueryDisplayAttribEXT", (__eglMustCastToProperFunctionPointerType)QueryDisplayAttribEXT },
{ "eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)QuerySurfacePointerANGLE }, { "eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)QuerySurfacePointerANGLE },
{ "eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)PostSubBufferNV }, { "eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)PostSubBufferNV },
{ "eglGetPlatformDisplayEXT", (__eglMustCastToProperFunctionPointerType)GetPlatformDisplayEXT }, { "eglGetPlatformDisplayEXT", (__eglMustCastToProperFunctionPointerType)GetPlatformDisplayEXT },
......
...@@ -10,8 +10,10 @@ ...@@ -10,8 +10,10 @@
#include "libGLESv2/global_state.h" #include "libGLESv2/global_state.h"
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/Device.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/validationEGL.h" #include "libANGLE/validationEGL.h"
#include "libANGLE/renderer/renderer.h"
#include "common/debug.h" #include "common/debug.h"
...@@ -268,4 +270,113 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -268,4 +270,113 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
return Display::getDisplay(displayId, AttributeMap(attrib_list)); return Display::getDisplay(displayId, AttributeMap(attrib_list));
} }
// EGL_EXT_device_query
EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribute, EGLAttrib *value)
{
EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)",
device, attribute, value);
Device *dev = static_cast<Device*>(device);
if (dev == EGL_NO_DEVICE_EXT)
{
SetGlobalError(Error(EGL_BAD_ACCESS));
return EGL_FALSE;
}
Display *display = dev->getDisplay();
Error error(EGL_SUCCESS);
if (!display->getExtensions().deviceQuery)
{
SetGlobalError(Error(EGL_BAD_ACCESS));
return EGL_FALSE;
}
// validate the attribute parameter
switch (attribute)
{
case EGL_D3D11_DEVICE_ANGLE:
if (!dev->getExtensions().deviceD3D || dev->getType() != EGL_D3D11_DEVICE_ANGLE)
{
SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE;
}
error = dev->getDevice(value);
break;
case EGL_D3D9_DEVICE_ANGLE:
if (!dev->getExtensions().deviceD3D || dev->getType() != EGL_D3D9_DEVICE_ANGLE)
{
SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE;
}
error = dev->getDevice(value);
break;
default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE;
}
SetGlobalError(error);
return (error.isError() ? EGL_FALSE : EGL_TRUE);
}
// EGL_EXT_device_query
const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
{
EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint name = %d)",
device, name);
Device *dev = static_cast<Device*>(device);
if (dev == EGL_NO_DEVICE_EXT)
{
SetGlobalError(Error(EGL_BAD_DEVICE_EXT));
return nullptr;
}
const char *result;
switch (name)
{
case EGL_EXTENSIONS:
result = dev->getExtensionString().c_str();
break;
default:
SetGlobalError(Error(EGL_BAD_DEVICE_EXT));
return nullptr;
}
SetGlobalError(Error(EGL_SUCCESS));
return result;
}
// EGL_EXT_device_query
EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value)
{
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)",
dpy, attribute, value);
Display *display = static_cast<Display*>(dpy);
Error error(EGL_SUCCESS);
if (!display->getExtensions().deviceQuery)
{
SetGlobalError(Error(EGL_BAD_ACCESS));
return EGL_FALSE;
}
// validate the attribute parameter
switch (attribute)
{
case EGL_DEVICE_EXT:
*value = reinterpret_cast<EGLAttrib>(display->getDevice());
break;
default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE;
}
SetGlobalError(error);
return (error.isError() ? EGL_FALSE : EGL_TRUE);
}
} }
...@@ -25,6 +25,11 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface s ...@@ -25,6 +25,11 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface s
// EGL_EXT_platform_base // EGL_EXT_platform_base
ANGLE_EXPORT EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list); ANGLE_EXPORT EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list);
// EGL_EXT_device_query
ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
ANGLE_EXPORT const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name);
} }
#endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_ #endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
'<(angle_path)/src/tests/end2end_tests/PbufferTest.cpp', '<(angle_path)/src/tests/end2end_tests/PbufferTest.cpp',
'<(angle_path)/src/tests/end2end_tests/PointSpritesTest.cpp', '<(angle_path)/src/tests/end2end_tests/PointSpritesTest.cpp',
'<(angle_path)/src/tests/end2end_tests/ProgramBinaryTest.cpp', '<(angle_path)/src/tests/end2end_tests/ProgramBinaryTest.cpp',
'<(angle_path)/src/tests/end2end_tests/QueryDisplayAttribTest.cpp',
'<(angle_path)/src/tests/end2end_tests/ReadPixelsTest.cpp', '<(angle_path)/src/tests/end2end_tests/ReadPixelsTest.cpp',
'<(angle_path)/src/tests/end2end_tests/RendererTest.cpp', '<(angle_path)/src/tests/end2end_tests/RendererTest.cpp',
'<(angle_path)/src/tests/end2end_tests/SimpleOperationTest.cpp', '<(angle_path)/src/tests/end2end_tests/SimpleOperationTest.cpp',
......
#define ANGLE_ENABLE_D3D9
#define ANGLE_ENABLE_D3D11
#include "ANGLETest.h"
#include "com_utils.h"
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_TYPED_TEST_CASE(QueryDisplayAttributeTest, ES2_D3D9, ES2_D3D11);
template<typename T>
class QueryDisplayAttributeTest : public ANGLETest
{
protected:
QueryDisplayAttributeTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
{
mQueryDisplayAttribEXT = nullptr;
mQueryDeviceAttribEXT = nullptr;
mQueryDeviceStringEXT = nullptr;
}
void SetUp() override
{
ANGLETest::SetUp();
const char *extensionString = static_cast<const char*>(eglQueryString(getEGLWindow()->getDisplay(), EGL_EXTENSIONS));
if (strstr(extensionString, "EGL_EXT_device_query"))
{
mQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC)eglGetProcAddress("eglQueryDisplayAttribEXT");
mQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC)eglGetProcAddress("eglQueryDeviceAttribEXT");
mQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT");
}
if (!mQueryDeviceStringEXT)
{
FAIL() << "ANGLE extension EGL_EXT_device_query export eglQueryDeviceStringEXT was not found";
}
if (!mQueryDisplayAttribEXT)
{
FAIL() << "ANGLE extension EGL_EXT_device_query export eglQueryDisplayAttribEXT was not found";
}
if (!mQueryDeviceAttribEXT)
{
FAIL() << "ANGLE extension EGL_EXT_device_query export eglQueryDeviceAttribEXT was not found";
}
EGLAttrib angleDevice = 0;
EXPECT_EQ(EGL_TRUE, mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
extensionString = static_cast<const char*>(mQueryDeviceStringEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_EXTENSIONS));
if (strstr(extensionString, "EGL_ANGLE_device_d3d") == NULL)
{
FAIL() << "ANGLE extension EGL_ANGLE_device_d3d was not found";
}
}
void TearDown() override
{
ANGLETest::TearDown();
}
PFNEGLQUERYDISPLAYATTRIBEXTPROC mQueryDisplayAttribEXT;
PFNEGLQUERYDEVICEATTRIBEXTPROC mQueryDeviceAttribEXT;
PFNEGLQUERYDEVICESTRINGEXTPROC mQueryDeviceStringEXT;
};
// This test attempts to obtain a D3D11 device and a D3D9 device using the eglQueryDeviceAttribEXT function.
// If the test is configured to use D3D11 then it should succeed to obtain a D3D11 device.
// If the test is confitured to use D3D9, then it should succeed to obtain a D3D9 device.
TYPED_TEST(QueryDisplayAttributeTest, QueryDevice)
{
EGLAttrib device = 0;
EGLAttrib angleDevice = 0;
if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
EXPECT_EQ(EGL_TRUE, mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
EXPECT_EQ(EGL_TRUE, mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_D3D11_DEVICE_ANGLE, &device));
ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device*>(device);
IDXGIDevice *dxgiDevice = DynamicCastComObject<IDXGIDevice>(d3d11Device);
EXPECT_TRUE(dxgiDevice != nullptr);
SafeRelease(dxgiDevice);
}
if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
{
EXPECT_EQ(EGL_TRUE, mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
EXPECT_EQ(EGL_TRUE, mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_D3D9_DEVICE_ANGLE, &device));
IDirect3DDevice9 *d3d9Device = reinterpret_cast<IDirect3DDevice9*>(device);
IDirect3D9 *d3d9 = nullptr;
EXPECT_EQ(S_OK, d3d9Device->GetDirect3D(&d3d9));
EXPECT_TRUE(d3d9 != nullptr);
SafeRelease(d3d9);
}
}
// This test attempts to obtain a D3D11 device from a D3D9 configured system and a D3D9 device from
// a D3D11 configured system using the eglQueryDeviceAttribEXT function.
// If the test is configured to use D3D11 then it should fail to obtain a D3D11 device.
// If the test is confitured to use D3D9, then it should fail to obtain a D3D9 device.
TYPED_TEST(QueryDisplayAttributeTest, QueryDeviceBadAttrbiute)
{
EGLAttrib device = 0;
EGLAttrib angleDevice = 0;
if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
EXPECT_EQ(EGL_TRUE, mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
EXPECT_EQ(EGL_FALSE, mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_D3D9_DEVICE_ANGLE, &device));
}
if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
{
EXPECT_EQ(EGL_TRUE, mQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
EXPECT_EQ(EGL_FALSE, mQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_D3D11_DEVICE_ANGLE, &device));
}
}
//
// Copyright (c) 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.
//
// com_utils.h: Utility functions for working with COM objects
#ifndef UTIL_COM_UTILS_H
#define UTIL_COM_UTILS_H
template <typename outType>
inline outType *DynamicCastComObject(IUnknown *object)
{
outType *outObject = nullptr;
HRESULT result = object->QueryInterface(__uuidof(outType), reinterpret_cast<void**>(&outObject));
if (SUCCEEDED(result))
{
return outObject;
}
else
{
SafeRelease(outObject);
return nullptr;
}
}
#endif // UTIL_COM_UTILS_H
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
], ],
'sources': 'sources':
[ [
'com_utils.h',
'keyboard.h', 'keyboard.h',
'mouse.h', 'mouse.h',
'path_utils.h', 'path_utils.h',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment