Collect GPU device information for end2end tests - Part I
This patch is the first one to support inspecting GPU information for
dawn_end2end_tests.
In this patch, we support collecting the device name, device id and
vendor id on D3D12 and Vulkan. We also support collecting the device
name on OpenGL. The collection on Metal will be supported in the next
patch. Using this information we implement a series of APIs to inspect
the information of both OS and GPU vendor.
We also skip two failed tests on Windows Intel Vulkan backends.
BUG=dawn:10
Change-Id: If52a960c0bae3922a0b5650500218eff1400d77a
Reviewed-on: https://dawn-review.googlesource.com/1460
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/DawnNative.cpp b/src/dawn_native/DawnNative.cpp
index b3efe84..f1dd1aa 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 @@
return GetProcsAutogen();
}
+ const PCIInfo& GetPCIInfo(dawnDevice device) {
+ DeviceBase* deviceBase = reinterpret_cast<DeviceBase*>(device);
+ return deviceBase->GetPCIInfo();
+ }
+
} // namespace dawn_native
diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h
index 6d366a8..e6b069f 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 <memory>
@@ -105,6 +106,8 @@
return nullptr;
}
+ virtual const PCIInfo& GetPCIInfo() const = 0;
+
private:
virtual ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) = 0;
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index fd23a2f..44a04b1 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 <locale>
+
namespace dawn_native { namespace d3d12 {
dawnDevice CreateDevice() {
@@ -133,6 +135,9 @@
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 @@
NextSerial();
}
+ const dawn_native::PCIInfo& Device::GetPCIInfo() const {
+ return mPCIInfo;
+ }
+
uint64_t Device::GetSerial() const {
return mSerial;
}
@@ -329,4 +338,18 @@
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<std::codecvt<wchar_t, char, std::mbstate_t>> 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 7ec5d53..aaceed9 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -55,6 +55,8 @@
void TickImpl() override;
+ const dawn_native::PCIInfo& GetPCIInfo() const override;
+
ComPtr<IDXGIFactory4> GetFactory();
ComPtr<ID3D12Device> GetD3D12Device();
ComPtr<ID3D12CommandQueue> GetCommandQueue();
@@ -89,6 +91,7 @@
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
ResultOrError<TextureBase*> 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 @@
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
std::unique_ptr<ResourceAllocator> mResourceAllocator;
std::unique_ptr<ResourceUploader> 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 ccb9627..cbd3701 100644
--- a/src/dawn_native/metal/DeviceMTL.h
+++ b/src/dawn_native/metal/DeviceMTL.h
@@ -51,6 +51,8 @@
void TickImpl() override;
+ const dawn_native::PCIInfo& GetPCIInfo() const override;
+
id<MTLDevice> GetMTLDevice();
id<MTLCommandBuffer> GetPendingCommandBuffer();
@@ -73,6 +75,7 @@
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override;
+ void CollectPCIInfo();
void OnCompletedHandler();
@@ -84,6 +87,8 @@
Serial mFinishedCommandSerial = 0;
Serial mPendingCommandSerial = 1;
id<MTLCommandBuffer> 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 9f95384..0b28b94 100644
--- a/src/dawn_native/metal/DeviceMTL.mm
+++ b/src/dawn_native/metal/DeviceMTL.mm
@@ -49,6 +49,7 @@
mResourceUploader(new ResourceUploader(this)) {
[mMtlDevice retain];
mCommandQueue = [mMtlDevice newCommandQueue];
+ CollectPCIInfo();
}
Device::~Device() {
@@ -144,6 +145,10 @@
SubmitPendingCommandBuffer();
}
+ const dawn_native::PCIInfo& Device::GetPCIInfo() const {
+ return mPCIInfo;
+ }
+
id<MTLDevice> Device::GetMTLDevice() {
return mMtlDevice;
}
@@ -193,4 +198,8 @@
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 824ff7a..dad6145 100644
--- a/src/dawn_native/null/NullBackend.cpp
+++ b/src/dawn_native/null/NullBackend.cpp
@@ -28,6 +28,7 @@
// Device
Device::Device() {
+ InitFakePCIInfo();
}
Device::~Device() {
@@ -98,6 +99,14 @@
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 e3aded0..3f6b6a3 100644
--- a/src/dawn_native/null/NullBackend.h
+++ b/src/dawn_native/null/NullBackend.h
@@ -109,6 +109,8 @@
void TickImpl() override;
+ const dawn_native::PCIInfo& GetPCIInfo() const override;
+
void AddPendingOperation(std::unique_ptr<PendingOperation> operation);
std::vector<std::unique_ptr<PendingOperation>> AcquirePendingOperations();
@@ -125,8 +127,10 @@
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override;
+ void InitFakePCIInfo();
std::vector<std::unique_ptr<PendingOperation>> 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 e2d60f5..7429e2f 100644
--- a/src/dawn_native/opengl/DeviceGL.cpp
+++ b/src/dawn_native/opengl/DeviceGL.cpp
@@ -46,6 +46,10 @@
// Device
+ Device::Device() {
+ CollectPCIInfo();
+ }
+
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
return new BindGroup(builder);
}
@@ -109,4 +113,12 @@
void Device::TickImpl() {
}
+ const dawn_native::PCIInfo& Device::GetPCIInfo() const {
+ return mPCIInfo;
+ }
+
+ void Device::CollectPCIInfo() {
+ mPCIInfo.name = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
+ }
+
}} // namespace dawn_native::opengl
diff --git a/src/dawn_native/opengl/DeviceGL.h b/src/dawn_native/opengl/DeviceGL.h
index 05f21d3..c1d4816 100644
--- a/src/dawn_native/opengl/DeviceGL.h
+++ b/src/dawn_native/opengl/DeviceGL.h
@@ -32,6 +32,7 @@
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 @@
void TickImpl() override;
+ const dawn_native::PCIInfo& GetPCIInfo() const override;
+
private:
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
@@ -59,6 +62,9 @@
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
ResultOrError<TextureBase*> 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 6e4d601..0a7763b 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -151,6 +151,10 @@
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
mMemoryAllocator = std::make_unique<MemoryAllocator>(this);
mRenderPassCache = std::make_unique<RenderPassCache>(this);
+
+ mPCIInfo.deviceId = mDeviceInfo.properties.deviceID;
+ mPCIInfo.vendorId = mDeviceInfo.properties.vendorID;
+ mPCIInfo.name = mDeviceInfo.properties.deviceName;
}
Device::~Device() {
@@ -290,6 +294,10 @@
}
}
+ 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 803101f..b8f3f15 100644
--- a/src/dawn_native/vulkan/DeviceVk.h
+++ b/src/dawn_native/vulkan/DeviceVk.h
@@ -78,6 +78,8 @@
void TickImpl() override;
+ const dawn_native::PCIInfo& GetPCIInfo() const override;
+
private:
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
@@ -155,6 +157,8 @@
std::vector<CommandPoolAndBuffer> mUnusedCommands;
CommandPoolAndBuffer mPendingCommands;
std::vector<VkSemaphore> 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 6a9fef9..f90dc9e 100644
--- a/src/include/dawn_native/DawnNative.h
+++ b/src/include/dawn_native/DawnNative.h
@@ -18,11 +18,20 @@
#include <dawn/dawn.h>
#include <dawn_native/dawn_native_export.h>
+#include <string>
+
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 68611af..a770b42 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 @@
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 @@
// 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 caf2978..a9f676f 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 <gtest/gtest.h>
#include <memory>
@@ -64,6 +65,13 @@
};
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 @@
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 @@
void ResolveExpectations();
std::unique_ptr<utils::BackendBinding> 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 7d30c2a..a9231fa 100644
--- a/src/tests/end2end/BlendStateTests.cpp
+++ b/src/tests/end2end/BlendStateTests.cpp
@@ -686,6 +686,7 @@
// Test that independent blend states on render targets works
TEST_P(BlendStateTest, IndependentBlendState) {
+ DAWN_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsIntel());
std::array<dawn::Texture, 4> renderTargets;
std::array<dawn::TextureView, 4> renderTargetViews;
diff --git a/src/tests/end2end/ScissorTests.cpp b/src/tests/end2end/ScissorTests.cpp
index 19a1590..3a4fc32 100644
--- a/src/tests/end2end/ScissorTests.cpp
+++ b/src/tests/end2end/ScissorTests.cpp
@@ -90,6 +90,7 @@
// 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);