diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index c83bb17b68f..001f1e084f3 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -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 = {