Commit 2018c0ba by Geoff Lang Committed by Commit Bot

Add a EGL_ANGLE_d3d_texture_client_buffer extension.

Allows creation of pbuffers from D3D texture objects. BUG=540829 BUG=angleproject:1144 Change-Id: If8ea717ef011608cd01357c217837133d726d3ea Reviewed-on: https://chromium-review.googlesource.com/316804 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 9f4583dd
Name
ANGLE_d3d_texture_client_buffer
Name Strings
EGL_ANGLE_d3d_texture_client_buffer
Contributors
Geoff Lang
Contacts
Geoff Lang, Google Inc. (geofflang 'at' google.com)
Status
Draft
Version
Version 1, Oct 5, 2016
Number
EGL Extension #??
Dependencies
This extension is written against the wording of the EGL 1.4
Specification.
References the EGL_ANGLE_device_d3d extension.
Overview
This extension allows creating EGL surfaces from D3D texture objects.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted in the <buftype> parameter of eglCreatePbufferFromClientBuffer:
EGL_D3D_TEXTURE_ANGLE 0x33A3
Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
Replace the last sentence of paragraph 1 of Section 3.5.3 with the
following text.
"Currently, the only client API resources which may be bound in this
fashion are OpenVG VGImage objects and Direct3D texture objects."
Replace the last sentence of paragraph 2 ("To bind a client API...") of
Section 3.5.3 with the following text.
"When <buftype> is EGL_OPENVG_IMAGE or EGL_D3D_TEXTURE_ANGLE, the width and
height of the pbuffer are determined by the width and height of <buffer>."
Replace the third paragraph of Section 3.5.3 with the following text.
"<buftype> specifies the type of buffer to be bound. The only allowed values
of <buftype> are EGL_OPENVG_IMAGE and EGL_D3D_TEXTURE_ANGLE".
Append the following text to the fourth paragraph of Section 3.5.3.
"When <buftype> is EGL_D3D_TEXTURE_ANGLE, <buffer> must be
a valid D3D texture object, cast into the type EGLClientBuffer. See table
egl.restrictions for acceptable texture object types and formats. If the
EGL_ANGLE_device_d3d extension is present, the provided D3D texture object
must have been created by the same D3D device queried from the display.
If these requirements are not met, an EGL_BAD_PARAMETER error is
generated."
---------------------------------------------------------------------------
Resource Type Resource Restrictions
---------------------------------------------------------------------------
IDirect3DTexture9 Memory pool must be D3DPOOL_DEFAULT. Format must be
D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_A16B16G16R16F or
D3DFMT_A32B32G32R32F.
ID3D11Texture2D Usage flags must be D3D11_USAGE_DEFAULT. Format must be
DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
DXGI_FORMAT_R16G16B16A16_FLOAT or
DXGI_FORMAT_R32G32B32A32_FLOAT.
--------------------------------------------------------------------------
Table egl.restrictions - Restrictions on D3D resources that can be used
as a <buffer>.
--------------------------------------------------------------------------
Append to the end of Section 3.5.3.
"When a pbuffer is created with type EGL_D3D_TEXTURE_ANGLE, the contents
of the associcated D3D texture object are undefined while the pbuffer is
the current read surface, draw surface or bound to a client texture."
Issues
Revision History
Version 1, 2016/10/05 - first draft.
......@@ -472,6 +472,11 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
#endif /* EGL_ANGLE_keyed_mutex */
#ifndef EGL_ANGLE_d3d_texture_client_buffer
#define EGL_ANGLE_d3d_texture_client_buffer 1
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
#endif /* EGL_ANGLE_d3d_texture_client_buffer */
#ifndef EGL_ANGLE_query_surface_pointer
#define EGL_ANGLE_query_surface_pointer 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
......
......@@ -762,6 +762,7 @@ Caps::Caps()
DisplayExtensions::DisplayExtensions()
: createContextRobustness(false),
d3dShareHandleClientBuffer(false),
d3dTextureClientBuffer(false),
surfaceD3DTexture2DShareHandle(false),
querySurfacePointer(false),
windowFixedSize(false),
......@@ -800,6 +801,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
// | Extension name | Supported flag | Output vector |
InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings);
InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer", d3dTextureClientBuffer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings);
InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
......
......@@ -533,6 +533,9 @@ struct DisplayExtensions
// EGL_ANGLE_d3d_share_handle_client_buffer
bool d3dShareHandleClientBuffer;
// EGL_ANGLE_d3d_texture_client_buffer
bool d3dTextureClientBuffer;
// EGL_ANGLE_surface_d3d_texture_2d_share_handle
bool surfaceD3DTexture2DShareHandle;
......
......@@ -587,8 +587,11 @@ Error Display::createPbufferSurface(const Config *configuration, const Attribute
return egl::Error(EGL_SUCCESS);
}
Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle,
const AttributeMap &attribs, Surface **outSurface)
Error Display::createPbufferFromClientBuffer(const Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs,
Surface **outSurface)
{
ASSERT(isInitialized());
......@@ -598,7 +601,7 @@ Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLCli
}
std::unique_ptr<Surface> surface(
new PbufferSurface(mImplementation, configuration, shareHandle, attribs));
new PbufferSurface(mImplementation, configuration, buftype, clientBuffer, attribs));
ANGLE_TRY(surface->initialize());
ASSERT(outSurface != nullptr);
......@@ -947,6 +950,14 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const
return mImplementation->isValidNativeWindow(window);
}
Error Display::validateClientBuffer(const Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs)
{
return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs);
}
bool Display::isValidDisplay(const egl::Display *display)
{
const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap();
......
......@@ -57,7 +57,10 @@ class Display final : angle::NonCopyable
Error createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs,
Surface **outSurface);
Error createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface);
Error createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, const AttributeMap &attribs,
Error createPbufferFromClientBuffer(const Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs,
Surface **outSurface);
Error createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs,
Surface **outSurface);
......@@ -88,6 +91,11 @@ class Display final : angle::NonCopyable
bool isValidStream(const Stream *stream) const;
bool isValidNativeWindow(EGLNativeWindowType window) const;
Error validateClientBuffer(const Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs);
static bool isValidDisplay(const egl::Display *display);
static bool isValidNativeDisplay(EGLNativeDisplayType display);
static bool hasExistingWindowSurface(EGLNativeWindowType window);
......
......@@ -211,19 +211,23 @@ EGLint Surface::getHeight() const
Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer)
{
ASSERT(!mTexture.get());
ANGLE_TRY(mImplementation->bindTexImage(texture, buffer));
texture->bindTexImageFromSurface(this);
mTexture.set(texture);
return mImplementation->bindTexImage(texture, buffer);
return Error(EGL_SUCCESS);
}
Error Surface::releaseTexImage(EGLint buffer)
{
ANGLE_TRY(mImplementation->releaseTexImage(buffer));
ASSERT(mTexture.get());
mTexture->releaseTexImageFromSurface();
mTexture.set(nullptr);
return mImplementation->releaseTexImage(buffer);
return Error(EGL_SUCCESS);
}
Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
......@@ -308,12 +312,13 @@ PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
const Config *config,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs)
: Surface(EGL_PBUFFER_BIT, config, attribs)
{
mImplementation =
implFactory->createPbufferFromClientBuffer(mState, config, shareHandle, attribs);
implFactory->createPbufferFromClientBuffer(mState, config, buftype, clientBuffer, attribs);
}
PbufferSurface::~PbufferSurface()
......
......@@ -164,7 +164,8 @@ class PbufferSurface final : public Surface
const AttributeMap &attribs);
PbufferSurface(rx::EGLImplFactory *implFactory,
const Config *config,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs);
~PbufferSurface() override;
};
......
......@@ -41,6 +41,15 @@ const egl::DisplayExtensions &DisplayImpl::getExtensions() const
return mExtensions;
}
egl::Error DisplayImpl::validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
UNREACHABLE();
return egl::Error(EGL_BAD_DISPLAY, "DisplayImpl::validateClientBuffer unimplemented.");
}
const egl::Caps &DisplayImpl::getCaps() const
{
if (!mCapsInitialized)
......
......@@ -59,6 +59,10 @@ class DisplayImpl : public EGLImplFactory
virtual egl::Error restoreLostDevice() = 0;
virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0;
virtual egl::Error validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const;
virtual std::string getVendorString() const = 0;
......
......@@ -47,7 +47,8 @@ class EGLImplFactory : angle::NonCopyable
const egl::AttributeMap &attribs) = 0;
virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) = 0;
virtual SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......
......@@ -176,16 +176,18 @@ SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state,
const egl::AttributeMap &attribs)
{
ASSERT(mRenderer != nullptr);
return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, nullptr, attribs);
return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, 0, nullptr, attribs);
}
SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
ASSERT(mRenderer != nullptr);
return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, shareHandle, attribs);
return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, buftype, clientBuffer,
attribs);
}
SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state,
......@@ -291,6 +293,26 @@ bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const
return mRenderer->isValidNativeWindow(window);
}
egl::Error DisplayD3D::validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
switch (buftype)
{
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
return mRenderer->validateShareHandle(configuration, static_cast<HANDLE>(clientBuffer),
attribs);
case EGL_D3D_TEXTURE_ANGLE:
return mRenderer->getD3DTextureInfo(static_cast<IUnknown *>(clientBuffer), nullptr,
nullptr, nullptr);
default:
return DisplayImpl::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
}
}
void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
{
mRenderer->generateDisplayExtensions(outExtensions);
......
......@@ -34,7 +34,8 @@ class DisplayD3D : public DisplayImpl
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......@@ -59,6 +60,10 @@ class DisplayD3D : public DisplayImpl
egl::Error restoreLostDevice() override;
bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
egl::Error getDevice(DeviceImpl **device) override;
......
......@@ -127,9 +127,17 @@ class RendererD3D : public BufferFactoryD3D
virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation) = 0;
virtual egl::Error getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const = 0;
virtual egl::Error validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const = 0;
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0;
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
......
......@@ -26,7 +26,8 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
egl::Display *display,
const egl::Config *config,
EGLNativeWindowType window,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
: SurfaceImpl(state),
mRenderer(renderer),
......@@ -41,19 +42,39 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
mWidth(static_cast<EGLint>(attribs.get(EGL_WIDTH, 0))),
mHeight(static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0))),
mSwapInterval(1),
mShareHandle(reinterpret_cast<HANDLE *>(shareHandle))
mShareHandle(0),
mD3DTexture(nullptr)
{
if (window != nullptr && !mFixedSize)
{
mWidth = -1;
mHeight = -1;
}
switch (buftype)
{
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
mShareHandle = static_cast<HANDLE>(clientBuffer);
break;
case EGL_D3D_TEXTURE_ANGLE:
mD3DTexture = static_cast<IUnknown *>(clientBuffer);
ASSERT(mD3DTexture != nullptr);
mD3DTexture->AddRef();
mRenderer->getD3DTextureInfo(mD3DTexture, &mWidth, &mHeight, &mRenderTargetFormat);
mDepthStencilFormat = GL_NONE;
break;
default:
break;
}
}
SurfaceD3D::~SurfaceD3D()
{
releaseSwapChain();
SafeDelete(mNativeWindow);
SafeRelease(mD3DTexture);
}
void SurfaceD3D::releaseSwapChain()
......@@ -127,8 +148,8 @@ egl::Error SurfaceD3D::resetSwapChain()
height = mHeight;
}
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat,
mDepthStencilFormat, mOrientation);
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture,
mRenderTargetFormat, mDepthStencilFormat, mOrientation);
if (!mSwapChain)
{
return egl::Error(EGL_BAD_ALLOC);
......@@ -346,7 +367,14 @@ WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state,
const egl::Config *config,
EGLNativeWindowType window,
const egl::AttributeMap &attribs)
: SurfaceD3D(state, renderer, display, config, window, static_cast<EGLClientBuffer>(0), attribs)
: SurfaceD3D(state,
renderer,
display,
config,
window,
0,
static_cast<EGLClientBuffer>(0),
attribs)
{
}
......@@ -358,14 +386,16 @@ PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state,
RendererD3D *renderer,
egl::Display *display,
const egl::Config *config,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
: SurfaceD3D(state,
renderer,
display,
config,
static_cast<EGLNativeWindowType>(0),
shareHandle,
buftype,
clientBuffer,
attribs)
{
}
......
......@@ -62,7 +62,8 @@ class SurfaceD3D : public SurfaceImpl
egl::Display *display,
const egl::Config *config,
EGLNativeWindowType window,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs);
egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
......@@ -88,6 +89,7 @@ class SurfaceD3D : public SurfaceImpl
EGLint mSwapInterval;
HANDLE mShareHandle;
IUnknown *mD3DTexture;
};
class WindowSurfaceD3D : public SurfaceD3D
......@@ -109,7 +111,8 @@ class PbufferSurfaceD3D : public SurfaceD3D
RendererD3D *renderer,
egl::Display *display,
const egl::Config *config,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs);
~PbufferSurfaceD3D() override;
};
......
//
// Copyright (c) 2016 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.
//
// SwapChainD3D.cpp: Defines a back-end specific class that hides the details of the
// implementation-specific swapchain.
#include "libANGLE/renderer/d3d/SwapChainD3D.h"
namespace rx
{
SwapChainD3D::SwapChainD3D(HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat)
: mOffscreenRenderTargetFormat(backBufferFormat),
mDepthBufferFormat(depthBufferFormat),
mShareHandle(shareHandle),
mD3DTexture(d3dTexture)
{
if (mD3DTexture)
{
mD3DTexture->AddRef();
}
}
SwapChainD3D::~SwapChainD3D()
{
SafeRelease(mD3DTexture);
}
} // namespace rx
......@@ -29,14 +29,11 @@ class RenderTargetD3D;
class SwapChainD3D : angle::NonCopyable
{
public:
SwapChainD3D(HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
: mOffscreenRenderTargetFormat(backBufferFormat),
mDepthBufferFormat(depthBufferFormat),
mShareHandle(shareHandle)
{
}
virtual ~SwapChainD3D() {};
SwapChainD3D(HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat);
virtual ~SwapChainD3D();
virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
......@@ -59,7 +56,8 @@ class SwapChainD3D : angle::NonCopyable
const GLenum mDepthBufferFormat;
HANDLE mShareHandle;
IUnknown *mD3DTexture;
};
}
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
......@@ -1081,6 +1081,7 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
outExtensions->d3dShareHandleClientBuffer = true;
outExtensions->surfaceD3DTexture2DShareHandle = true;
}
outExtensions->d3dTextureClientBuffer = true;
outExtensions->keyedMutex = true;
outExtensions->querySurfacePointer = true;
......@@ -1193,14 +1194,119 @@ NativeWindowD3D *Renderer11::createNativeWindow(EGLNativeWindowType window,
#endif
}
egl::Error Renderer11::getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const
{
ID3D11Texture2D *texture = d3d11::DynamicCastComObject<ID3D11Texture2D>(d3dTexture);
if (texture == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER, "client buffer is not a ID3D11Texture2D");
}
ID3D11Device *textureDevice = nullptr;
texture->GetDevice(&textureDevice);
if (textureDevice != mDevice)
{
SafeRelease(texture);
return egl::Error(EGL_BAD_PARAMETER, "Texture's device does not match.");
}
SafeRelease(textureDevice);
D3D11_TEXTURE2D_DESC desc = {0};
texture->GetDesc(&desc);
SafeRelease(texture);
if (width)
{
*width = static_cast<EGLint>(desc.Width);
}
if (height)
{
*height = static_cast<EGLint>(desc.Height);
}
// From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
switch (desc.Format)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_R16G16B16A16_FLOAT:
case DXGI_FORMAT_R32G32B32A32_FLOAT:
break;
default:
return egl::Error(EGL_BAD_PARAMETER, "Unknown client buffer texture format: %u.",
desc.Format);
}
if (fboFormat)
{
const angle::Format &angleFormat = d3d11_angle::GetFormat(desc.Format);
*fboFormat = angleFormat.fboImplementationInternalFormat;
}
return egl::Error(EGL_SUCCESS);
}
egl::Error Renderer11::validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const
{
if (shareHandle == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER, "NULL share handle.");
}
ID3D11Resource *tempResource11 = nullptr;
HRESULT result = mDevice->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
(void **)&tempResource11);
if (FAILED(result))
{
return egl::Error(EGL_BAD_PARAMETER, "Failed to open share handle, result: 0x%X.", result);
}
ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(tempResource11);
SafeRelease(tempResource11);
if (texture2D == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER,
"Failed to query ID3D11Texture2D object from share handle.");
}
D3D11_TEXTURE2D_DESC desc = {0};
texture2D->GetDesc(&desc);
SafeRelease(texture2D);
EGLint width = attribs.getAsInt(EGL_WIDTH, 0);
EGLint height = attribs.getAsInt(EGL_HEIGHT, 0);
ASSERT(width != 0 && height != 0);
const d3d11::Format &backbufferFormatInfo =
d3d11::Format::Get(config->renderTargetFormat, getRenderer11DeviceCaps());
if (desc.Width != static_cast<UINT>(width) || desc.Height != static_cast<UINT>(height) ||
desc.Format != backbufferFormatInfo.texFormat || desc.MipLevels != 1 || desc.ArraySize != 1)
{
return egl::Error(EGL_BAD_PARAMETER, "Invalid texture parameters in share handle texture.");
}
return egl::Error(EGL_SUCCESS);
}
SwapChainD3D *Renderer11::createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
{
return new SwapChain11(this, GetAs<NativeWindow11>(nativeWindow), shareHandle, backBufferFormat,
depthBufferFormat, orientation);
return new SwapChain11(this, GetAs<NativeWindow11>(nativeWindow), shareHandle, d3dTexture,
backBufferFormat, depthBufferFormat, orientation);
}
void *Renderer11::getD3DDevice()
......
......@@ -123,9 +123,17 @@ class Renderer11 : public RendererD3D
SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation) override;
egl::Error getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const override;
egl::Error validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const override;
gl::Error setSamplerState(gl::SamplerType type,
int index,
......@@ -334,7 +342,7 @@ class Renderer11 : public RendererD3D
bool colorBlit, bool depthBlit, bool stencilBlit);
bool isES3Capable() const;
const Renderer11DeviceCaps &getRenderer11DeviceCaps() { return mRenderer11DeviceCaps; };
const Renderer11DeviceCaps &getRenderer11DeviceCaps() const { return mRenderer11DeviceCaps; };
RendererClass getRendererClass() const override { return RENDERER_D3D11; }
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
......
......@@ -51,10 +51,11 @@ bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow11 *nativeWindow, E
SwapChain11::SwapChain11(Renderer11 *renderer,
NativeWindow11 *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
: SwapChainD3D(shareHandle, backBufferFormat, depthBufferFormat),
: SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
mRenderer(renderer),
mWidth(-1),
mHeight(-1),
......@@ -194,42 +195,29 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe
const d3d11::Format &backbufferFormatInfo =
d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
// If the app passed in a share handle, open the resource
// See EGL_ANGLE_d3d_share_handle_client_buffer
if (mAppCreatedShareHandle)
// If the app passed in a share handle or D3D texture, open the resource
// See EGL_ANGLE_d3d_share_handle_client_buffer and EGL_ANGLE_d3d_texture_client_buffer
if (mAppCreatedShareHandle || mD3DTexture != nullptr)
{
ID3D11Resource *tempResource11;
HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
if (FAILED(result))
if (mAppCreatedShareHandle)
{
ERR("Failed to open the swap chain pbuffer share handle: %08lX", result);
release();
return EGL_BAD_PARAMETER;
}
result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
SafeRelease(tempResource11);
ID3D11Resource *tempResource11;
HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource),
(void **)&tempResource11);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
mOffscreenTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(tempResource11);
SafeRelease(tempResource11);
ASSERT(SUCCEEDED(mOffscreenTexture != nullptr));
}
else if (mD3DTexture != nullptr)
{
ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result);
release();
return EGL_BAD_PARAMETER;
mOffscreenTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(mD3DTexture);
ASSERT(mOffscreenTexture != nullptr);
}
// Validate offscreen texture parameters
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
mOffscreenTexture->GetDesc(&offscreenTextureDesc);
if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
offscreenTextureDesc.Height != (UINT)backbufferHeight ||
offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1)
else
{
ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
release();
return EGL_BAD_PARAMETER;
UNREACHABLE();
}
}
else
......
......@@ -24,6 +24,7 @@ class SwapChain11 final : public SwapChainD3D
SwapChain11(Renderer11 *renderer,
NativeWindow11 *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation);
......
......@@ -60,6 +60,11 @@ GLenum GetComponentType(DXGI_FORMAT dxgiFormat);
} // namespace d3d11
namespace d3d11_angle
{
const angle::Format &GetFormat(DXGI_FORMAT dxgiFormat);
}
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
......@@ -525,6 +525,7 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions)
outExtensions->d3dShareHandleClientBuffer = true;
outExtensions->surfaceD3DTexture2DShareHandle = true;
}
outExtensions->d3dTextureClientBuffer = true;
outExtensions->querySurfacePointer = true;
outExtensions->windowFixedSize = true;
......@@ -672,12 +673,111 @@ NativeWindowD3D *Renderer9::createNativeWindow(EGLNativeWindowType window,
SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
{
return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, backBufferFormat,
depthBufferFormat, orientation);
return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, d3dTexture,
backBufferFormat, depthBufferFormat, orientation);
}
egl::Error Renderer9::getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const
{
IDirect3DTexture9 *texture = nullptr;
if (FAILED(d3dTexture->QueryInterface(&texture)))
{
return egl::Error(EGL_BAD_PARAMETER, "client buffer is not a IDirect3DTexture9");
}
IDirect3DDevice9 *textureDevice = nullptr;
texture->GetDevice(&textureDevice);
if (textureDevice != mDevice)
{
SafeRelease(texture);
return egl::Error(EGL_BAD_PARAMETER, "Texture's device does not match.");
}
SafeRelease(textureDevice);
D3DSURFACE_DESC desc;
texture->GetLevelDesc(0, &desc);
SafeRelease(texture);
if (width)
{
*width = static_cast<EGLint>(desc.Width);
}
if (height)
{
*height = static_cast<EGLint>(desc.Height);
}
// From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
switch (desc.Format)
{
case D3DFMT_R8G8B8:
case D3DFMT_A8R8G8B8:
case D3DFMT_A16B16G16R16F:
case D3DFMT_A32B32G32R32F:
break;
default:
return egl::Error(EGL_BAD_PARAMETER, "Unknown client buffer texture format: %u.",
desc.Format);
}
if (fboFormat)
{
const auto &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
ASSERT(d3dFormatInfo.info != nullptr);
*fboFormat = d3dFormatInfo.info->fboImplementationInternalFormat;
}
return egl::Error(EGL_SUCCESS);
}
egl::Error Renderer9::validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const
{
if (shareHandle == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER, "NULL share handle.");
}
EGLint width = attribs.getAsInt(EGL_WIDTH, 0);
EGLint height = attribs.getAsInt(EGL_HEIGHT, 0);
ASSERT(width != 0 && height != 0);
const d3d9::TextureFormat &backBufferd3dFormatInfo =
d3d9::GetTextureFormatInfo(config->renderTargetFormat);
IDirect3DTexture9 *texture = nullptr;
HRESULT result = mDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET,
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT,
&texture, &shareHandle);
if (FAILED(result))
{
return egl::Error(EGL_BAD_PARAMETER, "Failed to open share handle, result: 0x%X.", result);
}
DWORD levelCount = texture->GetLevelCount();
D3DSURFACE_DESC desc;
texture->GetLevelDesc(0, &desc);
SafeRelease(texture);
if (levelCount != 1 || desc.Width != static_cast<UINT>(width) ||
desc.Height != static_cast<UINT>(height) ||
desc.Format != backBufferd3dFormatInfo.texFormat)
{
return egl::Error(EGL_BAD_PARAMETER, "Invalid texture parameters in share handle texture.");
}
return egl::Error(EGL_SUCCESS);
}
ContextImpl *Renderer9::createContext(const gl::ContextState &state)
......
......@@ -88,9 +88,17 @@ class Renderer9 : public RendererD3D
SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation) override;
egl::Error getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const override;
egl::Error validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const override;
ContextImpl *createContext(const gl::ContextState &state) override;
......
......@@ -19,10 +19,11 @@ namespace rx
SwapChain9::SwapChain9(Renderer9 *renderer,
NativeWindow9 *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation)
: SwapChainD3D(shareHandle, backBufferFormat, depthBufferFormat),
: SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
mRenderer(renderer),
mWidth(-1),
mHeight(-1),
......@@ -105,28 +106,37 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
SafeRelease(mOffscreenTexture);
SafeRelease(mDepthStencil);
HANDLE *pShareHandle = NULL;
if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport())
const d3d9::TextureFormat &backBufferd3dFormatInfo =
d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat);
if (mD3DTexture != nullptr)
{
pShareHandle = &mShareHandle;
result = mD3DTexture->QueryInterface(&mOffscreenTexture);
ASSERT(SUCCEEDED(result));
}
const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat);
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture,
pShareHandle);
if (FAILED(result))
else
{
ERR("Could not create offscreen texture: %08lX", result);
release();
if (d3d9::isDeviceLostError(result))
HANDLE *pShareHandle = NULL;
if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport())
{
return EGL_CONTEXT_LOST;
pShareHandle = &mShareHandle;
}
else
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT,
&mOffscreenTexture, pShareHandle);
if (FAILED(result))
{
return EGL_BAD_ALLOC;
ERR("Could not create offscreen texture: %08lX", result);
release();
if (d3d9::isDeviceLostError(result))
{
return EGL_CONTEXT_LOST;
}
else
{
return EGL_BAD_ALLOC;
}
}
}
......
......@@ -24,6 +24,7 @@ class SwapChain9 : public SwapChainD3D
SwapChain9(Renderer9 *renderer,
NativeWindow9 *nativeWindow,
HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat,
EGLint orientation);
......
......@@ -22,8 +22,7 @@
namespace rx
{
DisplayGL::DisplayGL()
: mRenderer(nullptr)
DisplayGL::DisplayGL() : mRenderer(nullptr), mCurrentDrawSurface(nullptr)
{
}
......@@ -73,6 +72,13 @@ StreamProducerImpl *DisplayGL::createStreamProducerD3DTextureNV12(
egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
{
// Notify the previous surface (if it still exists) that it is no longer current
if (mCurrentDrawSurface && mSurfaceSet.find(mCurrentDrawSurface) != mSurfaceSet.end())
{
ANGLE_TRY(GetImplAs<SurfaceGL>(mCurrentDrawSurface)->unMakeCurrent());
}
mCurrentDrawSurface = nullptr;
if (!drawSurface)
{
return egl::Error(EGL_SUCCESS);
......@@ -83,7 +89,10 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS
glContext->getStateManager()->pauseTransformFeedback(context->getContextState());
SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface);
return glDrawSurface->makeCurrent();
ANGLE_TRY(glDrawSurface->makeCurrent());
mCurrentDrawSurface = drawSurface;
return egl::Error(EGL_SUCCESS);
}
gl::Version DisplayGL::getMaxSupportedESVersion() const
......
......@@ -12,6 +12,11 @@
#include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
namespace egl
{
class Surface;
}
namespace rx
{
......@@ -48,6 +53,8 @@ class DisplayGL : public DisplayImpl
virtual const FunctionsGL *getFunctionsGL() const = 0;
RendererGL *mRenderer;
egl::Surface *mCurrentDrawSurface;
};
}
......
......@@ -34,4 +34,9 @@ egl::Error SurfaceGL::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuin
UNREACHABLE();
return egl::Error(EGL_BAD_SURFACE);
}
egl::Error SurfaceGL::unMakeCurrent()
{
return egl::Error(EGL_SUCCESS);
}
}
......@@ -26,6 +26,7 @@ class SurfaceGL : public SurfaceImpl
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
virtual egl::Error makeCurrent() = 0;
virtual egl::Error unMakeCurrent();
private:
RendererGL *mRenderer;
......
......@@ -35,7 +35,8 @@ class DisplayCGL : public DisplayGL
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......
......@@ -128,7 +128,8 @@ SurfaceImpl *DisplayCGL::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayCGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
......
......@@ -185,7 +185,8 @@ SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state
SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
......
......@@ -36,7 +36,8 @@ class DisplayAndroid : public DisplayEGL
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......
......@@ -859,7 +859,8 @@ SurfaceImpl *DisplayOzone::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayOzone::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
......
......@@ -122,7 +122,8 @@ class DisplayOzone final : public DisplayEGL
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......
......@@ -410,7 +410,8 @@ SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayGLX::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
......
......@@ -53,7 +53,8 @@ class DisplayGLX : public DisplayGL
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......
// 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.
//
// D3DTextureSurfaceWGL.h: WGL implementation of egl::Surface for D3D texture interop.
#ifndef LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
#define LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
#include "libANGLE/renderer/gl/SurfaceGL.h"
#include <GL/wglext.h>
namespace rx
{
class FunctionsGL;
class FunctionsWGL;
class DisplayWGL;
class StateManagerGL;
struct WorkaroundsGL;
class D3DTextureSurfaceWGL : public SurfaceGL
{
public:
D3DTextureSurfaceWGL(const egl::SurfaceState &state,
RendererGL *renderer,
EGLClientBuffer clientBuffer,
DisplayWGL *display,
HGLRC wglContext,
HDC deviceContext,
const FunctionsGL *functionsGL,
const FunctionsWGL *functionsWGL);
~D3DTextureSurfaceWGL() override;
static egl::Error ValidateD3DTextureClientBuffer(EGLClientBuffer clientBuffer);
egl::Error initialize() override;
egl::Error makeCurrent() override;
egl::Error unMakeCurrent() override;
egl::Error swap() override;
egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
egl::Error releaseTexImage(EGLint buffer) override;
void setSwapInterval(EGLint interval) override;
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
private:
EGLClientBuffer mClientBuffer;
RendererGL *mRenderer;
DisplayWGL *mDisplay;
StateManagerGL *mStateManager;
const WorkaroundsGL &mWorkarounds;
const FunctionsGL *mFunctionsGL;
const FunctionsWGL *mFunctionsWGL;
HGLRC mWGLContext;
HDC mDeviceContext;
size_t mWidth;
size_t mHeight;
HANDLE mDeviceHandle;
IUnknown *mObject;
HANDLE mBoundObjectTextureHandle;
HANDLE mBoundObjectRenderbufferHandle;
GLuint mRenderbufferID;
GLuint mFramebufferID;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
......@@ -14,6 +14,7 @@
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/renderergl_utils.h"
#include "libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h"
#include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h"
#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
#include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h"
......@@ -464,11 +465,13 @@ SurfaceImpl *DisplayWGL::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayWGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
return nullptr;
ASSERT(buftype == EGL_D3D_TEXTURE_ANGLE);
return new D3DTextureSurfaceWGL(state, getRenderer(), clientBuffer, this, mWGLContext,
mDeviceContext, mFunctionsGL, mFunctionsWGL);
}
SurfaceImpl *DisplayWGL::createPixmapSurface(const egl::SurfaceState &state,
......@@ -581,6 +584,21 @@ bool DisplayWGL::isValidNativeWindow(EGLNativeWindowType window) const
return (IsWindow(window) == TRUE);
}
egl::Error DisplayWGL::validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
switch (buftype)
{
case EGL_D3D_TEXTURE_ANGLE:
return D3DTextureSurfaceWGL::ValidateD3DTextureClientBuffer(clientBuffer);
default:
return DisplayGL::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
}
}
std::string DisplayWGL::getVendorString() const
{
//UNIMPLEMENTED();
......@@ -644,6 +662,8 @@ void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->surfaceOrientation = mUseDXGISwapChains;
outExtensions->createContextRobustness = mHasRobustness;
outExtensions->d3dTextureClientBuffer = mFunctionsWGL->hasExtension("WGL_NV_DX_interop2");
}
void DisplayWGL::generateCaps(egl::Caps *outCaps) const
......
......@@ -37,7 +37,8 @@ class DisplayWGL : public DisplayGL
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......@@ -50,6 +51,10 @@ class DisplayWGL : public DisplayGL
egl::Error restoreLostDevice() override;
bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
egl::Error getDevice(DeviceImpl **device) override;
......
......@@ -116,7 +116,8 @@ SurfaceImpl *DisplayNULL::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayNULL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
......
......@@ -54,7 +54,8 @@ class DisplayNULL : public DisplayImpl
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......
......@@ -111,7 +111,8 @@ SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayVk::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
UNIMPLEMENTED();
......
......@@ -54,7 +54,8 @@ class DisplayVk : public DisplayImpl
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration,
EGLClientBuffer shareHandle,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration,
......
......@@ -653,6 +653,17 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E
}
break;
case EGL_D3D_TEXTURE_ANGLE:
if (!displayExtensions.d3dTextureClientBuffer)
{
return Error(EGL_BAD_PARAMETER);
}
if (buffer == nullptr)
{
return Error(EGL_BAD_PARAMETER);
}
break;
default:
return Error(EGL_BAD_PARAMETER);
}
......@@ -753,6 +764,8 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E
}
}
ANGLE_TRY(display->validateClientBuffer(config, buftype, buffer, attributes));
return Error(EGL_SUCCESS);
}
......
......@@ -255,6 +255,7 @@
'libANGLE/renderer/d3d/ShaderExecutableD3D.h',
'libANGLE/renderer/d3d/SurfaceD3D.cpp',
'libANGLE/renderer/d3d/SurfaceD3D.h',
'libANGLE/renderer/d3d/SwapChainD3D.cpp',
'libANGLE/renderer/d3d/SwapChainD3D.h',
'libANGLE/renderer/d3d/TextureD3D.cpp',
'libANGLE/renderer/d3d/TextureD3D.h',
......@@ -511,6 +512,8 @@
],
'libangle_gl_wgl_sources':
[
'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp',
'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h',
'libANGLE/renderer/gl/wgl/DisplayWGL.cpp',
'libANGLE/renderer/gl/wgl/DisplayWGL.h',
'libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp',
......
......@@ -1068,7 +1068,8 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf
}
egl::Surface *surface = nullptr;
error = display->createPbufferFromClientBuffer(configuration, buffer, attributes, &surface);
error = display->createPbufferFromClientBuffer(configuration, buftype, buffer, attributes,
&surface);
if (error.isError())
{
SetGlobalError(error);
......
......@@ -96,6 +96,7 @@
'angle_end2end_tests_win_sources':
[
'<(angle_path)/src/tests/gl_tests/D3DImageFormatConversionTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3DTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3D11FormatTablesTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp',
......
......@@ -103,9 +103,10 @@ class MockEGLFactory : public EGLImplFactory
SurfaceImpl *(const egl::SurfaceState &,
const egl::Config *,
const egl::AttributeMap &));
MOCK_METHOD4(createPbufferFromClientBuffer,
MOCK_METHOD5(createPbufferFromClientBuffer,
SurfaceImpl *(const egl::SurfaceState &,
const egl::Config *,
EGLenum,
EGLClientBuffer,
const egl::AttributeMap &));
MOCK_METHOD4(createPixmapSurface,
......
......@@ -549,6 +549,14 @@ bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
}
bool ANGLETest::eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName)
{
PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT =
reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(
eglGetProcAddress("eglQueryDeviceStringEXT"));
return checkExtensionExists(eglQueryDeviceStringEXT(device, EGL_EXTENSIONS), extName);
}
void ANGLETest::setWindowWidth(int width)
{
mWidth = width;
......
......@@ -172,6 +172,7 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
static GLuint compileShader(GLenum type, const std::string &source);
static bool extensionEnabled(const std::string &extName);
static bool eglClientExtensionEnabled(const std::string &extName);
static bool eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName);
void setWindowWidth(int width);
void setWindowHeight(int height);
......
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