mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-27 00:43:38 +00:00
Float16 is not standardized in WGSL or implemented in Tint, so remove support of the extension for now. Bug: dawn:571, dawn:426 Change-Id: Ia26f0ddb07cabf6057c0d7db9ade547494d2cc6e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/56441 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
260 lines
12 KiB
C++
260 lines
12 KiB
C++
// Copyright 2019 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/vulkan/AdapterVk.h"
|
|
|
|
#include "dawn_native/vulkan/BackendVk.h"
|
|
#include "dawn_native/vulkan/DeviceVk.h"
|
|
|
|
#include "common/GPUInfo.h"
|
|
|
|
namespace dawn_native { namespace vulkan {
|
|
|
|
Adapter::Adapter(Backend* backend, VkPhysicalDevice physicalDevice)
|
|
: AdapterBase(backend->GetInstance(), wgpu::BackendType::Vulkan),
|
|
mPhysicalDevice(physicalDevice),
|
|
mBackend(backend) {
|
|
}
|
|
|
|
const VulkanDeviceInfo& Adapter::GetDeviceInfo() const {
|
|
return mDeviceInfo;
|
|
}
|
|
|
|
VkPhysicalDevice Adapter::GetPhysicalDevice() const {
|
|
return mPhysicalDevice;
|
|
}
|
|
|
|
Backend* Adapter::GetBackend() const {
|
|
return mBackend;
|
|
}
|
|
|
|
MaybeError Adapter::Initialize() {
|
|
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
|
|
DAWN_TRY(CheckCoreWebGPUSupport());
|
|
|
|
if (mDeviceInfo.HasExt(DeviceExt::DriverProperties)) {
|
|
mDriverDescription = mDeviceInfo.driverProperties.driverName;
|
|
if (mDeviceInfo.driverProperties.driverInfo[0] != '\0') {
|
|
mDriverDescription += std::string(": ") + mDeviceInfo.driverProperties.driverInfo;
|
|
}
|
|
} else {
|
|
mDriverDescription =
|
|
"Vulkan driver version: " + std::to_string(mDeviceInfo.properties.driverVersion);
|
|
}
|
|
|
|
InitializeSupportedExtensions();
|
|
|
|
mPCIInfo.deviceId = mDeviceInfo.properties.deviceID;
|
|
mPCIInfo.vendorId = mDeviceInfo.properties.vendorID;
|
|
mPCIInfo.name = mDeviceInfo.properties.deviceName;
|
|
|
|
switch (mDeviceInfo.properties.deviceType) {
|
|
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
|
|
mAdapterType = wgpu::AdapterType::IntegratedGPU;
|
|
break;
|
|
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
|
|
mAdapterType = wgpu::AdapterType::DiscreteGPU;
|
|
break;
|
|
case VK_PHYSICAL_DEVICE_TYPE_CPU:
|
|
mAdapterType = wgpu::AdapterType::CPU;
|
|
break;
|
|
default:
|
|
mAdapterType = wgpu::AdapterType::Unknown;
|
|
break;
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
MaybeError Adapter::CheckCoreWebGPUSupport() {
|
|
// Needed for viewport Y-flip.
|
|
if (!mDeviceInfo.HasExt(DeviceExt::Maintenance1)) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 required.");
|
|
}
|
|
|
|
// Needed for security
|
|
if (!mDeviceInfo.features.robustBufferAccess) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan robustBufferAccess feature required.");
|
|
}
|
|
|
|
// TODO(crbug.com/dawn/955): Require BC || (ETC && ASTC) instead.
|
|
if (!mDeviceInfo.features.textureCompressionBC) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan textureCompressionBC feature required.");
|
|
}
|
|
|
|
// Needed for the respective WebGPU features.
|
|
if (!mDeviceInfo.features.depthBiasClamp) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan depthBiasClamp feature required.");
|
|
}
|
|
if (!mDeviceInfo.features.fragmentStoresAndAtomics) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan fragmentStoresAndAtomics feature required.");
|
|
}
|
|
if (!mDeviceInfo.features.fullDrawIndexUint32) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan fullDrawIndexUint32 feature required.");
|
|
}
|
|
if (!mDeviceInfo.features.imageCubeArray) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan imageCubeArray feature required.");
|
|
}
|
|
if (!mDeviceInfo.features.independentBlend) {
|
|
return DAWN_INTERNAL_ERROR("Vulkan independentBlend feature required.");
|
|
}
|
|
|
|
// Check base WebGPU limits are supported.
|
|
const VkPhysicalDeviceLimits& limits = mDeviceInfo.properties.limits;
|
|
if (limits.maxImageDimension1D < kMaxTextureDimension1D) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureDimension1D");
|
|
}
|
|
if (limits.maxImageDimension2D < kMaxTextureDimension2D ||
|
|
limits.maxImageDimensionCube < kMaxTextureDimension2D ||
|
|
limits.maxFramebufferWidth < kMaxTextureDimension2D ||
|
|
limits.maxFramebufferHeight < kMaxTextureDimension2D ||
|
|
limits.maxViewportDimensions[0] < kMaxTextureDimension2D ||
|
|
limits.maxViewportDimensions[1] < kMaxTextureDimension2D ||
|
|
limits.viewportBoundsRange[1] < kMaxTextureDimension2D) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureDimension2D");
|
|
}
|
|
if (limits.maxImageDimension3D < kMaxTextureDimension3D) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureDimension3D");
|
|
}
|
|
if (limits.maxImageArrayLayers < kMaxTextureArrayLayers) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureArrayLayers");
|
|
}
|
|
if (limits.maxBoundDescriptorSets < kMaxBindGroups) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxBindGroups");
|
|
}
|
|
if (limits.maxDescriptorSetUniformBuffersDynamic <
|
|
kMaxDynamicUniformBuffersPerPipelineLayout) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxDynamicUniformBuffersPerPipelineLayout");
|
|
}
|
|
if (limits.maxDescriptorSetStorageBuffersDynamic <
|
|
kMaxDynamicStorageBuffersPerPipelineLayout) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxDynamicStorageBuffersPerPipelineLayout");
|
|
}
|
|
if (limits.maxPerStageDescriptorSampledImages < kMaxSampledTexturesPerShaderStage) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxDynamicStorageBuffersPerPipelineLayout");
|
|
}
|
|
if (limits.maxPerStageDescriptorSampledImages < kMaxSampledTexturesPerShaderStage) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxSampledTexturesPerShaderStage");
|
|
}
|
|
if (limits.maxPerStageDescriptorSamplers < kMaxSamplersPerShaderStage) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxSamplersPerShaderStage");
|
|
}
|
|
if (limits.maxPerStageDescriptorStorageBuffers < kMaxStorageBuffersPerShaderStage) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxStorageBuffersPerShaderStage");
|
|
}
|
|
if (limits.maxPerStageDescriptorStorageImages < kMaxStorageTexturesPerShaderStage) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxStorageTexturesPerShaderStage");
|
|
}
|
|
if (limits.maxPerStageDescriptorUniformBuffers < kMaxUniformBuffersPerShaderStage) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxUniformBuffersPerShaderStage");
|
|
}
|
|
if (limits.maxUniformBufferRange < kMaxUniformBufferBindingSize) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxUniformBufferBindingSize");
|
|
}
|
|
if (limits.maxStorageBufferRange < kMaxStorageBufferBindingSize) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxStorageBufferBindingSize");
|
|
}
|
|
if (limits.minUniformBufferOffsetAlignment > kMinUniformBufferOffsetAlignment) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for minUniformBufferOffsetAlignment");
|
|
}
|
|
if (limits.minStorageBufferOffsetAlignment > kMinStorageBufferOffsetAlignment) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for minStorageBufferOffsetAlignment");
|
|
}
|
|
if (limits.maxVertexInputBindings < kMaxVertexBuffers) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxVertexBuffers");
|
|
}
|
|
if (limits.maxVertexInputAttributes < kMaxVertexAttributes) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxVertexAttributes");
|
|
}
|
|
if (limits.maxVertexInputBindingStride < kMaxVertexBufferArrayStride ||
|
|
limits.maxVertexInputAttributeOffset < kMaxVertexBufferArrayStride - 1) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxVertexBufferArrayStride");
|
|
}
|
|
if (limits.maxVertexOutputComponents < kMaxInterStageShaderComponents ||
|
|
limits.maxFragmentInputComponents < kMaxInterStageShaderComponents) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxInterStageShaderComponents");
|
|
}
|
|
if (limits.maxComputeSharedMemorySize < kMaxComputeWorkgroupStorageSize) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxComputeWorkgroupStorageSize");
|
|
}
|
|
if (limits.maxComputeWorkGroupInvocations < kMaxComputeWorkgroupInvocations) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxComputeWorkgroupInvocations");
|
|
}
|
|
if (limits.maxComputeWorkGroupSize[0] < kMaxComputeWorkgroupSizeX ||
|
|
limits.maxComputeWorkGroupSize[1] < kMaxComputeWorkgroupSizeY ||
|
|
limits.maxComputeWorkGroupSize[2] < kMaxComputeWorkgroupSizeZ) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxComputeWorkgroupSize");
|
|
}
|
|
if (limits.maxComputeWorkGroupCount[0] < kMaxComputePerDimensionDispatchSize ||
|
|
limits.maxComputeWorkGroupCount[1] < kMaxComputePerDimensionDispatchSize ||
|
|
limits.maxComputeWorkGroupCount[2] < kMaxComputePerDimensionDispatchSize) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan limits for maxComputePerDimensionDispatchSize");
|
|
}
|
|
if (limits.maxColorAttachments < kMaxColorAttachments) {
|
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxColorAttachments");
|
|
}
|
|
|
|
// Only check maxFragmentCombinedOutputResources on mobile GPUs. Desktop GPUs drivers seem
|
|
// to put incorrect values for this limit with things like 8 or 16 when they can do bindless
|
|
// storage buffers.
|
|
uint32_t vendorId = mDeviceInfo.properties.vendorID;
|
|
if (!gpu_info::IsAMD(vendorId) && !gpu_info::IsIntel(vendorId) &&
|
|
!gpu_info::IsNvidia(vendorId)) {
|
|
if (limits.maxFragmentCombinedOutputResources < kMaxColorAttachments +
|
|
kMaxStorageTexturesPerShaderStage +
|
|
kMaxStorageBuffersPerShaderStage) {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"Insufficient Vulkan maxFragmentCombinedOutputResources limit");
|
|
}
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
void Adapter::InitializeSupportedExtensions() {
|
|
if (mDeviceInfo.features.textureCompressionBC == VK_TRUE) {
|
|
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
|
|
}
|
|
|
|
if (mDeviceInfo.features.pipelineStatisticsQuery == VK_TRUE) {
|
|
mSupportedExtensions.EnableExtension(Extension::PipelineStatisticsQuery);
|
|
}
|
|
|
|
if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE) {
|
|
mSupportedExtensions.EnableExtension(Extension::TimestampQuery);
|
|
}
|
|
}
|
|
|
|
ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
|
return Device::Create(this, descriptor);
|
|
}
|
|
|
|
}} // namespace dawn_native::vulkan
|