Commit 45095581 by Austin Kinross Committed by Jamie Madill

Enable resource sharing for D3D11 devices created with WARP

ANGLE currently blocks resources sharing if ANGLE was initialized using EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE. This is to prevent applications from trying to share resources between hardware D3D devices and WARP. However, this prevents developers from deliberately initializing ANGLE to run on WARP, and then sharing resources with an external WARP device. ANGLE should support that scenario. BUG=angleproject:1283 Change-Id: I86681355bf34f7fe3367261dd76c434a9fa60739 Reviewed-on: https://chromium-review.googlesource.com/317318Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tryjob-Request: Austin Kinross <aukinros@microsoft.com> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 88829e84
......@@ -10,6 +10,7 @@
#include <EGL/eglext.h>
#include <sstream>
#include <VersionHelpers.h>
#include "common/tls.h"
#include "common/utilities.h"
......@@ -559,19 +560,19 @@ Renderer11::Renderer11(egl::Display *display)
switch (requestedDeviceType)
{
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
mDriverType = D3D_DRIVER_TYPE_HARDWARE;
mRequestedDriverType = D3D_DRIVER_TYPE_HARDWARE;
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
mDriverType = D3D_DRIVER_TYPE_WARP;
mRequestedDriverType = D3D_DRIVER_TYPE_WARP;
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
mDriverType = D3D_DRIVER_TYPE_REFERENCE;
mRequestedDriverType = D3D_DRIVER_TYPE_REFERENCE;
break;
case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
mDriverType = D3D_DRIVER_TYPE_NULL;
mRequestedDriverType = D3D_DRIVER_TYPE_NULL;
break;
default:
......@@ -583,6 +584,10 @@ Renderer11::Renderer11(egl::Display *display)
mEGLDevice = GetImplAs<DeviceD3D>(display->getDevice());
ASSERT(mEGLDevice != nullptr);
mCreatedWithDeviceEXT = true;
// Also set EGL_PLATFORM_ANGLE_ANGLE variables, in case they're used elsewhere in ANGLE
// mAvailableFeatureLevels defaults to empty
mRequestedDriverType = D3D_DRIVER_TYPE_UNKNOWN;
}
initializeDebugAnnotator();
......@@ -790,10 +795,11 @@ egl::Error Renderer11::initializeD3DDevice()
#ifdef _DEBUG
{
TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)");
result = D3D11CreateDevice(
NULL, mDriverType, NULL, D3D11_CREATE_DEVICE_DEBUG, mAvailableFeatureLevels.data(),
static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION,
&mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
result = D3D11CreateDevice(nullptr, mRequestedDriverType, nullptr,
D3D11_CREATE_DEVICE_DEBUG, mAvailableFeatureLevels.data(),
static_cast<unsigned int>(mAvailableFeatureLevels.size()),
D3D11_SDK_VERSION, &mDevice,
&(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
}
if (!mDevice || FAILED(result))
......@@ -807,10 +813,10 @@ egl::Error Renderer11::initializeD3DDevice()
SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.D3D11CreateDeviceMS");
TRACE_EVENT0("gpu.angle", "D3D11CreateDevice");
result = D3D11CreateDevice(NULL, mDriverType, NULL, 0, mAvailableFeatureLevels.data(),
static_cast<unsigned int>(mAvailableFeatureLevels.size()),
D3D11_SDK_VERSION, &mDevice,
&(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
result = D3D11CreateDevice(
nullptr, mRequestedDriverType, nullptr, 0, mAvailableFeatureLevels.data(),
static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION,
&mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
// Cleanup done by destructor
if (!mDevice || FAILED(result))
......@@ -2548,8 +2554,9 @@ bool Renderer11::testDeviceResettable()
D3D_FEATURE_LEVEL dummyFeatureLevel;
ID3D11DeviceContext* dummyContext;
ASSERT(mRequestedDriverType != D3D_DRIVER_TYPE_UNKNOWN);
HRESULT result = D3D11CreateDevice(
NULL, mDriverType, NULL,
NULL, mRequestedDriverType, NULL,
#if defined(_DEBUG)
D3D11_CREATE_DEVICE_DEBUG,
#else
......@@ -2616,6 +2623,8 @@ void Renderer11::release()
}
mCompiler.release();
mSupportsShareHandles.reset();
}
bool Renderer11::resetDevice()
......@@ -2685,33 +2694,94 @@ unsigned int Renderer11::getReservedFragmentUniformBuffers() const
return 2;
}
d3d11::ANGLED3D11DeviceType Renderer11::getDeviceType() const
{
if (mCreatedWithDeviceEXT)
{
return d3d11::GetDeviceType(mDevice);
}
if ((mRequestedDriverType == D3D_DRIVER_TYPE_SOFTWARE) ||
(mRequestedDriverType == D3D_DRIVER_TYPE_REFERENCE) ||
(mRequestedDriverType == D3D_DRIVER_TYPE_NULL))
{
return d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
}
if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
{
return d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP;
}
return d3d11::ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
}
bool Renderer11::getShareHandleSupport() const
{
if (mSupportsShareHandles.valid())
{
return mSupportsShareHandles.value();
}
// We only currently support share handles with BGRA surfaces, because
// chrome needs BGRA. Once chrome fixes this, we should always support them.
if (!getRendererExtensions().textureFormatBGRA8888)
{
mSupportsShareHandles = false;
return false;
}
// PIX doesn't seem to support using share handles, so disable them.
if (gl::DebugAnnotationsActive())
{
mSupportsShareHandles = false;
return false;
}
// Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains.
if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
mSupportsShareHandles = false;
return false;
}
// Also disable on non-hardware drivers, since sharing doesn't work cross-driver.
if (mDriverType != D3D_DRIVER_TYPE_HARDWARE)
// Find out which type of D3D11 device the Renderer11 is using
d3d11::ANGLED3D11DeviceType deviceType = getDeviceType();
if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_UNKNOWN)
{
mSupportsShareHandles = false;
return false;
}
if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL)
{
// Software/Reference/NULL devices don't support share handles
mSupportsShareHandles = false;
return false;
}
if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP)
{
#ifndef ANGLE_ENABLE_WINDOWS_STORE
if (!IsWindows8OrGreater())
{
// WARP on Windows 7 doesn't support shared handles
mSupportsShareHandles = false;
return false;
}
#endif // ANGLE_ENABLE_WINDOWS_STORE
// WARP on Windows 8.0+ supports shared handles when shared with another WARP device
// TODO: allow applications to query for HARDWARE or WARP-specific share handles,
// to prevent them trying to use a WARP share handle with an a HW device (or
// vice-versa)
// e.g. by creating EGL_D3D11_[HARDWARE/WARP]_DEVICE_SHARE_HANDLE_ANGLE
mSupportsShareHandles = true;
return true;
}
ASSERT(mCreatedWithDeviceEXT || mRequestedDriverType == D3D_DRIVER_TYPE_HARDWARE);
mSupportsShareHandles = true;
return true;
}
......
......@@ -18,6 +18,7 @@
#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"
#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
......@@ -329,7 +330,7 @@ class Renderer11 : public RendererD3D
HMODULE mDxgiModule;
HMODULE mDCompModule;
std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
D3D_DRIVER_TYPE mDriverType;
D3D_DRIVER_TYPE mRequestedDriverType;
bool mCreatedWithDeviceEXT;
DeviceD3D *mEGLDevice;
......@@ -340,6 +341,8 @@ class Renderer11 : public RendererD3D
void releaseDeviceResources();
void release();
d3d11::ANGLED3D11DeviceType getDeviceType() const;
RenderStateCache mStateCache;
// current render target states
......@@ -477,6 +480,8 @@ class Renderer11 : public RendererD3D
ID3D11Debug *mDebug;
std::vector<GLuint> mScratchIndexDataBuffer;
mutable Optional<bool> mSupportsShareHandles;
};
}
......
......@@ -1252,6 +1252,72 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
namespace d3d11
{
ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device)
{
// Note that this function returns an ANGLED3D11DeviceType rather than a D3D_DRIVER_TYPE value,
// since it is difficult to tell Software and Reference devices apart
IDXGIDevice *dxgiDevice = nullptr;
IDXGIAdapter *dxgiAdapter = nullptr;
IDXGIAdapter2 *dxgiAdapter2 = nullptr;
ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN;
HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
if (SUCCEEDED(hr))
{
hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter);
if (SUCCEEDED(hr))
{
std::wstring adapterString;
HRESULT adapter2hr =
dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2);
if (SUCCEEDED(adapter2hr))
{
// On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter"
// for the description string. Try to use IDXGIAdapter2::GetDesc2 to get the
// actual hardware values if possible.
DXGI_ADAPTER_DESC2 adapterDesc2;
dxgiAdapter2->GetDesc2(&adapterDesc2);
adapterString = std::wstring(adapterDesc2.Description);
}
else
{
DXGI_ADAPTER_DESC adapterDesc;
dxgiAdapter->GetDesc(&adapterDesc);
adapterString = std::wstring(adapterDesc.Description);
}
// Both Reference and Software adapters will be 'Software Adapter'
const bool isSoftwareDevice =
(adapterString.find(std::wstring(L"Software Adapter")) != std::string::npos);
const bool isNullDevice = (adapterString == L"");
const bool isWARPDevice =
(adapterString.find(std::wstring(L"Basic Render")) != std::string::npos);
if (isSoftwareDevice || isNullDevice)
{
ASSERT(!isWARPDevice);
retDeviceType = ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
}
else if (isWARPDevice)
{
retDeviceType = ANGLE_D3D11_DEVICE_TYPE_WARP;
}
else
{
retDeviceType = ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
}
}
}
SafeRelease(dxgiDevice);
SafeRelease(dxgiAdapter);
SafeRelease(dxgiAdapter2);
return retDeviceType;
}
void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
{
const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
......
......@@ -65,6 +65,16 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
namespace d3d11
{
enum ANGLED3D11DeviceType
{
ANGLE_D3D11_DEVICE_TYPE_UNKNOWN,
ANGLE_D3D11_DEVICE_TYPE_HARDWARE,
ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL,
ANGLE_D3D11_DEVICE_TYPE_WARP,
};
ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device);
void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
void GenerateInitialTextureData(GLint internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, GLuint width, GLuint height, GLuint depth,
......
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