v3dv: Use common runtime vk_properties

Remove the v3dv_GetPhysicalDeviceProperties and the
v3dv_GetPhysicalDeviceProperties2 functions, replace them
by a private get_device_properties() called at device initialization
time.

(given the diff, the change is best viewed with --diff-algorithm=histogram)

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Tested-by: Roman Stratiienko <r.stratiienko@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26386>
This commit is contained in:
Oskar Viljasaar 2023-11-17 21:49:30 +02:00 committed by Marge Bot
parent 18c9b64e65
commit a5d59a50a9

View file

@ -773,6 +773,410 @@ v3dv_physical_device_init_disk_cache(struct v3dv_physical_device *device)
#endif
}
static void
get_device_properties(const struct v3dv_physical_device *device,
struct vk_properties *properties)
{
STATIC_ASSERT(MAX_SAMPLED_IMAGES + MAX_STORAGE_IMAGES + MAX_INPUT_ATTACHMENTS
<= V3D_MAX_TEXTURE_SAMPLERS);
STATIC_ASSERT(MAX_UNIFORM_BUFFERS >= MAX_DYNAMIC_UNIFORM_BUFFERS);
STATIC_ASSERT(MAX_STORAGE_BUFFERS >= MAX_DYNAMIC_STORAGE_BUFFERS);
const uint32_t page_size = 4096;
const uint64_t mem_size = compute_heap_size();
const uint32_t max_varying_components = 16 * 4;
const float v3d_point_line_granularity = 2.0f / (1 << V3D_COORD_SHIFT);
const uint32_t max_fb_size = V3D_MAX_IMAGE_DIMENSION;
const VkSampleCountFlags supported_sample_counts =
VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
const uint8_t max_rts = V3D_MAX_RENDER_TARGETS(device->devinfo.ver);
struct timespec clock_res;
clock_getres(CLOCK_MONOTONIC, &clock_res);
const float timestamp_period =
clock_res.tv_sec * 1000000000.0f + clock_res.tv_nsec;
/* We don't really have special restrictions for the maximum
* descriptors per set, other than maybe not exceeding the limits
* of addressable memory in a single allocation on either the host
* or the GPU. This will be a much larger limit than any of the
* per-stage limits already available in Vulkan though, so in practice,
* it is not expected to limit anything beyond what is already
* constrained through per-stage limits.
*/
const uint32_t max_host_descriptors =
(UINT32_MAX - sizeof(struct v3dv_descriptor_set)) /
sizeof(struct v3dv_descriptor);
const uint32_t max_gpu_descriptors =
(UINT32_MAX / v3dv_X(device, max_descriptor_bo_size)());
VkSubgroupFeatureFlags subgroup_ops = VK_SUBGROUP_FEATURE_BASIC_BIT;
if (device->devinfo.ver >= 71) {
subgroup_ops |= VK_SUBGROUP_FEATURE_BALLOT_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
VK_SUBGROUP_FEATURE_VOTE_BIT |
VK_SUBGROUP_FEATURE_QUAD_BIT;
}
#if DETECT_OS_ANDROID
/* Used to determine the sharedImage prop in
* VkPhysicalDevicePresentationPropertiesANDROID
*/
uint64_t front_rendering_usage = 0;
struct u_gralloc *gralloc = u_gralloc_create(U_GRALLOC_TYPE_AUTO);
if (gralloc != NULL) {
u_gralloc_get_front_rendering_usage(gralloc, &front_rendering_usage);
u_gralloc_destroy(&gralloc);
}
VkBool32 shared_image = front_rendering_usage ? VK_TRUE : VK_FALSE;
#endif
/* FIXME: this will probably require an in-depth review */
*properties = (struct vk_properties) {
/* VkPhysicalDeviceProperties, limits and sparse props below */
.apiVersion = V3DV_API_VERSION,
.driverVersion = vk_get_driver_version(),
.vendorID = v3dv_physical_device_vendor_id(device),
.deviceID = v3dv_physical_device_device_id(device),
.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
/* Vulkan 1.0 limits */
.maxImageDimension1D = V3D_MAX_IMAGE_DIMENSION,
.maxImageDimension2D = V3D_MAX_IMAGE_DIMENSION,
.maxImageDimension3D = V3D_MAX_IMAGE_DIMENSION,
.maxImageDimensionCube = V3D_MAX_IMAGE_DIMENSION,
.maxImageArrayLayers = V3D_MAX_ARRAY_LAYERS,
.maxTexelBufferElements = (1ul << 28),
.maxUniformBufferRange = V3D_MAX_BUFFER_RANGE,
.maxStorageBufferRange = V3D_MAX_BUFFER_RANGE,
.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
.maxMemoryAllocationCount = mem_size / page_size,
.maxSamplerAllocationCount = 64 * 1024,
.bufferImageGranularity = V3D_NON_COHERENT_ATOM_SIZE,
.sparseAddressSpaceSize = 0,
.maxBoundDescriptorSets = MAX_SETS,
.maxPerStageDescriptorSamplers = V3D_MAX_TEXTURE_SAMPLERS,
.maxPerStageDescriptorUniformBuffers = MAX_UNIFORM_BUFFERS,
.maxPerStageDescriptorStorageBuffers = MAX_STORAGE_BUFFERS,
.maxPerStageDescriptorSampledImages = MAX_SAMPLED_IMAGES,
.maxPerStageDescriptorStorageImages = MAX_STORAGE_IMAGES,
.maxPerStageDescriptorInputAttachments = MAX_INPUT_ATTACHMENTS,
.maxPerStageResources = 128,
/* Some of these limits are multiplied by 6 because they need to
* include all possible shader stages (even if not supported). See
* 'Required Limits' table in the Vulkan spec.
*/
.maxDescriptorSetSamplers = 6 * V3D_MAX_TEXTURE_SAMPLERS,
.maxDescriptorSetUniformBuffers = 6 * MAX_UNIFORM_BUFFERS,
.maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS,
.maxDescriptorSetStorageBuffers = 6 * MAX_STORAGE_BUFFERS,
.maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS,
.maxDescriptorSetSampledImages = 6 * MAX_SAMPLED_IMAGES,
.maxDescriptorSetStorageImages = 6 * MAX_STORAGE_IMAGES,
.maxDescriptorSetInputAttachments = MAX_INPUT_ATTACHMENTS,
/* Vertex limits */
.maxVertexInputAttributes = MAX_VERTEX_ATTRIBS,
.maxVertexInputBindings = MAX_VBS,
.maxVertexInputAttributeOffset = 0xffffffff,
.maxVertexInputBindingStride = 0xffffffff,
.maxVertexOutputComponents = max_varying_components,
/* Tessellation limits */
.maxTessellationGenerationLevel = 0,
.maxTessellationPatchSize = 0,
.maxTessellationControlPerVertexInputComponents = 0,
.maxTessellationControlPerVertexOutputComponents = 0,
.maxTessellationControlPerPatchOutputComponents = 0,
.maxTessellationControlTotalOutputComponents = 0,
.maxTessellationEvaluationInputComponents = 0,
.maxTessellationEvaluationOutputComponents = 0,
/* Geometry limits */
.maxGeometryShaderInvocations = 32,
.maxGeometryInputComponents = 64,
.maxGeometryOutputComponents = 64,
.maxGeometryOutputVertices = 256,
.maxGeometryTotalOutputComponents = 1024,
/* Fragment limits */
.maxFragmentInputComponents = max_varying_components,
.maxFragmentOutputAttachments = 4,
.maxFragmentDualSrcAttachments = 0,
.maxFragmentCombinedOutputResources = max_rts +
MAX_STORAGE_BUFFERS +
MAX_STORAGE_IMAGES,
/* Compute limits */
.maxComputeSharedMemorySize = 16384,
.maxComputeWorkGroupCount = { 65535, 65535, 65535 },
.maxComputeWorkGroupInvocations = 256,
.maxComputeWorkGroupSize = { 256, 256, 256 },
.subPixelPrecisionBits = V3D_COORD_SHIFT,
.subTexelPrecisionBits = 8,
.mipmapPrecisionBits = 8,
.maxDrawIndexedIndexValue = device->devinfo.ver >= 71 ?
0xffffffff : 0x00ffffff,
.maxDrawIndirectCount = 0x7fffffff,
.maxSamplerLodBias = 14.0f,
.maxSamplerAnisotropy = 16.0f,
.maxViewports = MAX_VIEWPORTS,
.maxViewportDimensions = { max_fb_size, max_fb_size },
.viewportBoundsRange = { -2.0 * max_fb_size,
2.0 * max_fb_size - 1 },
.viewportSubPixelBits = 0,
.minMemoryMapAlignment = page_size,
.minTexelBufferOffsetAlignment = V3D_TMU_TEXEL_ALIGN,
.minUniformBufferOffsetAlignment = 32,
.minStorageBufferOffsetAlignment = 32,
.minTexelOffset = -8,
.maxTexelOffset = 7,
.minTexelGatherOffset = -8,
.maxTexelGatherOffset = 7,
.minInterpolationOffset = -0.5,
.maxInterpolationOffset = 0.5,
.subPixelInterpolationOffsetBits = V3D_COORD_SHIFT,
.maxFramebufferWidth = max_fb_size,
.maxFramebufferHeight = max_fb_size,
.maxFramebufferLayers = 256,
.framebufferColorSampleCounts = supported_sample_counts,
.framebufferDepthSampleCounts = supported_sample_counts,
.framebufferStencilSampleCounts = supported_sample_counts,
.framebufferNoAttachmentsSampleCounts = supported_sample_counts,
.maxColorAttachments = max_rts,
.sampledImageColorSampleCounts = supported_sample_counts,
.sampledImageIntegerSampleCounts = supported_sample_counts,
.sampledImageDepthSampleCounts = supported_sample_counts,
.sampledImageStencilSampleCounts = supported_sample_counts,
.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
.maxSampleMaskWords = 1,
.timestampComputeAndGraphics = true,
.timestampPeriod = timestamp_period,
.maxClipDistances = 8,
.maxCullDistances = 0,
.maxCombinedClipAndCullDistances = 8,
.discreteQueuePriorities = 2,
.pointSizeRange = { v3d_point_line_granularity,
V3D_MAX_POINT_SIZE },
.lineWidthRange = { 1.0f, V3D_MAX_LINE_WIDTH },
.pointSizeGranularity = v3d_point_line_granularity,
.lineWidthGranularity = v3d_point_line_granularity,
.strictLines = true,
.standardSampleLocations = false,
.optimalBufferCopyOffsetAlignment = 32,
.optimalBufferCopyRowPitchAlignment = 32,
.nonCoherentAtomSize = V3D_NON_COHERENT_ATOM_SIZE,
/* Vulkan 1.0 sparse properties */
.sparseResidencyStandard2DBlockShape = false,
.sparseResidencyStandard2DMultisampleBlockShape = false,
.sparseResidencyStandard3DBlockShape = false,
.sparseResidencyAlignedMipSize = false,
.sparseResidencyNonResidentStrict = false,
/* Vulkan 1.1 properties*/
.deviceLUIDValid = false,
.subgroupSize = V3D_CHANNELS,
.subgroupSupportedStages = VK_SHADER_STAGE_COMPUTE_BIT |
VK_SHADER_STAGE_FRAGMENT_BIT,
.subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT,
.subgroupQuadOperationsInAllStages = false,
.pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES,
.maxMultiviewViewCount = MAX_MULTIVIEW_VIEW_COUNT,
.maxMultiviewInstanceIndex = UINT32_MAX - 1,
.protectedNoFault = false,
.maxPerSetDescriptors = MIN2(max_host_descriptors, max_gpu_descriptors),
/* Minimum required by the spec */
.maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE,
/* Vulkan 1.2 properties */
.driverID = VK_DRIVER_ID_MESA_V3DV,
.conformanceVersion = {
.major = 1,
.minor = 3,
.subminor = 6,
.patch = 1,
},
.supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
.supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
/* FIXME: if we want to support independentResolveNone then we would
* need to honor attachment load operations on resolve attachments,
* which we currently ignore because the resolve makes them irrelevant,
* as it unconditionally writes all pixels in the render area. However,
* with independentResolveNone, it is possible to have one aspect of a
* D/S resolve attachment stay unresolved, in which case the attachment
* load operation is relevant.
*
* NOTE: implementing attachment load for resolve attachments isn't
* immediately trivial because these attachments are not part of the
* framebuffer and therefore we can't use the same mechanism we use
* for framebuffer attachments. Instead, we should probably have to
* emit a meta operation for that right at the start of the render
* pass (or subpass).
*/
.independentResolveNone = false,
.independentResolve = false,
.maxTimelineSemaphoreValueDifference = UINT64_MAX,
.denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.shaderSignedZeroInfNanPreserveFloat16 = true,
.shaderSignedZeroInfNanPreserveFloat32 = true,
.shaderSignedZeroInfNanPreserveFloat64 = false,
.shaderDenormPreserveFloat16 = true,
.shaderDenormPreserveFloat32 = true,
.shaderDenormPreserveFloat64 = false,
.shaderDenormFlushToZeroFloat16 = false,
.shaderDenormFlushToZeroFloat32 = false,
.shaderDenormFlushToZeroFloat64 = false,
.shaderRoundingModeRTEFloat16 = true,
.shaderRoundingModeRTEFloat32 = true,
.shaderRoundingModeRTEFloat64 = false,
.shaderRoundingModeRTZFloat16 = false,
.shaderRoundingModeRTZFloat32 = false,
.shaderRoundingModeRTZFloat64 = false,
/* V3D doesn't support min/max filtering */
.filterMinmaxSingleComponentFormats = false,
.filterMinmaxImageComponentMapping = false,
.framebufferIntegerColorSampleCounts =
VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT,
/* Vulkan 1.3 properties */
.maxInlineUniformBlockSize = 4096,
.maxPerStageDescriptorInlineUniformBlocks = MAX_INLINE_UNIFORM_BUFFERS,
.maxDescriptorSetInlineUniformBlocks = MAX_INLINE_UNIFORM_BUFFERS,
.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks =
MAX_INLINE_UNIFORM_BUFFERS,
.maxDescriptorSetUpdateAfterBindInlineUniformBlocks =
MAX_INLINE_UNIFORM_BUFFERS,
.maxBufferSize = V3D_MAX_BUFFER_RANGE,
.storageTexelBufferOffsetAlignmentBytes = V3D_TMU_TEXEL_ALIGN,
.storageTexelBufferOffsetSingleTexelAlignment = false,
.uniformTexelBufferOffsetAlignmentBytes = V3D_TMU_TEXEL_ALIGN,
.uniformTexelBufferOffsetSingleTexelAlignment = false,
/* No native acceleration for integer dot product. We use NIR lowering. */
.integerDotProduct8BitUnsignedAccelerated = false,
.integerDotProduct8BitMixedSignednessAccelerated = false,
.integerDotProduct4x8BitPackedUnsignedAccelerated = false,
.integerDotProduct4x8BitPackedSignedAccelerated = false,
.integerDotProduct4x8BitPackedMixedSignednessAccelerated = false,
.integerDotProduct16BitUnsignedAccelerated = false,
.integerDotProduct16BitSignedAccelerated = false,
.integerDotProduct16BitMixedSignednessAccelerated = false,
.integerDotProduct32BitUnsignedAccelerated = false,
.integerDotProduct32BitSignedAccelerated = false,
.integerDotProduct32BitMixedSignednessAccelerated = false,
.integerDotProduct64BitUnsignedAccelerated = false,
.integerDotProduct64BitSignedAccelerated = false,
.integerDotProduct64BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating8BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated = false,
.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating16BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating32BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating64BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated = false,
/* VkPhysicalDeviceCustomBorderColorPropertiesEXT */
.maxCustomBorderColorSamplers = V3D_MAX_TEXTURE_SAMPLERS,
/* VkPhysicalDeviceProvokingVertexPropertiesEXT */
.provokingVertexModePerPipeline = true,
/* FIXME: update when supporting EXT_transform_feedback */
.transformFeedbackPreservesTriangleFanProvokingVertex = false,
/* VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT */
.maxVertexAttribDivisor = V3D_MAX_VERTEX_ATTRIB_DIVISOR,
.supportsNonZeroFirstInstance = true,
/* VkPhysicalDevicePerformanceQueryPropertiesKHR */
.allowCommandBufferQueryCopies = true,
#if DETECT_OS_ANDROID
/* VkPhysicalDevicePresentationPropertiesANDROID */
.sharedImage = shared_image,
#endif
/* VkPhysicalDeviceDrmPropertiesEXT */
.drmHasPrimary = device->has_primary,
.drmPrimaryMajor = (int64_t) major(device->primary_devid),
.drmPrimaryMinor = (int64_t) minor(device->primary_devid),
.drmHasRender = device->has_render,
.drmRenderMajor = (int64_t) major(device->render_devid),
.drmRenderMinor = (int64_t) minor(device->render_devid),
/* VkPhysicalDeviceLineRasterizationPropertiesEXT */
.lineSubPixelPrecisionBits = V3D_COORD_SHIFT,
/* VkPhysicalDevicePipelineRobustnessPropertiesEXT */
.defaultRobustnessStorageBuffers =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT,
.defaultRobustnessUniformBuffers =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT,
.defaultRobustnessVertexInputs =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT,
.defaultRobustnessImages =
VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT,
/* VkPhysicalDeviceMultiDrawPropertiesEXT */
.maxMultiDrawCount = 2048,
/* VkPhysicalDevicePCIBusInfoPropertiesEXT is not supported
* and is left unfilled
*/
/* VK_EXT_subgroup_size_control */
.minSubgroupSize = V3D_CHANNELS,
.maxSubgroupSize = V3D_CHANNELS,
.maxComputeWorkgroupSubgroups = 16, /* 256 / 16 */
.requiredSubgroupSizeStages = VK_SHADER_STAGE_COMPUTE_BIT,
.subgroupSupportedOperations = subgroup_ops,
};
/* VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT */
STATIC_ASSERT(sizeof(vk_shaderModuleIdentifierAlgorithmUUID) ==
sizeof(properties->shaderModuleIdentifierAlgorithmUUID));
memcpy(properties->shaderModuleIdentifierAlgorithmUUID,
vk_shaderModuleIdentifierAlgorithmUUID,
sizeof(properties->shaderModuleIdentifierAlgorithmUUID));
/* VkPhysicalDeviceProperties */
snprintf(properties->deviceName, sizeof(properties->deviceName),
"%s", device->name);
memcpy(properties->pipelineCacheUUID,
device->pipeline_cache_uuid, VK_UUID_SIZE);
/* Vulkan 1.1 properties */
memcpy(properties->deviceUUID, device->device_uuid, VK_UUID_SIZE);
memcpy(properties->driverUUID, device->driver_uuid, VK_UUID_SIZE);
/* Vulkan 1.2 properties */
memset(properties->driverName, 0, VK_MAX_DRIVER_NAME_SIZE);
snprintf(properties->driverName, VK_MAX_DRIVER_NAME_SIZE, "V3DV Mesa");
memset(properties->driverInfo, 0, VK_MAX_DRIVER_INFO_SIZE);
snprintf(properties->driverInfo, VK_MAX_DRIVER_INFO_SIZE,
"Mesa " PACKAGE_VERSION MESA_GIT_SHA1);
}
static VkResult
create_physical_device(struct v3dv_instance *instance,
drmDevicePtr gpu_device,
@ -968,6 +1372,7 @@ create_physical_device(struct v3dv_instance *instance,
get_device_extensions(device, &device->vk.supported_extensions);
get_features(device, &device->vk.supported_features);
get_device_properties(device, &device->vk.properties);
mtx_init(&device->mutex, mtx_plain);
@ -1097,465 +1502,6 @@ v3dv_physical_device_device_id(const struct v3dv_physical_device *dev)
#endif
}
VKAPI_ATTR void VKAPI_CALL
v3dv_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties *pProperties)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
STATIC_ASSERT(MAX_SAMPLED_IMAGES + MAX_STORAGE_IMAGES + MAX_INPUT_ATTACHMENTS
<= V3D_MAX_TEXTURE_SAMPLERS);
STATIC_ASSERT(MAX_UNIFORM_BUFFERS >= MAX_DYNAMIC_UNIFORM_BUFFERS);
STATIC_ASSERT(MAX_STORAGE_BUFFERS >= MAX_DYNAMIC_STORAGE_BUFFERS);
const uint32_t page_size = 4096;
const uint64_t mem_size = compute_heap_size();
const uint32_t max_varying_components = 16 * 4;
const float v3d_point_line_granularity = 2.0f / (1 << V3D_COORD_SHIFT);
const uint32_t max_fb_size = V3D_MAX_IMAGE_DIMENSION;
const VkSampleCountFlags supported_sample_counts =
VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
const uint8_t max_rts = V3D_MAX_RENDER_TARGETS(pdevice->devinfo.ver);
struct timespec clock_res;
clock_getres(CLOCK_MONOTONIC, &clock_res);
const float timestamp_period =
clock_res.tv_sec * 1000000000.0f + clock_res.tv_nsec;
/* FIXME: this will probably require an in-depth review */
VkPhysicalDeviceLimits limits = {
.maxImageDimension1D = V3D_MAX_IMAGE_DIMENSION,
.maxImageDimension2D = V3D_MAX_IMAGE_DIMENSION,
.maxImageDimension3D = V3D_MAX_IMAGE_DIMENSION,
.maxImageDimensionCube = V3D_MAX_IMAGE_DIMENSION,
.maxImageArrayLayers = V3D_MAX_ARRAY_LAYERS,
.maxTexelBufferElements = (1ul << 28),
.maxUniformBufferRange = V3D_MAX_BUFFER_RANGE,
.maxStorageBufferRange = V3D_MAX_BUFFER_RANGE,
.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
.maxMemoryAllocationCount = mem_size / page_size,
.maxSamplerAllocationCount = 64 * 1024,
.bufferImageGranularity = V3D_NON_COHERENT_ATOM_SIZE,
.sparseAddressSpaceSize = 0,
.maxBoundDescriptorSets = MAX_SETS,
.maxPerStageDescriptorSamplers = V3D_MAX_TEXTURE_SAMPLERS,
.maxPerStageDescriptorUniformBuffers = MAX_UNIFORM_BUFFERS,
.maxPerStageDescriptorStorageBuffers = MAX_STORAGE_BUFFERS,
.maxPerStageDescriptorSampledImages = MAX_SAMPLED_IMAGES,
.maxPerStageDescriptorStorageImages = MAX_STORAGE_IMAGES,
.maxPerStageDescriptorInputAttachments = MAX_INPUT_ATTACHMENTS,
.maxPerStageResources = 128,
/* Some of these limits are multiplied by 6 because they need to
* include all possible shader stages (even if not supported). See
* 'Required Limits' table in the Vulkan spec.
*/
.maxDescriptorSetSamplers = 6 * V3D_MAX_TEXTURE_SAMPLERS,
.maxDescriptorSetUniformBuffers = 6 * MAX_UNIFORM_BUFFERS,
.maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS,
.maxDescriptorSetStorageBuffers = 6 * MAX_STORAGE_BUFFERS,
.maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS,
.maxDescriptorSetSampledImages = 6 * MAX_SAMPLED_IMAGES,
.maxDescriptorSetStorageImages = 6 * MAX_STORAGE_IMAGES,
.maxDescriptorSetInputAttachments = MAX_INPUT_ATTACHMENTS,
/* Vertex limits */
.maxVertexInputAttributes = MAX_VERTEX_ATTRIBS,
.maxVertexInputBindings = MAX_VBS,
.maxVertexInputAttributeOffset = 0xffffffff,
.maxVertexInputBindingStride = 0xffffffff,
.maxVertexOutputComponents = max_varying_components,
/* Tessellation limits */
.maxTessellationGenerationLevel = 0,
.maxTessellationPatchSize = 0,
.maxTessellationControlPerVertexInputComponents = 0,
.maxTessellationControlPerVertexOutputComponents = 0,
.maxTessellationControlPerPatchOutputComponents = 0,
.maxTessellationControlTotalOutputComponents = 0,
.maxTessellationEvaluationInputComponents = 0,
.maxTessellationEvaluationOutputComponents = 0,
/* Geometry limits */
.maxGeometryShaderInvocations = 32,
.maxGeometryInputComponents = 64,
.maxGeometryOutputComponents = 64,
.maxGeometryOutputVertices = 256,
.maxGeometryTotalOutputComponents = 1024,
/* Fragment limits */
.maxFragmentInputComponents = max_varying_components,
.maxFragmentOutputAttachments = 4,
.maxFragmentDualSrcAttachments = 0,
.maxFragmentCombinedOutputResources = max_rts +
MAX_STORAGE_BUFFERS +
MAX_STORAGE_IMAGES,
/* Compute limits */
.maxComputeSharedMemorySize = 16384,
.maxComputeWorkGroupCount = { 65535, 65535, 65535 },
.maxComputeWorkGroupInvocations = 256,
.maxComputeWorkGroupSize = { 256, 256, 256 },
.subPixelPrecisionBits = V3D_COORD_SHIFT,
.subTexelPrecisionBits = 8,
.mipmapPrecisionBits = 8,
.maxDrawIndexedIndexValue = pdevice->devinfo.ver >= 71 ?
0xffffffff : 0x00ffffff,
.maxDrawIndirectCount = 0x7fffffff,
.maxSamplerLodBias = 14.0f,
.maxSamplerAnisotropy = 16.0f,
.maxViewports = MAX_VIEWPORTS,
.maxViewportDimensions = { max_fb_size, max_fb_size },
.viewportBoundsRange = { -2.0 * max_fb_size,
2.0 * max_fb_size - 1 },
.viewportSubPixelBits = 0,
.minMemoryMapAlignment = page_size,
.minTexelBufferOffsetAlignment = V3D_TMU_TEXEL_ALIGN,
.minUniformBufferOffsetAlignment = 32,
.minStorageBufferOffsetAlignment = 32,
.minTexelOffset = -8,
.maxTexelOffset = 7,
.minTexelGatherOffset = -8,
.maxTexelGatherOffset = 7,
.minInterpolationOffset = -0.5,
.maxInterpolationOffset = 0.5,
.subPixelInterpolationOffsetBits = V3D_COORD_SHIFT,
.maxFramebufferWidth = max_fb_size,
.maxFramebufferHeight = max_fb_size,
.maxFramebufferLayers = 256,
.framebufferColorSampleCounts = supported_sample_counts,
.framebufferDepthSampleCounts = supported_sample_counts,
.framebufferStencilSampleCounts = supported_sample_counts,
.framebufferNoAttachmentsSampleCounts = supported_sample_counts,
.maxColorAttachments = max_rts,
.sampledImageColorSampleCounts = supported_sample_counts,
.sampledImageIntegerSampleCounts = supported_sample_counts,
.sampledImageDepthSampleCounts = supported_sample_counts,
.sampledImageStencilSampleCounts = supported_sample_counts,
.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
.maxSampleMaskWords = 1,
.timestampComputeAndGraphics = true,
.timestampPeriod = timestamp_period,
.maxClipDistances = 8,
.maxCullDistances = 0,
.maxCombinedClipAndCullDistances = 8,
.discreteQueuePriorities = 2,
.pointSizeRange = { v3d_point_line_granularity,
V3D_MAX_POINT_SIZE },
.lineWidthRange = { 1.0f, V3D_MAX_LINE_WIDTH },
.pointSizeGranularity = v3d_point_line_granularity,
.lineWidthGranularity = v3d_point_line_granularity,
.strictLines = true,
.standardSampleLocations = false,
.optimalBufferCopyOffsetAlignment = 32,
.optimalBufferCopyRowPitchAlignment = 32,
.nonCoherentAtomSize = V3D_NON_COHERENT_ATOM_SIZE,
};
*pProperties = (VkPhysicalDeviceProperties) {
.apiVersion = V3DV_API_VERSION,
.driverVersion = vk_get_driver_version(),
.vendorID = v3dv_physical_device_vendor_id(pdevice),
.deviceID = v3dv_physical_device_device_id(pdevice),
.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
.limits = limits,
.sparseProperties = { 0 },
};
snprintf(pProperties->deviceName, sizeof(pProperties->deviceName),
"%s", pdevice->name);
memcpy(pProperties->pipelineCacheUUID,
pdevice->pipeline_cache_uuid, VK_UUID_SIZE);
}
VKAPI_ATTR void VKAPI_CALL
v3dv_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2 *pProperties)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
v3dv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
/* We don't really have special restrictions for the maximum
* descriptors per set, other than maybe not exceeding the limits
* of addressable memory in a single allocation on either the host
* or the GPU. This will be a much larger limit than any of the
* per-stage limits already available in Vulkan though, so in practice,
* it is not expected to limit anything beyond what is already
* constrained through per-stage limits.
*/
const uint32_t max_host_descriptors =
(UINT32_MAX - sizeof(struct v3dv_descriptor_set)) /
sizeof(struct v3dv_descriptor);
const uint32_t max_gpu_descriptors =
(UINT32_MAX / v3dv_X(pdevice, max_descriptor_bo_size)());
VkPhysicalDeviceVulkan13Properties vk13 = {
.maxInlineUniformBlockSize = 4096,
.maxPerStageDescriptorInlineUniformBlocks = MAX_INLINE_UNIFORM_BUFFERS,
.maxDescriptorSetInlineUniformBlocks = MAX_INLINE_UNIFORM_BUFFERS,
.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks =
MAX_INLINE_UNIFORM_BUFFERS,
.maxDescriptorSetUpdateAfterBindInlineUniformBlocks =
MAX_INLINE_UNIFORM_BUFFERS,
.maxBufferSize = V3D_MAX_BUFFER_RANGE,
.storageTexelBufferOffsetAlignmentBytes = V3D_TMU_TEXEL_ALIGN,
.storageTexelBufferOffsetSingleTexelAlignment = false,
.uniformTexelBufferOffsetAlignmentBytes = V3D_TMU_TEXEL_ALIGN,
.uniformTexelBufferOffsetSingleTexelAlignment = false,
/* No native acceleration for integer dot product. We use NIR lowering. */
.integerDotProduct8BitUnsignedAccelerated = false,
.integerDotProduct8BitMixedSignednessAccelerated = false,
.integerDotProduct4x8BitPackedUnsignedAccelerated = false,
.integerDotProduct4x8BitPackedSignedAccelerated = false,
.integerDotProduct4x8BitPackedMixedSignednessAccelerated = false,
.integerDotProduct16BitUnsignedAccelerated = false,
.integerDotProduct16BitSignedAccelerated = false,
.integerDotProduct16BitMixedSignednessAccelerated = false,
.integerDotProduct32BitUnsignedAccelerated = false,
.integerDotProduct32BitSignedAccelerated = false,
.integerDotProduct32BitMixedSignednessAccelerated = false,
.integerDotProduct64BitUnsignedAccelerated = false,
.integerDotProduct64BitSignedAccelerated = false,
.integerDotProduct64BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating8BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated = false,
.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating16BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating32BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated = false,
.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated = false,
.integerDotProductAccumulatingSaturating64BitSignedAccelerated = false,
.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated = false,
/* VK_EXT_subgroup_size_control */
.minSubgroupSize = V3D_CHANNELS,
.maxSubgroupSize = V3D_CHANNELS,
.maxComputeWorkgroupSubgroups = 16, /* 256 / 16 */
.requiredSubgroupSizeStages = VK_SHADER_STAGE_COMPUTE_BIT,
};
VkPhysicalDeviceVulkan12Properties vk12 = {
.driverID = VK_DRIVER_ID_MESA_V3DV,
.conformanceVersion = {
.major = 1,
.minor = 3,
.subminor = 6,
.patch = 1,
},
.supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
.supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
/* FIXME: if we want to support independentResolveNone then we would
* need to honor attachment load operations on resolve attachments,
* which we currently ignore because the resolve makes them irrelevant,
* as it unconditionally writes all pixels in the render area. However,
* with independentResolveNone, it is possible to have one aspect of a
* D/S resolve attachment stay unresolved, in which case the attachment
* load operation is relevant.
*
* NOTE: implementing attachment load for resolve attachments isn't
* immediately trivial because these attachments are not part of the
* framebuffer and therefore we can't use the same mechanism we use
* for framebuffer attachments. Instead, we should probably have to
* emit a meta operation for that right at the start of the render
* pass (or subpass).
*/
.independentResolveNone = false,
.independentResolve = false,
.maxTimelineSemaphoreValueDifference = UINT64_MAX,
.denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.shaderSignedZeroInfNanPreserveFloat16 = true,
.shaderSignedZeroInfNanPreserveFloat32 = true,
.shaderSignedZeroInfNanPreserveFloat64 = false,
.shaderDenormPreserveFloat16 = true,
.shaderDenormPreserveFloat32 = true,
.shaderDenormPreserveFloat64 = false,
.shaderDenormFlushToZeroFloat16 = false,
.shaderDenormFlushToZeroFloat32 = false,
.shaderDenormFlushToZeroFloat64 = false,
.shaderRoundingModeRTEFloat16 = true,
.shaderRoundingModeRTEFloat32 = true,
.shaderRoundingModeRTEFloat64 = false,
.shaderRoundingModeRTZFloat16 = false,
.shaderRoundingModeRTZFloat32 = false,
.shaderRoundingModeRTZFloat64 = false,
/* V3D doesn't support min/max filtering */
.filterMinmaxSingleComponentFormats = false,
.filterMinmaxImageComponentMapping = false,
.framebufferIntegerColorSampleCounts =
VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT,
};
memset(vk12.driverName, 0, VK_MAX_DRIVER_NAME_SIZE);
snprintf(vk12.driverName, VK_MAX_DRIVER_NAME_SIZE, "V3DV Mesa");
memset(vk12.driverInfo, 0, VK_MAX_DRIVER_INFO_SIZE);
snprintf(vk12.driverInfo, VK_MAX_DRIVER_INFO_SIZE,
"Mesa " PACKAGE_VERSION MESA_GIT_SHA1);
VkSubgroupFeatureFlags subgroup_ops = VK_SUBGROUP_FEATURE_BASIC_BIT;
if (pdevice->devinfo.ver >= 71) {
subgroup_ops |= VK_SUBGROUP_FEATURE_BALLOT_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
VK_SUBGROUP_FEATURE_VOTE_BIT |
VK_SUBGROUP_FEATURE_QUAD_BIT;
}
VkPhysicalDeviceVulkan11Properties vk11 = {
.deviceLUIDValid = false,
.subgroupSize = V3D_CHANNELS,
.subgroupSupportedStages = VK_SHADER_STAGE_COMPUTE_BIT |
VK_SHADER_STAGE_FRAGMENT_BIT,
.subgroupSupportedOperations = subgroup_ops,
.subgroupQuadOperationsInAllStages = false,
.pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES,
.maxMultiviewViewCount = MAX_MULTIVIEW_VIEW_COUNT,
.maxMultiviewInstanceIndex = UINT32_MAX - 1,
.protectedNoFault = false,
.maxPerSetDescriptors = MIN2(max_host_descriptors, max_gpu_descriptors),
/* Minimum required by the spec */
.maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE,
};
memcpy(vk11.deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
memcpy(vk11.driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
vk_foreach_struct(ext, pProperties->pNext) {
if (vk_get_physical_device_core_1_1_property_ext(ext, &vk11))
continue;
if (vk_get_physical_device_core_1_2_property_ext(ext, &vk12))
continue;
if (vk_get_physical_device_core_1_3_property_ext(ext, &vk13))
continue;
switch (ext->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
VkPhysicalDeviceCustomBorderColorPropertiesEXT *props =
(VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;
props->maxCustomBorderColorSamplers = V3D_MAX_TEXTURE_SAMPLERS;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {
VkPhysicalDeviceProvokingVertexPropertiesEXT *props =
(VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext;
props->provokingVertexModePerPipeline = true;
/* FIXME: update when supporting EXT_transform_feedback */
props->transformFeedbackPreservesTriangleFanProvokingVertex = false;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
props->maxVertexAttribDivisor = V3D_MAX_VERTEX_ATTRIB_DIVISOR;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_KHR: {
VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR *props =
(VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR *)ext;
props->maxVertexAttribDivisor = V3D_MAX_VERTEX_ATTRIB_DIVISOR;
props->supportsNonZeroFirstInstance = true;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR : {
VkPhysicalDevicePerformanceQueryPropertiesKHR *props =
(VkPhysicalDevicePerformanceQueryPropertiesKHR *)ext;
props->allowCommandBufferQueryCopies = true;
break;
}
#if DETECT_OS_ANDROID
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID: {
VkPhysicalDevicePresentationPropertiesANDROID *props =
(VkPhysicalDevicePresentationPropertiesANDROID *)ext;
uint64_t front_rendering_usage = 0;
struct u_gralloc *gralloc = u_gralloc_create(U_GRALLOC_TYPE_AUTO);
if (gralloc != NULL) {
u_gralloc_get_front_rendering_usage(gralloc, &front_rendering_usage);
u_gralloc_destroy(&gralloc);
}
props->sharedImage = front_rendering_usage ? VK_TRUE
: VK_FALSE;
break;
}
#pragma GCC diagnostic pop
#endif
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT: {
VkPhysicalDeviceDrmPropertiesEXT *props =
(VkPhysicalDeviceDrmPropertiesEXT *)ext;
props->hasPrimary = pdevice->has_primary;
if (props->hasPrimary) {
props->primaryMajor = (int64_t) major(pdevice->primary_devid);
props->primaryMinor = (int64_t) minor(pdevice->primary_devid);
}
props->hasRender = pdevice->has_render;
if (props->hasRender) {
props->renderMajor = (int64_t) major(pdevice->render_devid);
props->renderMinor = (int64_t) minor(pdevice->render_devid);
}
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
VkPhysicalDeviceLineRasterizationPropertiesEXT *props =
(VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
props->lineSubPixelPrecisionBits = V3D_COORD_SHIFT;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT:
/* Do nothing, not even logging. This is a non-PCI device, so we will
* never provide this extension.
*/
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT: {
VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT *props =
(VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT *)ext;
STATIC_ASSERT(sizeof(vk_shaderModuleIdentifierAlgorithmUUID) ==
sizeof(props->shaderModuleIdentifierAlgorithmUUID));
memcpy(props->shaderModuleIdentifierAlgorithmUUID,
vk_shaderModuleIdentifierAlgorithmUUID,
sizeof(props->shaderModuleIdentifierAlgorithmUUID));
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT: {
VkPhysicalDevicePipelineRobustnessPropertiesEXT *props =
(VkPhysicalDevicePipelineRobustnessPropertiesEXT *)ext;
props->defaultRobustnessStorageBuffers =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT;
props->defaultRobustnessUniformBuffers =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT;
props->defaultRobustnessVertexInputs =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT;
props->defaultRobustnessImages =
VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {
VkPhysicalDeviceMultiDrawPropertiesEXT *properties =
(VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;
properties->maxMultiDrawCount = 2048;
break;
}
default:
v3dv_debug_ignored_stype(ext->sType);
break;
}
}
}
/* We support exactly one queue family. */
static const VkQueueFamilyProperties
v3dv_queue_family_properties = {