Vulkan: Check for required limits when initializing adapters
Also adds the new limits for maxComputeWorkgroupSize because there are few systems where the .Z of that limit goes above 64. Bug: dawn:796 Change-Id: I52e85e7b7c666da15493178e170ca82922d34017 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/56082 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
14d4a3b729
commit
fc37b32c55
|
@ -25,9 +25,14 @@ static constexpr uint32_t kNumStages = 3;
|
|||
static constexpr uint8_t kMaxColorAttachments = 8u;
|
||||
static constexpr uint32_t kTextureBytesPerRowAlignment = 256u;
|
||||
static constexpr uint32_t kMaxInterStageShaderComponents = 60u;
|
||||
|
||||
// Compute constants
|
||||
static constexpr uint32_t kMaxComputeWorkgroupStorageSize = 16352u;
|
||||
static constexpr uint32_t kMaxComputeWorkgroupInvocations = 256u;
|
||||
static constexpr uint32_t kMaxComputePerDimensionDispatchSize = 65535u;
|
||||
static constexpr uint32_t kMaxComputeWorkgroupSizeX = 256;
|
||||
static constexpr uint32_t kMaxComputeWorkgroupSizeY = 256;
|
||||
static constexpr uint32_t kMaxComputeWorkgroupSizeZ = 64;
|
||||
|
||||
// Per stage limits
|
||||
static constexpr uint32_t kMaxSampledTexturesPerShaderStage = 16;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#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)
|
||||
|
@ -108,6 +110,131 @@ namespace dawn_native { namespace vulkan {
|
|||
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 {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue