Commit a2ec926c by Patrick To Committed by Commit Bot

Specify LUID in D3D11

Add an extension to provide the ability to specify the LUID of the GPU adapter to use when using D3D11. Corresponding chromium CL: https://chromium-review.googlesource.com/c/chromium/src/+/2096778 Bug: chromium:792657 Change-Id: Iefebea221a4b7a20f150b445ae1adf375444726d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2096663 Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 36c938e0
......@@ -118,6 +118,7 @@ Microsoft Corporation
Rafael Cintron
James Clarke
Nathan Zabriskie
Patrick To
Microsoft Open Technologies, Inc.
Cooper Partin
......
Name
ANGLE_platform_angle_d3d_luid
Name Strings
EGL_ANGLE_platform_angle_d3d_luid
Contributors
Patrick To, Microsoft
Contacts
Patrick To, Microsoft (patrto 'at' microsoft.com)
Status
Draft
Version
Version 1, 2020-04-30
Number
EGL Extension XXX
Extension Type
EGL client extension
Dependencies
Requires ANGLE_platform_angle_d3d.
Overview
This extension enables the selection of a graphics adapter to back D3D.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as an attribute name in the <attrib_list> argument of
eglGetPlatformDisplayEXT:
EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE 0x34A0
EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE 0x34A1
Additions to the EGL Specification
None
New Behavior
To request a display that is backed by a specific graphics adapter,
EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and/or
EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE should be set to the high part and low
part of the adapter's LUID. If only one attribute is specified, the other is
assumed to be zero.
If the high part and low part combined is zero, an EGL_BAD_ATTRIBUTE error
is generated and EGL_NO_DISPLAY is returned.
If the LUID specified doesn't match any adapters on the system, the default
adapter is used.
If EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and/or
EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE is included in the <attrib_list>
argument of eglGetPlatformDisplayEXT and EGL_PLATFORM_ANGLE_TYPE_ANGLE is
not set to EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, an EGL_BAD_ATTRIBUTE error
is generated and EGL_NO_DISPLAY is returned.
Issues
None
Revision History
Version 1, 2020-04-30 (Patrick To)
- Initial draft
......@@ -65,6 +65,12 @@
#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
#endif /* EGL_ANGLE_platform_angle_d3d */
#ifndef EGL_ANGLE_platform_angle_d3d_luid
#define EGL_ANGLE_platform_angle_d3d_luid 1
#define EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE 0x34A0
#define EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE 0x34A1
#endif /* EGL_ANGLE_platform_angle_d3d_luid */
#ifndef EGL_ANGLE_platform_angle_d3d11on12
#define EGL_ANGLE_platform_angle_d3d11on12 1
#define EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488
......
......@@ -690,10 +690,39 @@ egl::Error Renderer11::initialize()
HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug)
{
angle::ComPtr<IDXGIAdapter> adapter;
const egl::AttributeMap &attributes = mDisplay->getAttributeMap();
long high = static_cast<long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0));
unsigned long low =
static_cast<unsigned long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0));
if (high != 0 || low != 0)
{
angle::ComPtr<IDXGIFactory1> factory;
if (SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
{
angle::ComPtr<IDXGIAdapter> temp;
for (UINT i = 0; SUCCEEDED(factory->EnumAdapters(i, &temp)); i++)
{
DXGI_ADAPTER_DESC desc;
if (SUCCEEDED(temp->GetDesc(&desc)) && desc.AdapterLuid.HighPart == high &&
desc.AdapterLuid.LowPart == low)
{
adapter = temp;
break;
}
}
}
}
// If adapter is not nullptr, the driver type must be D3D_DRIVER_TYPE_UNKNOWN or
// D3D11CreateDevice will return E_INVALIDARG.
return createDevice(
nullptr, mRequestedDriverType, nullptr, debug ? D3D11_CREATE_DEVICE_DEBUG : 0,
mAvailableFeatureLevels.data(), static_cast<unsigned int>(mAvailableFeatureLevels.size()),
D3D11_SDK_VERSION, &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
adapter.Get(), adapter ? D3D_DRIVER_TYPE_UNKNOWN : mRequestedDriverType, nullptr,
debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(),
static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &mDevice,
&(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
}
HRESULT Renderer11::callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12,
......
......@@ -467,6 +467,7 @@ Error ValidateGetPlatformDisplayCommon(EGLenum platform,
bool enableAutoTrimSpecified = false;
bool enableD3D11on12 = false;
bool presentPathSpecified = false;
bool luidSpecified = false;
Optional<EGLAttrib> majorVersion;
Optional<EGLAttrib> minorVersion;
......@@ -631,6 +632,10 @@ Error ValidateGetPlatformDisplayCommon(EGLenum platform,
}
break;
case EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE:
case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE:
luidSpecified = true;
break;
default:
break;
}
......@@ -680,6 +685,25 @@ Error ValidateGetPlatformDisplayCommon(EGLenum platform,
"device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.";
}
if (luidSpecified)
{
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
return EglBadAttribute() << "EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and "
"EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE "
"require a platform type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.";
}
if (attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0) == 0 &&
attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0) == 0)
{
return EglBadAttribute() << "If either EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE "
"and/or EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE are "
"specified, at least one must non-zero.";
}
}
if (deviceType.valid())
{
switch (deviceType.value())
......
......@@ -172,6 +172,7 @@ angle_end2end_tests_mac_sources = [
]
angle_end2end_tests_win_sources = [
"egl_tests/EGLDeviceTest.cpp",
"egl_tests/EGLDisplayLuidTest.cpp",
"egl_tests/EGLPresentPathD3D11Test.cpp",
"egl_tests/EGLStreamTest.cpp",
"egl_tests/EGLSyncControlTest.cpp",
......
//
// Copyright 2020 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.
//
// EGLDisplayLuidTest.cpp:
// Tests for the EGL_ANGLE_platform_angle_d3d_luid extension.
//
#include "test_utils/ANGLETest.h"
using namespace angle;
class EGLDisplayLuidTest : public ANGLETest
{
protected:
EGLDisplayLuidTest() : mDisplay(EGL_NO_DISPLAY) {}
void testTearDown() override
{
if (mDisplay != EGL_NO_DISPLAY)
{
EXPECT_EGL_TRUE(eglTerminate(mDisplay));
EXPECT_EGL_SUCCESS();
}
}
void testInvalidAttribs(const EGLint displayAttribs[])
{
EXPECT_EQ(
eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttribs),
EGL_NO_DISPLAY);
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
}
void testValidAttribs(const EGLint displayAttribs[])
{
mDisplay =
eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttribs);
EXPECT_EGL_SUCCESS();
EXPECT_NE(mDisplay, EGL_NO_DISPLAY);
// eglInitialize should succeed even if the LUID doesn't match an actual
// adapter on the system. The behavior in this case is that the default
// adapter is used.
EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
EXPECT_EGL_SUCCESS();
}
private:
EGLDisplay mDisplay;
};
// EGL_ANGLE_platform_angle_d3d_luid is only supported on D3D11. Verify failure
// if D3D9 is specified in the attributes.
TEST_P(EGLDisplayLuidTest, D3D9Failure)
{
EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 1, EGL_NONE};
testInvalidAttribs(displayAttribs);
}
// Verify failure if the specified LUID is zero.
TEST_P(EGLDisplayLuidTest, ZeroLuidFailure)
{
EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE,
0,
EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE,
0,
EGL_NONE};
testInvalidAttribs(displayAttribs);
}
TEST_P(EGLDisplayLuidTest, D3D11)
{
EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 1, EGL_NONE};
testValidAttribs(displayAttribs);
}
ANGLE_INSTANTIATE_TEST(EGLDisplayLuidTest, WithNoFixture(ES2_D3D9()), WithNoFixture(ES2_D3D11()));
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