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: Zhenyao Mo <zmo@chromium.org>
This commit is contained in:
Patrick To
2020-01-02 19:07:38 -08:00
committed by Commit Bot
parent 36c938e098
commit a2ec926cfc
7 changed files with 236 additions and 3 deletions

View File

@@ -118,6 +118,7 @@ Microsoft Corporation
Rafael Cintron
James Clarke
Nathan Zabriskie
Patrick To
Microsoft Open Technologies, Inc.
Cooper Partin

View File

@@ -0,0 +1,88 @@
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

View File

@@ -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

View File

@@ -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,

View File

@@ -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())

View File

@@ -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",

View File

@@ -0,0 +1,84 @@
//
// 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()));