d3d11: implement Adaptor, Backend, etc

This CL also moves some comman code in d3d12::Adapter and
d3d11::Backend to d3d::Adapter and d3d::Backend, so it can be
shared with d3d11 backend.

Bug: dawn:1705
Change-Id: Ica3bf33232d3380b7d4799c77bf9b43a8374a66e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/126220
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
This commit is contained in:
Peng Huang 2023-04-03 21:33:54 +00:00 committed by Dawn LUCI CQ
parent a7423b3d83
commit ebfd505d29
27 changed files with 818 additions and 100 deletions

View File

@ -0,0 +1,35 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_
#define INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_
#include <dxgi1_4.h>
#include <windows.h>
#include <wrl/client.h>
#include <memory>
#include "dawn/native/D3DBackend.h"
namespace dawn::native::d3d11 {
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public d3d::AdapterDiscoveryOptions {
AdapterDiscoveryOptions();
explicit AdapterDiscoveryOptions(Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
};
} // namespace dawn::native::d3d11
#endif // INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_

View File

@ -24,7 +24,7 @@
#include <vector>
#include "dawn/dawn_wsi.h"
#include "dawn/native/DawnNative.h"
#include "dawn/native/D3DBackend.h"
struct ID3D12Device;
struct ID3D12Resource;
@ -126,11 +126,9 @@ class DAWN_NATIVE_EXPORT ExternalImageDXGI {
std::unique_ptr<ExternalImageDXGIImpl> mImpl;
};
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public d3d::AdapterDiscoveryOptions {
AdapterDiscoveryOptions();
explicit AdapterDiscoveryOptions(Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
};
} // namespace dawn::native::d3d12

View File

@ -0,0 +1,33 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef INCLUDE_DAWN_NATIVE_D3DBACKEND_H_
#define INCLUDE_DAWN_NATIVE_D3DBACKEND_H_
#include <dxgi1_4.h>
#include <windows.h>
#include <wrl/client.h>
#include "dawn/native/DawnNative.h"
namespace dawn::native::d3d {
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
AdapterDiscoveryOptions(WGPUBackendType type, Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
};
} // namespace dawn::native::d3d
#endif // INCLUDE_DAWN_NATIVE_D3DBACKEND_H_

View File

@ -54,6 +54,9 @@ declare_args() {
# standalone to produce static libraries to use in their projects.
dawn_complete_static_libs = false
# Enables the compilation of Dawn's D3D11 backend
dawn_enable_d3d11 = false
# Enables the compilation of Dawn's D3D12 backend
dawn_enable_d3d12 = is_win

View File

@ -58,6 +58,9 @@ config("internal_config") {
]
}
if (dawn_enable_d3d11) {
defines += [ "DAWN_ENABLE_BACKEND_D3D11" ]
}
if (dawn_enable_d3d12) {
defines += [ "DAWN_ENABLE_BACKEND_D3D12" ]
}

View File

@ -134,7 +134,9 @@ source_set("headers") {
# Include all backend's public headers so that dependencies can include
# them even when the backends are disabled.
"${dawn_root}/include/dawn/native/D3D11Backend.h",
"${dawn_root}/include/dawn/native/D3D12Backend.h",
"${dawn_root}/include/dawn/native/D3DBackend.h",
"${dawn_root}/include/dawn/native/MetalBackend.h",
"${dawn_root}/include/dawn/native/NullBackend.h",
"${dawn_root}/include/dawn/native/OpenGLBackend.h",
@ -393,7 +395,7 @@ source_set("sources") {
# Somehow use dxcompiler.lib makes CoreApp unable to activate
# WinPIX should be added as third party tools and linked statically
if (dawn_enable_d3d12) {
if (dawn_enable_d3d11 || dawn_enable_d3d12) {
sources += [
"d3d/AdapterD3D.cpp",
"d3d/AdapterD3D.h",
@ -401,6 +403,7 @@ source_set("sources") {
"d3d/BackendD3D.h",
"d3d/BlobD3D.cpp",
"d3d/BlobD3D.h",
"d3d/D3DBackend.cpp",
"d3d/D3DCompilationRequest.h",
"d3d/D3DError.cpp",
"d3d/D3DError.h",
@ -417,6 +420,21 @@ source_set("sources") {
]
}
if (dawn_enable_d3d11) {
libs += [ "dxguid.lib" ]
sources += [
"d3d11/AdapterD3D11.cpp",
"d3d11/AdapterD3D11.h",
"d3d11/BackendD3D11.cpp",
"d3d11/BackendD3D11.h",
"d3d11/D3D11Backend.cpp",
"d3d11/DeviceInfoD3D11.cpp",
"d3d11/DeviceInfoD3D11.h",
"d3d11/PlatformFunctionsD3D11.cpp",
"d3d11/PlatformFunctionsD3D11.h",
]
}
if (dawn_enable_d3d12) {
libs += [ "dxguid.lib" ]
sources += [

View File

@ -251,14 +251,16 @@ if (WINDOWS_STORE)
target_link_libraries(dawn_native PRIVATE debug dxgi.lib)
endif()
if (DAWN_ENABLE_D3D12)
if (DAWN_ENABLE_D3D11 OR DAWN_ENABLE_D3D12)
target_sources(dawn_native PRIVATE
"${DAWN_INCLUDE_DIR}/dawn/native/D3DBackend.h"
"d3d/AdapterD3D.cpp"
"d3d/AdapterD3D.h"
"d3d/BackendD3D.cpp"
"d3d/BackendD3D.h"
"d3d/BlobD3D.cpp"
"d3d/BlobD3D.h"
"d3d/D3DBackend.cpp"
"d3d/D3DCompilationRequest.h"
"d3d/D3DError.cpp"
"d3d/D3DError.h"
@ -275,6 +277,22 @@ if (DAWN_ENABLE_D3D12)
)
endif()
if (DAWN_ENABLE_D3D11)
target_sources(dawn_native PRIVATE
"${DAWN_INCLUDE_DIR}/dawn/native/D3D11Backend.h"
"d3d11/AdapterD3D11.cpp"
"d3d11/AdapterD3D11.h"
"d3d11/BackendD3D11.cpp"
"d3d11/BackendD3D11.h"
"d3d11/D3D11Backend.cpp"
"d3d11/DeviceInfoD3D11.cpp"
"d3d11/DeviceInfoD3D11.h"
"d3d11/PlatformFunctionsD3D11.cpp"
"d3d11/PlatformFunctionsD3D11.h"
)
endif()
if (DAWN_ENABLE_D3D12)
target_sources(dawn_native PRIVATE
"${DAWN_INCLUDE_DIR}/dawn/native/D3D12Backend.h"

View File

@ -44,6 +44,11 @@ namespace dawn::native {
// Forward definitions of each backend's "Connect" function that creates new BackendConnection.
// Conditionally compiled declarations are used to avoid using static constructors instead.
#if defined(DAWN_ENABLE_BACKEND_D3D11)
namespace d3d11 {
BackendConnection* Connect(InstanceBase* instance);
}
#endif // defined(DAWN_ENABLE_BACKEND_D3D11)
#if defined(DAWN_ENABLE_BACKEND_D3D12)
namespace d3d12 {
BackendConnection* Connect(InstanceBase* instance);
@ -77,6 +82,9 @@ BackendsBitset GetEnabledBackends() {
#if defined(DAWN_ENABLE_BACKEND_NULL)
enabledBackends.set(wgpu::BackendType::Null);
#endif // defined(DAWN_ENABLE_BACKEND_NULL)
#if defined(DAWN_ENABLE_BACKEND_D3D11)
enabledBackends.set(wgpu::BackendType::D3D11);
#endif // defined(DAWN_ENABLE_BACKEND_D3D11)
#if defined(DAWN_ENABLE_BACKEND_D3D12)
enabledBackends.set(wgpu::BackendType::D3D12);
#endif // defined(DAWN_ENABLE_BACKEND_D3D12)
@ -372,6 +380,12 @@ void InstanceBase::EnsureBackendConnection(wgpu::BackendType backendType) {
break;
#endif // defined(DAWN_ENABLE_BACKEND_NULL)
#if defined(DAWN_ENABLE_BACKEND_D3D11)
case wgpu::BackendType::D3D11:
Register(d3d11::Connect(this), wgpu::BackendType::D3D11);
break;
#endif // defined(DAWN_ENABLE_BACKEND_D3D11)
#if defined(DAWN_ENABLE_BACKEND_D3D12)
case wgpu::BackendType::D3D12:
Register(d3d12::Connect(this), wgpu::BackendType::D3D12);

View File

@ -14,8 +14,10 @@
#include "dawn/native/d3d/AdapterD3D.h"
#include <string>
#include <utility>
#include "dawn/common/WindowsUtils.h"
#include "dawn/native/d3d/BackendD3D.h"
namespace dawn::native::d3d {
@ -38,4 +40,35 @@ Backend* Adapter::GetBackend() const {
return mBackend;
}
MaybeError Adapter::InitializeImpl() {
DXGI_ADAPTER_DESC1 adapterDesc;
GetHardwareAdapter()->GetDesc1(&adapterDesc);
mDeviceId = adapterDesc.DeviceId;
mVendorId = adapterDesc.VendorId;
mName = WCharToUTF8(adapterDesc.Description);
if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
mAdapterType = wgpu::AdapterType::CPU;
} else {
// Assume it is a discrete GPU. If it is an integrated GPU, it will be overwritten later.
mAdapterType = wgpu::AdapterType::DiscreteGPU;
}
// Convert the adapter's D3D11 driver version to a readable string like "24.21.13.9793".
LARGE_INTEGER umdVersion;
if (GetHardwareAdapter()->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umdVersion) !=
DXGI_ERROR_UNSUPPORTED) {
uint64_t encodedVersion = umdVersion.QuadPart;
uint16_t mask = 0xFFFF;
mDriverVersion = {static_cast<uint16_t>((encodedVersion >> 48) & mask),
static_cast<uint16_t>((encodedVersion >> 32) & mask),
static_cast<uint16_t>((encodedVersion >> 16) & mask),
static_cast<uint16_t>(encodedVersion & mask)};
mDriverDescription = std::string("D3D11 driver version ") + mDriverVersion.ToString();
}
return {};
}
} // namespace dawn::native::d3d

View File

@ -34,6 +34,9 @@ class Adapter : public AdapterBase {
IDXGIAdapter3* GetHardwareAdapter() const;
Backend* GetBackend() const;
protected:
MaybeError InitializeImpl() override;
private:
ComPtr<IDXGIAdapter3> mHardwareAdapter;
Backend* mBackend;

View File

@ -17,6 +17,7 @@
#include <utility>
#include "dawn/common/Log.h"
#include "dawn/native/D3DBackend.h"
#include "dawn/native/Instance.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d/PlatformFunctions.h"
@ -237,4 +238,50 @@ const PlatformFunctions* Backend::GetFunctions() const {
return mFunctions.get();
}
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters(const TogglesState& adapterToggles) {
AdapterDiscoveryOptions options(ToAPI(GetType()), nullptr);
std::vector<Ref<AdapterBase>> adapters;
if (GetInstance()->ConsumedError(DiscoverAdapters(&options, adapterToggles), &adapters)) {
return {};
}
return adapters;
}
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
const AdapterDiscoveryOptionsBase* optionsBase,
const TogglesState& adapterToggles) {
ASSERT(optionsBase->backendType == ToAPI(GetType()));
const AdapterDiscoveryOptions* options =
static_cast<const AdapterDiscoveryOptions*>(optionsBase);
std::vector<Ref<AdapterBase>> adapters;
if (options->dxgiAdapter != nullptr) {
// |dxgiAdapter| was provided. Discover just that adapter.
Ref<AdapterBase> adapter;
DAWN_TRY_ASSIGN(adapter,
CreateAdapterFromIDXGIAdapter(options->dxgiAdapter, adapterToggles));
adapters.push_back(std::move(adapter));
return std::move(adapters);
}
// Enumerate and discover all available adapters.
for (uint32_t adapterIndex = 0;; ++adapterIndex) {
ComPtr<IDXGIAdapter1> dxgiAdapter = nullptr;
if (GetFactory()->EnumAdapters1(adapterIndex, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND) {
break; // No more adapters to enumerate.
}
ASSERT(dxgiAdapter != nullptr);
Ref<AdapterBase> adapter;
if (GetInstance()->ConsumedError(CreateAdapterFromIDXGIAdapter(dxgiAdapter, adapterToggles),
&adapter)) {
continue;
}
adapters.push_back(std::move(adapter));
}
return adapters;
}
} // namespace dawn::native::d3d

View File

@ -18,6 +18,7 @@
#include <memory>
#include <string>
#include <variant>
#include <vector>
#include "dawn/native/BackendConnection.h"
@ -74,6 +75,17 @@ class Backend : public BackendConnection {
const PlatformFunctions* GetFunctions() const;
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
const TogglesState& adapterToggles) override;
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
const AdapterDiscoveryOptionsBase* optionsBase,
const TogglesState& adapterToggles) override;
protected:
virtual ResultOrError<Ref<AdapterBase>> CreateAdapterFromIDXGIAdapter(
ComPtr<IDXGIAdapter> dxgiAdapter,
const TogglesState& adapterToggles) = 0;
private:
// Acquiring DXC version information and store the result in mDxcVersionInfo. This function
// should be called only once, during startup in `Initialize`.

View File

@ -0,0 +1,28 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// D3D12Backend.cpp: contains the definition of symbols exported by D3D12Backend.h so that they
// can be compiled twice: once export (shared library), once not exported (static library)
#include "dawn/native/D3DBackend.h"
#include <utility>
namespace dawn::native::d3d {
AdapterDiscoveryOptions::AdapterDiscoveryOptions(WGPUBackendType type,
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter)
: AdapterDiscoveryOptionsBase(type), dxgiAdapter(std::move(adapter)) {}
} // namespace dawn::native::d3d

View File

@ -21,7 +21,7 @@
// NOLINTNEXTLINE(build/include_order)
#include "dawn/common/windows_with_undefs.h"
#include <d3d11_2.h> // NOLINT(build/include_order)
#include <d3d11_4.h> // NOLINT(build/include_order)
#include <dxcapi.h> // NOLINT(build/include_order)
#include <dxgi1_4.h> // NOLINT(build/include_order)
#include <wrl.h> // NOLINT(build/include_order)

View File

@ -0,0 +1,169 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn/native/d3d11/AdapterD3D11.h"
#include <string>
#include <utility>
#include "dawn/common/Constants.h"
#include "dawn/native/Instance.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d11/BackendD3D11.h"
#include "dawn/native/d3d11/PlatformFunctionsD3D11.h"
namespace dawn::native::d3d11 {
Adapter::Adapter(Backend* backend,
ComPtr<IDXGIAdapter3> hardwareAdapter,
const TogglesState& adapterToggles)
: Base(backend, std::move(hardwareAdapter), wgpu::BackendType::D3D11, adapterToggles) {}
Adapter::~Adapter() = default;
bool Adapter::SupportsExternalImages() const {
// TODO(dawn:1724): Implement external images on D3D11.
return false;
}
const DeviceInfo& Adapter::GetDeviceInfo() const {
return mDeviceInfo;
}
ComPtr<ID3D11Device> Adapter::GetD3D11Device() const {
return mD3d11Device;
}
MaybeError Adapter::InitializeImpl() {
DAWN_TRY(Base::InitializeImpl());
// D3D11 cannot check for feature support without a device.
// Create the device to populate the adapter properties then reuse it when needed for actual
// rendering.
const PlatformFunctions* functions = static_cast<Backend*>(GetBackend())->GetFunctions();
const D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0};
UINT flags = 0;
if (GetInstance()->IsBackendValidationEnabled()) {
flags |= D3D11_CREATE_DEVICE_DEBUG;
}
DAWN_TRY(CheckHRESULT(functions->d3d11CreateDevice(
GetHardwareAdapter(), D3D_DRIVER_TYPE_UNKNOWN, /*Software=*/nullptr,
flags, featureLevels, std::size(featureLevels), D3D11_SDK_VERSION,
&mD3d11Device, &mFeatureLevel, /*[out] ppImmediateContext=*/nullptr),
"D3D11CreateDevice failed"));
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
// Base::InitializeImpl() cannot distinguish between discrete and integrated GPUs, so we need to
// overwrite it.
if (mAdapterType == wgpu::AdapterType::DiscreteGPU && mDeviceInfo.isUMA) {
mAdapterType = wgpu::AdapterType::IntegratedGPU;
}
return {};
}
void Adapter::InitializeSupportedFeaturesImpl() {
EnableFeature(Feature::TextureCompressionBC);
}
MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
GetDefaultLimits(&limits->v1);
// // https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels
// Limits that are the same across D3D feature levels
limits->v1.maxTextureDimension1D = D3D11_REQ_TEXTURE1D_U_DIMENSION;
limits->v1.maxTextureDimension2D = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
limits->v1.maxTextureDimension3D = D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
limits->v1.maxTextureArrayLayers = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
// Slot values can be 0-15, inclusive:
// https://docs.microsoft.com/en-ca/windows/win32/api/d3d11/ns-d3d11-d3d11_input_element_desc
limits->v1.maxVertexBuffers = 16;
limits->v1.maxVertexAttributes = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT;
uint32_t maxUAVsAllStages = mFeatureLevel == D3D_FEATURE_LEVEL_11_1
? D3D11_1_UAV_SLOT_COUNT
: D3D11_PS_CS_UAV_REGISTER_COUNT;
ASSERT(maxUAVsAllStages / 4 > limits->v1.maxStorageTexturesPerShaderStage);
ASSERT(maxUAVsAllStages / 4 > limits->v1.maxStorageBuffersPerShaderStage);
uint32_t maxUAVsPerStage = maxUAVsAllStages / 2;
// Reserve one slot for builtin constants.
constexpr uint32_t kReservedCBVSlots = 1;
limits->v1.maxUniformBuffersPerShaderStage =
D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - kReservedCBVSlots;
// Allocate half of the UAVs to storage buffers, and half to storage textures.
limits->v1.maxStorageTexturesPerShaderStage = maxUAVsPerStage / 2;
limits->v1.maxStorageBuffersPerShaderStage = maxUAVsPerStage - maxUAVsPerStage / 2;
limits->v1.maxSampledTexturesPerShaderStage = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
limits->v1.maxSamplersPerShaderStage = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
limits->v1.maxColorAttachments = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
// TODO(dawn:1721): support dynamic uniform buffers and storage buffers?
limits->v1.maxDynamicUniformBuffersPerPipelineLayout = 0;
limits->v1.maxDynamicStorageBuffersPerPipelineLayout = 0;
// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-attributes-numthreads
limits->v1.maxComputeWorkgroupSizeX = D3D11_CS_THREAD_GROUP_MAX_X;
limits->v1.maxComputeWorkgroupSizeY = D3D11_CS_THREAD_GROUP_MAX_Y;
limits->v1.maxComputeWorkgroupSizeZ = D3D11_CS_THREAD_GROUP_MAX_Z;
limits->v1.maxComputeInvocationsPerWorkgroup = D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP;
// https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-dispatch
limits->v1.maxComputeWorkgroupsPerDimension = D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION;
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-compute-shaders
// Thread Group Shared Memory is limited to 16Kb on downlevel hardware. This is less than
// the 32Kb that is available to Direct3D 11 hardware. D3D12 is also 32kb.
limits->v1.maxComputeWorkgroupStorageSize = 32768;
// Max number of "constants" where each constant is a 16-byte float4
limits->v1.maxUniformBufferBindingSize = D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16;
// D3D11 has no documented limit on the size of a storage buffer binding.
limits->v1.maxStorageBufferBindingSize = 4294967295;
// D3D11 has no documented limit on the buffer size.
limits->v1.maxBufferSize = kAssumedMaxBufferSize;
return {};
}
MaybeError Adapter::ValidateFeatureSupportedWithTogglesImpl(wgpu::FeatureName feature,
const TogglesState& toggles) const {
return {};
}
void Adapter::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {}
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor,
const TogglesState& deviceToggles) {
// TODO(dawn:1705): Implement D3D11 backend.
return DAWN_UNIMPLEMENTED_ERROR("D3D11 backend is not implemented yet");
}
// Resets the backend device and creates a new one. If any D3D11 objects belonging to the
// current ID3D11Device have not been destroyed, a non-zero value will be returned upon Reset()
// and the subequent call to CreateDevice will return a handle the existing device instead of
// creating a new one.
MaybeError Adapter::ResetInternalDeviceForTestingImpl() {
[[maybe_unused]] auto refCount = mD3d11Device.Reset();
ASSERT(refCount == 0);
DAWN_TRY(Initialize());
return {};
}
} // namespace dawn::native::d3d11

View File

@ -0,0 +1,64 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_NATIVE_D3D11_ADAPTERD3D11_H_
#define SRC_DAWN_NATIVE_D3D11_ADAPTERD3D11_H_
#include "dawn/native/d3d/AdapterD3D.h"
#include "dawn/native/d3d/d3d_platform.h"
#include "dawn/native/d3d11/DeviceInfoD3D11.h"
namespace dawn::native::d3d11 {
class Backend;
class Adapter : public d3d::Adapter {
public:
Adapter(Backend* backend,
ComPtr<IDXGIAdapter3> hardwareAdapter,
const TogglesState& adapterToggles);
~Adapter() override;
// AdapterBase Implementation
bool SupportsExternalImages() const override;
const DeviceInfo& GetDeviceInfo() const;
ComPtr<ID3D11Device> GetD3D11Device() const;
private:
using Base = d3d::Adapter;
void SetupBackendDeviceToggles(TogglesState* deviceToggles) const override;
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor,
const TogglesState& deviceToggles) override;
MaybeError ResetInternalDeviceForTestingImpl() override;
MaybeError InitializeImpl() override;
void InitializeSupportedFeaturesImpl() override;
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
MaybeError ValidateFeatureSupportedWithTogglesImpl(wgpu::FeatureName feature,
const TogglesState& toggles) const override;
ComPtr<ID3D11Device> mD3d11Device;
D3D_FEATURE_LEVEL mFeatureLevel;
DeviceInfo mDeviceInfo = {};
};
} // namespace dawn::native::d3d11
#endif // SRC_DAWN_NATIVE_D3D11_ADAPTERD3D11_H_

View File

@ -0,0 +1,66 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn/native/d3d11/BackendD3D11.h"
#include <memory>
#include <utility>
#include "dawn/common/Log.h"
#include "dawn/native/D3D11Backend.h"
#include "dawn/native/Instance.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d11/AdapterD3D11.h"
#include "dawn/native/d3d11/PlatformFunctionsD3D11.h"
namespace dawn::native::d3d11 {
Backend::Backend(InstanceBase* instance) : Base(instance, wgpu::BackendType::D3D11) {}
MaybeError Backend::Initialize() {
auto functions = std::make_unique<PlatformFunctions>();
DAWN_TRY(functions->LoadFunctions());
DAWN_TRY(Base::Initialize(std::move(functions)));
return {};
}
const PlatformFunctions* Backend::GetFunctions() const {
return static_cast<const PlatformFunctions*>(Base::GetFunctions());
}
ResultOrError<Ref<AdapterBase>> Backend::CreateAdapterFromIDXGIAdapter(
ComPtr<IDXGIAdapter> dxgiAdapter,
const TogglesState& adapterToggles) {
ComPtr<IDXGIAdapter3> dxgiAdapter3;
DAWN_TRY(CheckHRESULT(dxgiAdapter.As(&dxgiAdapter3), "DXGIAdapter retrieval"));
Ref<Adapter> adapter = AcquireRef(new Adapter(this, std::move(dxgiAdapter3), adapterToggles));
DAWN_TRY(adapter->Initialize());
return {std::move(adapter)};
}
BackendConnection* Connect(InstanceBase* instance) {
Backend* backend = new Backend(instance);
if (instance->ConsumedError(backend->Initialize())) {
delete backend;
return nullptr;
}
return backend;
}
} // namespace dawn::native::d3d11

View File

@ -0,0 +1,44 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_NATIVE_D3D11_BACKENDD3D11_H_
#define SRC_DAWN_NATIVE_D3D11_BACKENDD3D11_H_
#include <vector>
#include "dawn/native/d3d/BackendD3D.h"
namespace dawn::native::d3d11 {
class PlatformFunctions;
class Backend : public d3d::Backend {
public:
explicit Backend(InstanceBase* instance);
MaybeError Initialize();
const PlatformFunctions* GetFunctions() const;
protected:
ResultOrError<Ref<AdapterBase>> CreateAdapterFromIDXGIAdapter(
ComPtr<IDXGIAdapter> dxgiAdapter,
const TogglesState& adapterToggles) override;
private:
using Base = d3d::Backend;
};
} // namespace dawn::native::d3d11
#endif // SRC_DAWN_NATIVE_D3D11_BACKENDD3D11_H_

View File

@ -0,0 +1,31 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// D3D11Backend.cpp: contains the definition of symbols exported by D3D11Backend.h so that they
// can be compiled twice: once export (shared library), once not exported (static library)
#include "dawn/native/D3D11Backend.h"
#include <utility>
#include "dawn/native/d3d/d3d_platform.h"
namespace dawn::native::d3d11 {
AdapterDiscoveryOptions::AdapterDiscoveryOptions() : AdapterDiscoveryOptions(nullptr) {}
AdapterDiscoveryOptions::AdapterDiscoveryOptions(ComPtr<IDXGIAdapter> adapter)
: d3d::AdapterDiscoveryOptions(WGPUBackendType_D3D11, std::move(adapter)) {}
} // namespace dawn::native::d3d11

View File

@ -0,0 +1,45 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn/native/d3d11/DeviceInfoD3D11.h"
#include <utility>
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d11/AdapterD3D11.h"
#include "dawn/native/d3d11/PlatformFunctionsD3D11.h"
namespace dawn::native::d3d11 {
ResultOrError<DeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
DeviceInfo info = {};
D3D11_FEATURE_DATA_D3D11_OPTIONS2 options2;
DAWN_TRY(CheckHRESULT(adapter.GetD3D11Device()->CheckFeatureSupport(
D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2)),
"D3D11_FEATURE_D3D11_OPTIONS2"));
info.isUMA = options2.UnifiedMemoryArchitecture;
info.shaderModel = 50;
// Profiles are always <stage>s_<minor>_<major> so we build the s_<minor>_major and add
// it to each of the stage's suffix.
info.shaderProfiles[SingleShaderStage::Vertex] = L"vs_5_0";
info.shaderProfiles[SingleShaderStage::Fragment] = L"ps_5_0";
info.shaderProfiles[SingleShaderStage::Compute] = L"cs_5_0";
return std::move(info);
}
} // namespace dawn::native::d3d11

View File

@ -0,0 +1,38 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_NATIVE_D3D11_DEVICEINFOD3D11_H_
#define SRC_DAWN_NATIVE_D3D11_DEVICEINFOD3D11_H_
#include "dawn/native/Error.h"
#include "dawn/native/PerStage.h"
#include "dawn/native/d3d/d3d_platform.h"
namespace dawn::native::d3d11 {
class Adapter;
struct DeviceInfo {
bool isUMA;
// shaderModel indicates the maximum supported shader model, for example, the value 62
// indicates that current driver supports the maximum shader model is shader model 6.2.
uint32_t shaderModel;
PerStage<std::wstring> shaderProfiles;
};
ResultOrError<DeviceInfo> GatherDeviceInfo(const Adapter& adapter);
} // namespace dawn::native::d3d11
#endif // SRC_DAWN_NATIVE_D3D11_DEVICEINFOD3D11_H_

View File

@ -0,0 +1,45 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn/native/d3d11/PlatformFunctionsD3D11.h"
#include <string>
namespace dawn::native::d3d11 {
PlatformFunctions::PlatformFunctions() = default;
PlatformFunctions::~PlatformFunctions() = default;
MaybeError PlatformFunctions::LoadFunctions() {
DAWN_TRY(Base::LoadFunctions());
DAWN_TRY(LoadD3D11());
return {};
}
MaybeError PlatformFunctions::LoadD3D11() {
#if DAWN_PLATFORM_IS(WINUWP)
d3d11CreateDevice = &D3D11CreateDevice;
#else
std::string error;
if (!mD3D11Lib.Open("d3d11.dll", &error) ||
!mD3D11Lib.GetProc(&d3d11CreateDevice, "D3D11CreateDevice", &error)) {
return DAWN_INTERNAL_ERROR(error.c_str());
}
#endif
return {};
}
} // namespace dawn::native::d3d11

View File

@ -0,0 +1,43 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_NATIVE_D3D11_PLATFORMFUNCTIONSD3D11_H_
#define SRC_DAWN_NATIVE_D3D11_PLATFORMFUNCTIONSD3D11_H_
#include "dawn/native/d3d/PlatformFunctions.h"
#include "dawn/native/d3d/d3d_platform.h"
namespace dawn::native::d3d11 {
class PlatformFunctions final : public d3d::PlatformFunctions {
public:
PlatformFunctions();
~PlatformFunctions() override;
MaybeError LoadFunctions();
// Functions from D3D11.dll
PFN_D3D11_CREATE_DEVICE d3d11CreateDevice = nullptr;
private:
using Base = d3d::PlatformFunctions;
MaybeError LoadD3D11();
DynamicLib mD3D11Lib;
};
} // namespace dawn::native::d3d11
#endif // SRC_DAWN_NATIVE_D3D11_PLATFORMFUNCTIONSD3D11_H_

View File

@ -56,6 +56,7 @@ ComPtr<ID3D12Device> Adapter::GetDevice() const {
}
MaybeError Adapter::InitializeImpl() {
DAWN_TRY(Base::InitializeImpl());
// D3D12 cannot check for feature support without a device.
// Create the device to populate the adapter properties then reuse it when needed for actual
// rendering.
@ -67,33 +68,12 @@ MaybeError Adapter::InitializeImpl() {
DAWN_TRY(InitializeDebugLayerFilters());
DXGI_ADAPTER_DESC1 adapterDesc;
GetHardwareAdapter()->GetDesc1(&adapterDesc);
mDeviceId = adapterDesc.DeviceId;
mVendorId = adapterDesc.VendorId;
mName = WCharToUTF8(adapterDesc.Description);
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
mAdapterType = wgpu::AdapterType::CPU;
} else {
mAdapterType =
(mDeviceInfo.isUMA) ? wgpu::AdapterType::IntegratedGPU : wgpu::AdapterType::DiscreteGPU;
}
// Convert the adapter's D3D12 driver version to a readable string like "24.21.13.9793".
LARGE_INTEGER umdVersion;
if (GetHardwareAdapter()->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umdVersion) !=
DXGI_ERROR_UNSUPPORTED) {
uint64_t encodedVersion = umdVersion.QuadPart;
uint16_t mask = 0xFFFF;
mDriverVersion = {static_cast<uint16_t>((encodedVersion >> 48) & mask),
static_cast<uint16_t>((encodedVersion >> 32) & mask),
static_cast<uint16_t>((encodedVersion >> 16) & mask),
static_cast<uint16_t>(encodedVersion & mask)};
mDriverDescription = std::string("D3D12 driver version ") + mDriverVersion.ToString();
// Base::InitializeImpl() cannot distinguish between discrete and integrated GPUs, so we need to
// overwrite it here.
if (mAdapterType == wgpu::AdapterType::DiscreteGPU && mDeviceInfo.isUMA) {
mAdapterType = wgpu::AdapterType::IntegratedGPU;
}
if (GetInstance()->IsAdapterBlocklistEnabled()) {
@ -316,7 +296,7 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
limits->v1.maxComputeWorkgroupSizeZ = D3D12_CS_THREAD_GROUP_MAX_Z;
limits->v1.maxComputeInvocationsPerWorkgroup = D3D12_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP;
// https://docs.maxComputeWorkgroupSizeXmicrosoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_dispatch_arguments
// https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_dispatch_arguments
limits->v1.maxComputeWorkgroupsPerDimension = D3D12_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION;
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-compute-shaders
@ -610,7 +590,8 @@ ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor*
// and the subequent call to CreateDevice will return a handle the existing device instead of
// creating a new one.
MaybeError Adapter::ResetInternalDeviceForTestingImpl() {
ASSERT(mD3d12Device.Reset() == 0);
[[maybe_unused]] auto refCount = mD3d12Device.Reset();
ASSERT(refCount == 0);
DAWN_TRY(Initialize());
return {};

View File

@ -26,21 +26,6 @@
#include "dawn/native/d3d12/UtilsD3D12.h"
namespace dawn::native::d3d12 {
namespace {
ResultOrError<Ref<AdapterBase>> CreateAdapterFromIDXGIAdapter(Backend* backend,
ComPtr<IDXGIAdapter> dxgiAdapter,
const TogglesState& adapterToggles) {
ComPtr<IDXGIAdapter3> dxgiAdapter3;
DAWN_TRY(CheckHRESULT(dxgiAdapter.As(&dxgiAdapter3), "DXGIAdapter retrieval"));
Ref<Adapter> adapter =
AcquireRef(new Adapter(backend, std::move(dxgiAdapter3), adapterToggles));
DAWN_TRY(adapter->Initialize());
return {std::move(adapter)};
}
} // namespace
Backend::Backend(InstanceBase* instance) : Base(instance, wgpu::BackendType::D3D12) {}
@ -78,52 +63,15 @@ const PlatformFunctions* Backend::GetFunctions() const {
return static_cast<const PlatformFunctions*>(Base::GetFunctions());
}
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters(const TogglesState& adapterToggles) {
AdapterDiscoveryOptions options;
auto result = DiscoverAdapters(&options, adapterToggles);
if (result.IsError()) {
GetInstance()->ConsumedError(result.AcquireError());
return {};
}
return result.AcquireSuccess();
}
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
const AdapterDiscoveryOptionsBase* optionsBase,
ResultOrError<Ref<AdapterBase>> Backend::CreateAdapterFromIDXGIAdapter(
ComPtr<IDXGIAdapter> dxgiAdapter,
const TogglesState& adapterToggles) {
ASSERT(optionsBase->backendType == WGPUBackendType_D3D12);
const AdapterDiscoveryOptions* options =
static_cast<const AdapterDiscoveryOptions*>(optionsBase);
ComPtr<IDXGIAdapter3> dxgiAdapter3;
DAWN_TRY(CheckHRESULT(dxgiAdapter.As(&dxgiAdapter3), "DXGIAdapter retrieval"));
Ref<Adapter> adapter = AcquireRef(new Adapter(this, std::move(dxgiAdapter3), adapterToggles));
DAWN_TRY(adapter->Initialize());
std::vector<Ref<AdapterBase>> adapters;
if (options->dxgiAdapter != nullptr) {
// |dxgiAdapter| was provided. Discover just that adapter.
Ref<AdapterBase> adapter;
DAWN_TRY_ASSIGN(adapter,
CreateAdapterFromIDXGIAdapter(this, options->dxgiAdapter, adapterToggles));
adapters.push_back(std::move(adapter));
return std::move(adapters);
}
// Enumerate and discover all available adapters.
for (uint32_t adapterIndex = 0;; ++adapterIndex) {
ComPtr<IDXGIAdapter1> dxgiAdapter = nullptr;
if (GetFactory()->EnumAdapters1(adapterIndex, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND) {
break; // No more adapters to enumerate.
}
ASSERT(dxgiAdapter != nullptr);
ResultOrError<Ref<AdapterBase>> adapter =
CreateAdapterFromIDXGIAdapter(this, dxgiAdapter, adapterToggles);
if (adapter.IsError()) {
GetInstance()->ConsumedError(adapter.AcquireError());
continue;
}
adapters.push_back(adapter.AcquireSuccess());
}
return adapters;
return {std::move(adapter)};
}
BackendConnection* Connect(InstanceBase* instance) {

View File

@ -34,10 +34,9 @@ class Backend final : public d3d::Backend {
const PlatformFunctions* GetFunctions() const;
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
const TogglesState& adapterToggles) override;
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
const AdapterDiscoveryOptionsBase* optionsBase,
protected:
ResultOrError<Ref<AdapterBase>> CreateAdapterFromIDXGIAdapter(
ComPtr<IDXGIAdapter> dxgiAdapter,
const TogglesState& adapterToggles) override;
private:

View File

@ -112,9 +112,9 @@ uint64_t SetExternalMemoryReservation(WGPUDevice device,
memorySegment, requestedReservationSize);
}
AdapterDiscoveryOptions::AdapterDiscoveryOptions()
: AdapterDiscoveryOptionsBase(WGPUBackendType_D3D12), dxgiAdapter(nullptr) {}
AdapterDiscoveryOptions::AdapterDiscoveryOptions() : AdapterDiscoveryOptions(nullptr) {}
AdapterDiscoveryOptions::AdapterDiscoveryOptions(ComPtr<IDXGIAdapter> adapter)
: AdapterDiscoveryOptionsBase(WGPUBackendType_D3D12), dxgiAdapter(std::move(adapter)) {}
: d3d::AdapterDiscoveryOptions(WGPUBackendType_D3D12, std::move(adapter)) {}
} // namespace dawn::native::d3d12