diff --git a/src/dawn_native/DawnNative.cpp b/src/dawn_native/DawnNative.cpp index b3efe843e7..f1dd1aa423 100644 --- a/src/dawn_native/DawnNative.cpp +++ b/src/dawn_native/DawnNative.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include "dawn_native/DawnNative.h" +#include "dawn_native/Device.h" // Contains the entry-points into dawn_native @@ -24,4 +25,9 @@ namespace dawn_native { return GetProcsAutogen(); } + const PCIInfo& GetPCIInfo(dawnDevice device) { + DeviceBase* deviceBase = reinterpret_cast(device); + return deviceBase->GetPCIInfo(); + } + } // namespace dawn_native diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h index 6d366a87ad..e6b069f03b 100644 --- a/src/dawn_native/Device.h +++ b/src/dawn_native/Device.h @@ -19,6 +19,7 @@ #include "dawn_native/Forward.h" #include "dawn_native/RefCounted.h" +#include "dawn_native/DawnNative.h" #include "dawn_native/dawn_platform.h" #include @@ -105,6 +106,8 @@ namespace dawn_native { return nullptr; } + virtual const PCIInfo& GetPCIInfo() const = 0; + private: virtual ResultOrError CreateBindGroupLayoutImpl( const BindGroupLayoutDescriptor* descriptor) = 0; diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp index fd23a2fd35..44a04b13a0 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/src/dawn_native/d3d12/DeviceD3D12.cpp @@ -40,6 +40,8 @@ #include "dawn_native/d3d12/SwapChainD3D12.h" #include "dawn_native/d3d12/TextureD3D12.h" +#include + namespace dawn_native { namespace d3d12 { dawnDevice CreateDevice() { @@ -133,6 +135,9 @@ namespace dawn_native { namespace d3d12 { ASSERT_SUCCESS(mFunctions->d3d12CreateDevice(mHardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&mD3d12Device))); + // Collect GPU information + CollectPCIInfo(); + // Create device-global objects D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; @@ -231,6 +236,10 @@ namespace dawn_native { namespace d3d12 { NextSerial(); } + const dawn_native::PCIInfo& Device::GetPCIInfo() const { + return mPCIInfo; + } + uint64_t Device::GetSerial() const { return mSerial; } @@ -329,4 +338,18 @@ namespace dawn_native { namespace d3d12 { return new TextureView(texture); } + void Device::CollectPCIInfo() { + memset(&mPCIInfo, 0, sizeof(mPCIInfo)); + + DXGI_ADAPTER_DESC1 adapterDesc; + mHardwareAdapter->GetDesc1(&adapterDesc); + + mPCIInfo.deviceId = adapterDesc.DeviceId; + mPCIInfo.vendorId = adapterDesc.VendorId; + + std::wstring_convert> converter( + "Error converting"); + mPCIInfo.name = converter.to_bytes(adapterDesc.Description); + } + }} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h index 7ec5d53027..aaceed9a30 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.h +++ b/src/dawn_native/d3d12/DeviceD3D12.h @@ -55,6 +55,8 @@ namespace dawn_native { namespace d3d12 { void TickImpl() override; + const dawn_native::PCIInfo& GetPCIInfo() const override; + ComPtr GetFactory(); ComPtr GetD3D12Device(); ComPtr GetCommandQueue(); @@ -89,6 +91,7 @@ namespace dawn_native { namespace d3d12 { ResultOrError CreateShaderModuleImpl( const ShaderModuleDescriptor* descriptor) override; ResultOrError CreateTextureImpl(const TextureDescriptor* descriptor) override; + void CollectPCIInfo(); // Keep mFunctions as the first member so that in the destructor it is freed. Otherwise the // D3D12 DLLs are unloaded before we are done using it. @@ -115,6 +118,8 @@ namespace dawn_native { namespace d3d12 { std::unique_ptr mMapRequestTracker; std::unique_ptr mResourceAllocator; std::unique_ptr mResourceUploader; + + dawn_native::PCIInfo mPCIInfo; }; }} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/metal/DeviceMTL.h b/src/dawn_native/metal/DeviceMTL.h index ccb962780c..cbd3701178 100644 --- a/src/dawn_native/metal/DeviceMTL.h +++ b/src/dawn_native/metal/DeviceMTL.h @@ -51,6 +51,8 @@ namespace dawn_native { namespace metal { void TickImpl() override; + const dawn_native::PCIInfo& GetPCIInfo() const override; + id GetMTLDevice(); id GetPendingCommandBuffer(); @@ -73,6 +75,7 @@ namespace dawn_native { namespace metal { ResultOrError CreateShaderModuleImpl( const ShaderModuleDescriptor* descriptor) override; ResultOrError CreateTextureImpl(const TextureDescriptor* descriptor) override; + void CollectPCIInfo(); void OnCompletedHandler(); @@ -84,6 +87,8 @@ namespace dawn_native { namespace metal { Serial mFinishedCommandSerial = 0; Serial mPendingCommandSerial = 1; id mPendingCommands = nil; + + dawn_native::PCIInfo mPCIInfo; }; }} // namespace dawn_native::metal diff --git a/src/dawn_native/metal/DeviceMTL.mm b/src/dawn_native/metal/DeviceMTL.mm index 9f95384e08..0b28b94c6f 100644 --- a/src/dawn_native/metal/DeviceMTL.mm +++ b/src/dawn_native/metal/DeviceMTL.mm @@ -49,6 +49,7 @@ namespace dawn_native { namespace metal { mResourceUploader(new ResourceUploader(this)) { [mMtlDevice retain]; mCommandQueue = [mMtlDevice newCommandQueue]; + CollectPCIInfo(); } Device::~Device() { @@ -144,6 +145,10 @@ namespace dawn_native { namespace metal { SubmitPendingCommandBuffer(); } + const dawn_native::PCIInfo& Device::GetPCIInfo() const { + return mPCIInfo; + } + id Device::GetMTLDevice() { return mMtlDevice; } @@ -193,4 +198,8 @@ namespace dawn_native { namespace metal { return mResourceUploader.get(); } + // TODO(jiawei.shao@intel.com): collect device information on Metal + void Device::CollectPCIInfo() { + } + }} // namespace dawn_native::metal diff --git a/src/dawn_native/null/NullBackend.cpp b/src/dawn_native/null/NullBackend.cpp index 824ff7a02e..dad614513c 100644 --- a/src/dawn_native/null/NullBackend.cpp +++ b/src/dawn_native/null/NullBackend.cpp @@ -28,6 +28,7 @@ namespace dawn_native { namespace null { // Device Device::Device() { + InitFakePCIInfo(); } Device::~Device() { @@ -98,6 +99,14 @@ namespace dawn_native { namespace null { return new TextureView(texture); } + void Device::InitFakePCIInfo() { + mPCIInfo.name = "Null backend"; + } + + const dawn_native::PCIInfo& Device::GetPCIInfo() const { + return mPCIInfo; + } + void Device::TickImpl() { } diff --git a/src/dawn_native/null/NullBackend.h b/src/dawn_native/null/NullBackend.h index e3aded0a01..3f6b6a34f9 100644 --- a/src/dawn_native/null/NullBackend.h +++ b/src/dawn_native/null/NullBackend.h @@ -109,6 +109,8 @@ namespace dawn_native { namespace null { void TickImpl() override; + const dawn_native::PCIInfo& GetPCIInfo() const override; + void AddPendingOperation(std::unique_ptr operation); std::vector> AcquirePendingOperations(); @@ -125,8 +127,10 @@ namespace dawn_native { namespace null { ResultOrError CreateShaderModuleImpl( const ShaderModuleDescriptor* descriptor) override; ResultOrError CreateTextureImpl(const TextureDescriptor* descriptor) override; + void InitFakePCIInfo(); std::vector> mPendingOperations; + dawn_native::PCIInfo mPCIInfo; }; class Buffer : public BufferBase { diff --git a/src/dawn_native/opengl/DeviceGL.cpp b/src/dawn_native/opengl/DeviceGL.cpp index e2d60f500e..7429e2f59b 100644 --- a/src/dawn_native/opengl/DeviceGL.cpp +++ b/src/dawn_native/opengl/DeviceGL.cpp @@ -46,6 +46,10 @@ namespace dawn_native { namespace opengl { // Device + Device::Device() { + CollectPCIInfo(); + } + BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) { return new BindGroup(builder); } @@ -109,4 +113,12 @@ namespace dawn_native { namespace opengl { void Device::TickImpl() { } + const dawn_native::PCIInfo& Device::GetPCIInfo() const { + return mPCIInfo; + } + + void Device::CollectPCIInfo() { + mPCIInfo.name = reinterpret_cast(glGetString(GL_RENDERER)); + } + }} // namespace dawn_native::opengl diff --git a/src/dawn_native/opengl/DeviceGL.h b/src/dawn_native/opengl/DeviceGL.h index 05f21d3512..c1d4816af7 100644 --- a/src/dawn_native/opengl/DeviceGL.h +++ b/src/dawn_native/opengl/DeviceGL.h @@ -32,6 +32,7 @@ namespace dawn_native { namespace opengl { class Device : public DeviceBase { public: + Device(); BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override; BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override; BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override; @@ -46,6 +47,8 @@ namespace dawn_native { namespace opengl { void TickImpl() override; + const dawn_native::PCIInfo& GetPCIInfo() const override; + private: ResultOrError CreateBindGroupLayoutImpl( const BindGroupLayoutDescriptor* descriptor) override; @@ -59,6 +62,9 @@ namespace dawn_native { namespace opengl { ResultOrError CreateShaderModuleImpl( const ShaderModuleDescriptor* descriptor) override; ResultOrError CreateTextureImpl(const TextureDescriptor* descriptor) override; + void CollectPCIInfo(); + + dawn_native::PCIInfo mPCIInfo; }; }} // namespace dawn_native::opengl diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index 6e4d601ea1..0a7763b3a8 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -151,6 +151,10 @@ namespace dawn_native { namespace vulkan { mMapRequestTracker = std::make_unique(this); mMemoryAllocator = std::make_unique(this); mRenderPassCache = std::make_unique(this); + + mPCIInfo.deviceId = mDeviceInfo.properties.deviceID; + mPCIInfo.vendorId = mDeviceInfo.properties.vendorID; + mPCIInfo.name = mDeviceInfo.properties.deviceName; } Device::~Device() { @@ -290,6 +294,10 @@ namespace dawn_native { namespace vulkan { } } + const dawn_native::PCIInfo& Device::GetPCIInfo() const { + return mPCIInfo; + } + const VulkanDeviceInfo& Device::GetDeviceInfo() const { return mDeviceInfo; } diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h index 803101f711..b8f3f1591b 100644 --- a/src/dawn_native/vulkan/DeviceVk.h +++ b/src/dawn_native/vulkan/DeviceVk.h @@ -78,6 +78,8 @@ namespace dawn_native { namespace vulkan { void TickImpl() override; + const dawn_native::PCIInfo& GetPCIInfo() const override; + private: ResultOrError CreateBindGroupLayoutImpl( const BindGroupLayoutDescriptor* descriptor) override; @@ -155,6 +157,8 @@ namespace dawn_native { namespace vulkan { std::vector mUnusedCommands; CommandPoolAndBuffer mPendingCommands; std::vector mWaitSemaphores; + + dawn_native::PCIInfo mPCIInfo; }; }} // namespace dawn_native::vulkan diff --git a/src/include/dawn_native/DawnNative.h b/src/include/dawn_native/DawnNative.h index 6a9fef9088..f90dc9eaa6 100644 --- a/src/include/dawn_native/DawnNative.h +++ b/src/include/dawn_native/DawnNative.h @@ -18,11 +18,20 @@ #include #include +#include + namespace dawn_native { + struct PCIInfo { + uint32_t deviceId = 0; + uint32_t vendorId = 0; + std::string name; + }; // Backend-agnostic API for dawn_native DAWN_NATIVE_EXPORT dawnProcTable GetProcs(); + DAWN_NATIVE_EXPORT const PCIInfo& GetPCIInfo(dawnDevice device); + } // namespace dawn_native #endif // DAWNNATIVE_DAWNNATIVE_H_ diff --git a/src/tests/DawnTest.cpp b/src/tests/DawnTest.cpp index 68611af262..a770b42cc1 100644 --- a/src/tests/DawnTest.cpp +++ b/src/tests/DawnTest.cpp @@ -17,6 +17,7 @@ #include "common/Assert.h" #include "common/Constants.h" #include "common/Math.h" +#include "common/Platform.h" #include "dawn_native/DawnNative.h" #include "dawn_wire/Wire.h" #include "utils/BackendBinding.h" @@ -125,6 +126,54 @@ bool DawnTest::IsVulkan() const { return GetParam() == VulkanBackend; } +bool DawnTest::IsAMD() const { + return mPCIInfo.vendorId == kVendorID_AMD; +} + +bool DawnTest::IsARM() const { + return mPCIInfo.vendorId == kVendorID_ARM; +} + +bool DawnTest::IsImgTec() const { + return mPCIInfo.vendorId == kVendorID_ImgTec; +} + +bool DawnTest::IsIntel() const { + return mPCIInfo.vendorId == kVendorID_Intel; +} + +bool DawnTest::IsNvidia() const { + return mPCIInfo.vendorId == kVendorID_Nvidia; +} + +bool DawnTest::IsQualcomm() const { + return mPCIInfo.vendorId == kVendorID_Qualcomm; +} + +bool DawnTest::IsWindows() const { +#ifdef DAWN_PLATFORM_WINDOWS + return true; +#else + return false; +#endif +} + +bool DawnTest::IsLinux() const { +#ifdef DAWN_PLATFORM_LINUX + return true; +#else + return false; +#endif +} + +bool DawnTest::IsMacOS() const { +#ifdef DAWN_PLATFORM_APPLE + return true; +#else + return false; +#endif +} + bool gTestUsesWire = false; void DawnTest::SetUp() { @@ -180,6 +229,8 @@ void DawnTest::SetUp() { // The end2end tests should never cause validation errors. These should be tested in unittests. device.SetErrorCallback(DeviceErrorCauseTestFailure, 0); + + mPCIInfo = dawn_native::GetPCIInfo(backendDevice); } void DawnTest::TearDown() { diff --git a/src/tests/DawnTest.h b/src/tests/DawnTest.h index caf2978c84..a9f676f7db 100644 --- a/src/tests/DawnTest.h +++ b/src/tests/DawnTest.h @@ -13,6 +13,7 @@ // limitations under the License. #include "dawn/dawncpp.h" +#include "dawn_native/DawnNative.h" #include #include @@ -64,6 +65,13 @@ enum BackendType { }; std::ostream& operator<<(std::ostream& stream, BackendType backend); +constexpr uint32_t kVendorID_AMD = 0x1002; +constexpr uint32_t kVendorID_ARM = 0x13B5; +constexpr uint32_t kVendorID_ImgTec = 0x1010; +constexpr uint32_t kVendorID_Intel = 0x8086; +constexpr uint32_t kVendorID_Nvidia = 0x10DE; +constexpr uint32_t kVendorID_Qualcomm = 0x5143; + namespace utils { class BackendBinding; class TerribleCommandBuffer; @@ -90,6 +98,17 @@ class DawnTest : public ::testing::TestWithParam { bool IsOpenGL() const; bool IsVulkan() const; + bool IsAMD() const; + bool IsARM() const; + bool IsImgTec() const; + bool IsIntel() const; + bool IsNvidia() const; + bool IsQualcomm() const; + + bool IsWindows() const; + bool IsLinux() const; + bool IsMacOS() const; + protected: dawn::Device device; dawn::Queue queue; @@ -167,6 +186,8 @@ class DawnTest : public ::testing::TestWithParam { void ResolveExpectations(); std::unique_ptr mBinding; + + dawn_native::PCIInfo mPCIInfo; }; // Instantiate the test once for each backend provided after the first argument. Use it like this: diff --git a/src/tests/end2end/BlendStateTests.cpp b/src/tests/end2end/BlendStateTests.cpp index 7d30c2a4c1..a9231fa25c 100644 --- a/src/tests/end2end/BlendStateTests.cpp +++ b/src/tests/end2end/BlendStateTests.cpp @@ -686,6 +686,7 @@ TEST_P(BlendStateTest, ColorWriteMaskBlendingDisabled) { // Test that independent blend states on render targets works TEST_P(BlendStateTest, IndependentBlendState) { + DAWN_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsIntel()); std::array renderTargets; std::array renderTargetViews; diff --git a/src/tests/end2end/ScissorTests.cpp b/src/tests/end2end/ScissorTests.cpp index 19a1590187..3a4fc32cac 100644 --- a/src/tests/end2end/ScissorTests.cpp +++ b/src/tests/end2end/ScissorTests.cpp @@ -90,6 +90,7 @@ TEST_P(ScissorTest, LargerThanAttachment) { // Test setting an empty scissor rect TEST_P(ScissorTest, EmptyRect) { DAWN_SKIP_TEST_IF(IsMetal()); + DAWN_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsIntel()); utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 2, 2); dawn::RenderPipeline pipeline = CreateQuadPipeline(renderPass.colorFormat);