Xclipse layer: copy any device-chain structure the headers define

The chain copy that clears the emulated textureCompressionBC only knew a
handful of structure sizes, so a valid chain such as
VkPhysicalDeviceTimelineSemaphoreFeatures -> VkPhysicalDeviceFeatures2 was
passed on unchanged and the compat layer refused the bit. Size every
structure that may extend VkDeviceCreateInfo from a table generated from the
Vulkan registry (gen_device_chain.py, Vulkan-Headers 1.3.275, the headers
the build compiles with), and copy onto the heap instead of a fixed buffer.
Only a structure newer than those headers still passes the chain unchanged.

Add a regression test that runs the layer between a simulated loader and a
mock driver: the timeline-semaphore chain, pEnabledFeatures, an unknown
structure, the caller's structures left untouched, per-device YCbCr sampler
tracking with handle reuse, and the KHR calibrated-timestamp forwarding. CI
installs libvulkan-dev for it.
This commit is contained in:
Stefan Zijlstra committed 2026-10-12 07:32:52 +02:00
1 parent db034d6598
commit 7ef64474e3
6 files changed
+527 -27

No files matched your search

+4 -1
View File
@@ -503,7 +503,10 @@ jobs:
if-no-files-found: ignore
- name: Steam import and game environment tests
run: python3 -m unittest discover -s tools/tests -p 'test_*.py'
run: |
# The Xclipse layer regression test compiles the layer against the distribution's headers.
sudo apt-get update -qq && sudo apt-get install -y -qq libvulkan-dev >/dev/null
python3 -m unittest discover -s tools/tests -p 'test_*.py'
- name: Unit tests
run: ./gradlew testReleaseUnitTest --console=plain -PndkVersion="$NDK_VERSION"
@@ -0,0 +1,180 @@
/* Generated by gen_device_chain.py from Vulkan-Headers 1.3.275; do not edit. */
DEVICE_CHAIN(VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT, VkDeviceDeviceMemoryReportCreateInfoEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV, VkDeviceDiagnosticsConfigCreateInfoNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, VkDeviceGroupDeviceCreateInfo)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD, VkDeviceMemoryOverallocationCreateInfoAMD)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, VkDevicePrivateDataCreateInfo)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_DEVICE_QUEUE_SHADER_CORE_CONTROL_CREATE_INFO_ARM, VkDeviceQueueShaderCoreControlCreateInfoARM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, VkPhysicalDevice16BitStorageFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT, VkPhysicalDevice4444FormatsFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, VkPhysicalDevice8BitStorageFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, VkPhysicalDeviceAccelerationStructureFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT, VkPhysicalDeviceAddressBindingReportFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC, VkPhysicalDeviceAmigoProfilingFeaturesSEC)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, VkPhysicalDeviceASTCDecodeFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT, VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT, VkPhysicalDeviceBorderColorSwizzleFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, VkPhysicalDeviceBufferDeviceAddressFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, VkPhysicalDeviceBufferDeviceAddressFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI, VkPhysicalDeviceClusterCullingShaderFeaturesHUAWEI)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, VkPhysicalDeviceCoherentMemoryFeaturesAMD)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, VkPhysicalDeviceColorWriteEnableFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV, VkPhysicalDeviceComputeShaderDerivativesFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, VkPhysicalDeviceConditionalRenderingFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR, VkPhysicalDeviceCooperativeMatrixFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, VkPhysicalDeviceCooperativeMatrixFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV, VkPhysicalDeviceCopyMemoryIndirectFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, VkPhysicalDeviceCornerSampledImageFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, VkPhysicalDeviceCoverageReductionModeFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM, VkPhysicalDeviceCubicClampFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM, VkPhysicalDeviceCubicWeightsFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_FEATURES_NV, VkPhysicalDeviceCudaKernelLaunchFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT, VkPhysicalDeviceCustomBorderColorFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_BIAS_CONTROL_FEATURES_EXT, VkPhysicalDeviceDepthBiasControlFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_EXT, VkPhysicalDeviceDepthClampZeroOneFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT, VkPhysicalDeviceDepthClipControlFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, VkPhysicalDeviceDepthClipEnableFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT, VkPhysicalDeviceDescriptorBufferFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, VkPhysicalDeviceDescriptorIndexingFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV, VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE, VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV, VkPhysicalDeviceDeviceGeneratedCommandsComputeFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV, VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, VkPhysicalDeviceDeviceMemoryReportFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV, VkPhysicalDeviceDiagnosticsConfigFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, VkPhysicalDeviceDynamicRenderingFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT, VkPhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, VkPhysicalDeviceExclusiveScissorFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, VkPhysicalDeviceExtendedDynamicState2FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT, VkPhysicalDeviceExtendedDynamicState3FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT, VkPhysicalDeviceExtendedDynamicStateFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_FEATURES_NV, VkPhysicalDeviceExtendedSparseAddressSpaceFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV, VkPhysicalDeviceExternalMemoryRDMAFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT, VkPhysicalDeviceFaultFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, VkPhysicalDeviceFeatures2)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT, VkPhysicalDeviceFragmentDensityMap2FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, VkPhysicalDeviceFragmentDensityMapFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM, VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV, VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, VkPhysicalDeviceFragmentShadingRateFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAME_BOUNDARY_FEATURES_EXT, VkPhysicalDeviceFrameBoundaryFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT, VkPhysicalDeviceHostImageCopyFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, VkPhysicalDeviceHostQueryResetFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, VkPhysicalDeviceImagelessFramebufferFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, VkPhysicalDeviceImage2DViewOf3DFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT, VkPhysicalDeviceImageCompressionControlFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT, VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_2_FEATURES_QCOM, VkPhysicalDeviceImageProcessing2FeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM, VkPhysicalDeviceImageProcessingFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, VkPhysicalDeviceImageRobustnessFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT, VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT, VkPhysicalDeviceImageViewMinLodFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, VkPhysicalDeviceIndexTypeUint8FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV, VkPhysicalDeviceInheritedViewportScissorFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, VkPhysicalDeviceInlineUniformBlockFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI, VkPhysicalDeviceInvocationMaskFeaturesHUAWEI)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT, VkPhysicalDeviceLegacyDitheringFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV, VkPhysicalDeviceLinearColorAttachmentFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, VkPhysicalDeviceLineRasterizationFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, VkPhysicalDeviceMaintenance4Features)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES_KHR, VkPhysicalDeviceMaintenance5FeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES_KHR, VkPhysicalDeviceMaintenance6FeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_NV, VkPhysicalDeviceMemoryDecompressionFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, VkPhysicalDeviceMemoryPriorityFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, VkPhysicalDeviceMeshShaderFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, VkPhysicalDeviceMeshShaderFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VkPhysicalDeviceMultiviewFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM, VkPhysicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM, VkPhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT, VkPhysicalDeviceMultiDrawFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT, VkPhysicalDeviceNestedCommandBufferFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT, VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT, VkPhysicalDeviceOpacityMicromapFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV, VkPhysicalDeviceOpticalFlowFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT, VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, VkPhysicalDevicePerformanceQueryFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PER_STAGE_DESCRIPTOR_SET_FEATURES_NV, VkPhysicalDevicePerStageDescriptorSetFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, VkPhysicalDevicePipelineCreationCacheControlFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT, VkPhysicalDevicePipelineLibraryGroupHandlesFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT, VkPhysicalDevicePipelinePropertiesFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT, VkPhysicalDevicePipelineProtectedAccessFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT, VkPhysicalDevicePipelineRobustnessFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV, VkPhysicalDevicePresentBarrierFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR, VkPhysicalDevicePresentIdFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, VkPhysicalDevicePresentWaitFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT, VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, VkPhysicalDevicePrivateDataFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, VkPhysicalDeviceProtectedMemoryFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT, VkPhysicalDeviceProvokingVertexFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR, VkPhysicalDeviceRayQueryFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV, VkPhysicalDeviceRayTracingInvocationReorderFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR, VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, VkPhysicalDeviceRayTracingMotionBlurFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, VkPhysicalDeviceRayTracingPipelineFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR, VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG, VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM, VkPhysicalDeviceRenderPassStripedFeaturesARM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT, VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT, VkPhysicalDeviceRobustness2FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, VkPhysicalDeviceSamplerYcbcrConversionFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, VkPhysicalDeviceScalarBlockLayoutFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM, VkPhysicalDeviceSchedulingControlsFeaturesARM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, VkPhysicalDeviceShaderAtomicInt64Features)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, VkPhysicalDeviceShaderClockFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM, VkPhysicalDeviceShaderCoreBuiltinsFeaturesARM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VkPhysicalDeviceShaderDrawParametersFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD, VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, VkPhysicalDeviceShaderFloat16Int8Features)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, VkPhysicalDeviceShaderImageFootprintFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, VkPhysicalDeviceShaderIntegerDotProductFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT, VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT, VkPhysicalDeviceShaderObjectFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, VkPhysicalDeviceShaderSMBuiltinsFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, VkPhysicalDeviceShaderTerminateInvocationFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT, VkPhysicalDeviceShaderTileImageFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV, VkPhysicalDeviceShadingRateImageFeaturesNV)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, VkPhysicalDeviceSubgroupSizeControlFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT, VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI, VkPhysicalDeviceSubpassShadingFeaturesHUAWEI)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, VkPhysicalDeviceSynchronization2Features)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, VkPhysicalDeviceTextureCompressionASTCHDRFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM, VkPhysicalDeviceTilePropertiesFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, VkPhysicalDeviceTimelineSemaphoreFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, VkPhysicalDeviceTransformFeedbackFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, VkPhysicalDeviceUniformBufferStandardLayoutFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VkPhysicalDeviceVariablePointersFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR, VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR, VkPhysicalDeviceVideoMaintenance1FeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, VkPhysicalDeviceVulkan11Features)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, VkPhysicalDeviceVulkan12Features)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, VkPhysicalDeviceVulkan13Features)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, VkPhysicalDeviceVulkanMemoryModelFeatures)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT, VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM, VkPhysicalDeviceYcbcrDegammaFeaturesQCOM)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, VkPhysicalDeviceYcbcrImageArraysFeaturesEXT)
DEVICE_CHAIN(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures)
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""Generate device_chain.inc: the structures a VkDeviceCreateInfo chain may hold, with their sizes.
The Xclipse layer copies the chain ahead of the VkPhysicalDeviceFeatures2 it edits, and copying a
structure needs its size. Run against the Vulkan-Headers release the build compiles with (Ubuntu
24.04's libvulkan-dev is 1.3.275):
gen_device_chain.py Vulkan-Headers/registry/vk.xml Vulkan-Headers/include/vulkan/vulkan_core.h
"""
import re
import sys
import xml.etree.ElementTree as ElementTree
from pathlib import Path
def main(registry, core_header, output):
core = Path(core_header).read_text()
root = ElementTree.parse(registry).getroot()
entries = []
for struct in root.iter("type"):
if struct.get("category") != "struct" or struct.get("alias"):
continue
if "VkDeviceCreateInfo" not in (struct.get("structextends") or "").split(","):
continue
name = struct.get("name")
stype = next((member.get("values") for member in struct.findall("member")
if member.findtext("name") == "sType"), None)
# Platform and provisional structures live outside vulkan_core.h; the layer never builds them.
if not stype or not re.search(r"\}\s*" + re.escape(name) + r"\s*;", core):
continue
entries.append((stype, name))
version = re.search(r"#define VK_HEADER_VERSION (\d+)", core).group(1)
lines = ["/* Generated by gen_device_chain.py from Vulkan-Headers 1.3.%s; do not edit. */" % version]
lines += ["DEVICE_CHAIN(%s, %s)" % entry for entry in sorted(entries)]
Path(output).write_text("\n".join(lines) + "\n")
print("%d structures" % len(entries))
if __name__ == "__main__":
if len(sys.argv) not in (3, 4):
sys.exit(__doc__)
main(sys.argv[1], sys.argv[2], sys.argv[3] if len(sys.argv) == 4 else
Path(__file__).with_name("device_chain.inc"))
+36 -26
View File
@@ -219,50 +219,56 @@ static void VKAPI_CALL get_format_properties2(VkPhysicalDevice physical, VkForma
/* ---- device ---- */
/* Structures that may precede VkPhysicalDeviceFeatures2 in a device chain, by size. Only these are
* copied; a chain with anything else first is passed on unchanged. */
static size_t copyable_size(VkStructureType type) {
/* The size of each structure a VkDeviceCreateInfo chain may hold (device_chain.inc, generated from the
* Vulkan registry), plus the loader's own; 0 for anything else. */
static size_t chain_size(VkStructureType type) {
switch (type) {
#define DEVICE_CHAIN(stype, name) case stype: return sizeof(name);
#include "device_chain.inc"
#undef DEVICE_CHAIN
case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO: return sizeof(VkLayerDeviceCreateInfo);
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: return sizeof(VkPhysicalDeviceFeatures2);
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: return sizeof(VkPhysicalDeviceVulkan11Features);
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: return sizeof(VkPhysicalDeviceVulkan12Features);
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: return sizeof(VkPhysicalDeviceVulkan13Features);
case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO: return sizeof(VkDeviceGroupDeviceCreateInfo);
case VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO: return sizeof(VkDevicePrivateDataCreateInfo);
default: return 0;
}
}
#define MAX_COPIED 16
#define COPY_SIZE 512
_Static_assert(sizeof(VkPhysicalDeviceVulkan12Features) <= COPY_SIZE &&
sizeof(VkPhysicalDeviceVulkan13Features) <= COPY_SIZE &&
sizeof(VkLayerDeviceCreateInfo) <= COPY_SIZE, "COPY_SIZE too small");
struct chain_copy { _Alignas(16) unsigned char nodes[MAX_COPIED][COPY_SIZE]; };
struct chain_copy { void **nodes; size_t count; };
static void free_chain_copy(struct chain_copy *copy) {
for (size_t i = 0; i < copy->count; i++) free(copy->nodes[i]);
free(copy->nodes);
copy->nodes = NULL;
copy->count = 0;
}
/* The chain with textureCompressionBC cleared in a copy of the VkPhysicalDeviceFeatures2 that enables
* it: every structure up to it is copied into [copy], the rest is shared. The caller's structures are
* never written. Returns [head] when nothing needs clearing or a structure ahead of it is unknown. */
static const void *chain_without_bc(const void *head, struct chain_copy *copy) {
* never written. *head_out stays [head] when nothing needs clearing, or when a structure ahead of it
* is unknown to this build (newer than its Vulkan headers); the compat layer then refuses the bit. */
static VkResult chain_without_bc(const void *head, struct chain_copy *copy, const void **head_out) {
*head_out = head;
const VkBaseInStructure *target = NULL;
int count = 0;
size_t count = 0;
for (const VkBaseInStructure *p = head; p && !target; p = p->pNext) {
if (!copyable_size(p->sType) || ++count > MAX_COPIED) return head;
if (!chain_size(p->sType)) return VK_SUCCESS;
count++;
if (p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 &&
((const VkPhysicalDeviceFeatures2 *)p)->features.textureCompressionBC) target = p;
}
if (!target) return head;
if (!target) return VK_SUCCESS;
if (!(copy->nodes = calloc(count, sizeof(*copy->nodes)))) return VK_ERROR_OUT_OF_HOST_MEMORY;
VkBaseOutStructure *first = NULL, *last = NULL;
int index = 0;
for (const VkBaseInStructure *p = head; ; p = p->pNext) {
VkBaseOutStructure *node = (VkBaseOutStructure *)copy->nodes[index++];
memcpy(node, p, copyable_size(p->sType));
size_t size = chain_size(p->sType);
VkBaseOutStructure *node = malloc(size);
if (!node) { free_chain_copy(copy); return VK_ERROR_OUT_OF_HOST_MEMORY; }
copy->nodes[copy->count++] = node;
memcpy(node, p, size);
if (last) last->pNext = node; else first = node;
last = node;
if (p == target) {
((VkPhysicalDeviceFeatures2 *)node)->features.textureCompressionBC = VK_FALSE;
return first; /* its pNext still leads to the caller's remaining structures */
*head_out = first; /* its pNext still leads to the caller's remaining structures */
return VK_SUCCESS;
}
}
}
@@ -288,9 +294,13 @@ static VkResult VKAPI_CALL create_device(VkPhysicalDevice physical, const VkDevi
plain_features.textureCompressionBC = VK_FALSE;
patched.pEnabledFeatures = &plain_features;
}
struct chain_copy copy;
if (strip_bc) patched.pNext = chain_without_bc(info->pNext, &copy);
struct chain_copy copy = {0};
if (strip_bc) {
VkResult copied = chain_without_bc(info->pNext, &copy, &patched.pNext);
if (copied != VK_SUCCESS) return copied;
}
VkResult result = next_create(physical, &patched, allocator, device);
free_chain_copy(&copy);
if (result != VK_SUCCESS) return result;
PFN_vkCreateSampler create_sampler = (PFN_vkCreateSampler)next_gdpa(*device, "vkCreateSampler");
+47
View File
@@ -0,0 +1,47 @@
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
import unittest
TOOLS = Path(__file__).resolve().parents[1]
LAYER = TOOLS / "linuxfs/xclipse-layer"
class XclipseLayerTest(unittest.TestCase):
def test_layer_against_a_mock_loader_and_driver(self):
compiler = shutil.which(os.environ.get("CC", "cc"))
if not compiler:
self.fail("A C compiler is required for the Xclipse layer regression test")
# The build compiles the layer against the distribution's headers (libvulkan-dev);
# VULKAN_INCLUDE points elsewhere, e.g. a Vulkan-Headers checkout on macOS.
include = Path(os.environ.get("VULKAN_INCLUDE", "/usr/include"))
if not (include / "vulkan/vk_layer.h").is_file():
self.fail("Vulkan headers are required: install libvulkan-dev or set VULKAN_INCLUDE")
with tempfile.TemporaryDirectory(prefix="droiddeck-xclipse-") as tmp:
program = Path(tmp) / "xclipse-layer"
built = subprocess.run([compiler, "-std=gnu11", "-Wall", "-Wextra", "-Werror", "-Wno-unused-parameter",
"-UNDEBUG", "-pthread", "-I", str(LAYER), "-I", str(include),
str(Path(__file__).with_name("xclipse_layer_test.c")), "-ldl", "-o", str(program)],
capture_output=True, text=True)
self.assertEqual(built.returncode, 0, built.stdout + built.stderr)
ran = subprocess.run([str(program)], capture_output=True, text=True, timeout=30)
self.assertEqual(ran.returncode, 0, ran.stdout + ran.stderr)
self.assertIn("xclipse layer ok", ran.stdout)
def test_device_chain_table_matches_its_generator(self):
registry = os.environ.get("VULKAN_REGISTRY")
if not registry:
self.skipTest("set VULKAN_REGISTRY to a Vulkan-Headers 1.3.275 checkout to recheck device_chain.inc")
with tempfile.TemporaryDirectory(prefix="droiddeck-chain-") as tmp:
output = Path(tmp) / "device_chain.inc"
subprocess.run(["python3", str(LAYER / "gen_device_chain.py"), str(Path(registry) / "registry/vk.xml"),
str(Path(registry) / "include/vulkan/vulkan_core.h"), str(output)],
check=True, capture_output=True)
self.assertEqual(output.read_text(), (LAYER / "device_chain.inc").read_text())
if __name__ == "__main__":
unittest.main()
+217
View File
@@ -0,0 +1,217 @@
/* The Xclipse layer between a simulated loader and a mock driver. The driver refuses what the compat
* layer and Samsung's driver refuse: textureCompressionBC, and a compute layout holding an immutable
* YCbCr sampler. Built by test_xclipse_layer.py with the layer source included directly. */
#include "xclipse_layer.c"
#include <assert.h>
struct object { void *dispatch; };
static int instance_table, device_table[4];
static struct object mock_instance = {&instance_table}, mock_physical = {&instance_table};
static struct object mock_devices[4] = {{&device_table[0]}, {&device_table[1]}, {&device_table[2]}, {&device_table[3]}};
static int devices_created;
/* What the driver last saw. */
static int driver_saw_bc, driver_saw_layout_sampler_count;
static VkSampler driver_layout_samplers[16];
static uint64_t next_sampler = 0x100;
static VkSampler driver_ycbcr[16];
static int driver_ycbcr_count;
static VkResult VKAPI_CALL mock_create_instance(const VkInstanceCreateInfo *info, const VkAllocationCallbacks *allocator,
VkInstance *instance) {
*instance = (VkInstance)&mock_instance;
return VK_SUCCESS;
}
static void VKAPI_CALL mock_features(VkPhysicalDevice physical, VkPhysicalDeviceFeatures *features) {
memset(features, 0, sizeof(*features));
}
static void VKAPI_CALL mock_features2(VkPhysicalDevice physical, VkPhysicalDeviceFeatures2 *features) {
mock_features(physical, &features->features);
}
/* The compat layer's emulation: BC formats sample, the feature bit stays off. */
static void VKAPI_CALL mock_format_properties(VkPhysicalDevice physical, VkFormat format, VkFormatProperties *out) {
memset(out, 0, sizeof(*out));
if (format >= VK_FORMAT_BC1_RGB_UNORM_BLOCK && format <= VK_FORMAT_BC7_SRGB_BLOCK)
out->optimalTilingFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
}
static void VKAPI_CALL mock_format_properties2(VkPhysicalDevice physical, VkFormat format, VkFormatProperties2 *out) {
mock_format_properties(physical, format, &out->formatProperties);
}
static VkResult VKAPI_CALL mock_time_domains(VkPhysicalDevice physical, uint32_t *count, VkTimeDomainEXT *domains) {
if (domains) { domains[0] = VK_TIME_DOMAIN_DEVICE_EXT; domains[1] = VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT; }
*count = 2;
return VK_SUCCESS;
}
static VkResult VKAPI_CALL mock_create_device(VkPhysicalDevice physical, const VkDeviceCreateInfo *info,
const VkAllocationCallbacks *allocator, VkDevice *device) {
driver_saw_bc = info->pEnabledFeatures && info->pEnabledFeatures->textureCompressionBC;
for (const VkBaseInStructure *p = info->pNext; p; p = p->pNext)
if (p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 &&
((const VkPhysicalDeviceFeatures2 *)p)->features.textureCompressionBC) driver_saw_bc = 1;
if (driver_saw_bc) return VK_ERROR_FEATURE_NOT_PRESENT;
assert(devices_created < 4);
*device = (VkDevice)&mock_devices[devices_created++];
return VK_SUCCESS;
}
static VkResult VKAPI_CALL mock_create_sampler(VkDevice device, const VkSamplerCreateInfo *info,
const VkAllocationCallbacks *allocator, VkSampler *sampler) {
*sampler = (VkSampler)next_sampler++;
for (const VkBaseInStructure *p = info->pNext; p; p = p->pNext)
if (p->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO) driver_ycbcr[driver_ycbcr_count++] = *sampler;
return VK_SUCCESS;
}
static void VKAPI_CALL mock_destroy_sampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *allocator) {
for (int i = 0; i < driver_ycbcr_count; i++)
if (driver_ycbcr[i] == sampler) driver_ycbcr[i] = driver_ycbcr[--driver_ycbcr_count];
}
static VkResult VKAPI_CALL mock_create_set_layout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *info,
const VkAllocationCallbacks *allocator, VkDescriptorSetLayout *layout) {
driver_saw_layout_sampler_count = 0;
for (uint32_t b = 0; b < info->bindingCount; b++) {
const VkDescriptorSetLayoutBinding *binding = &info->pBindings[b];
for (uint32_t s = 0; binding->pImmutableSamplers && s < binding->descriptorCount; s++) {
VkSampler sampler = binding->pImmutableSamplers[s];
driver_layout_samplers[driver_saw_layout_sampler_count++] = sampler;
for (int i = 0; i < driver_ycbcr_count; i++)
if ((binding->stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) && driver_ycbcr[i] == sampler)
return VK_ERROR_UNKNOWN;
}
}
*layout = (VkDescriptorSetLayout)0x5000;
return VK_SUCCESS;
}
static void VKAPI_CALL mock_destroy_device(VkDevice device, const VkAllocationCallbacks *allocator) {}
static VkResult VKAPI_CALL mock_timestamps(VkDevice device, uint32_t count, const VkCalibratedTimestampInfoEXT *infos,
uint64_t *timestamps, uint64_t *deviation) {
for (uint32_t i = 0; i < count; i++) timestamps[i] = 42;
*deviation = 1;
return VK_SUCCESS;
}
#define MOCK(name, function) if (!strcmp(requested, name)) return (PFN_vkVoidFunction)function
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL mock_gipa(VkInstance instance, const char *requested) {
MOCK("vkCreateInstance", mock_create_instance);
MOCK("vkCreateDevice", mock_create_device);
MOCK("vkGetPhysicalDeviceFeatures", mock_features);
MOCK("vkGetPhysicalDeviceFeatures2", mock_features2);
MOCK("vkGetPhysicalDeviceFormatProperties", mock_format_properties);
MOCK("vkGetPhysicalDeviceFormatProperties2", mock_format_properties2);
MOCK("vkGetPhysicalDeviceCalibrateableTimeDomainsEXT", mock_time_domains);
return NULL;
}
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL mock_gdpa(VkDevice device, const char *requested) {
MOCK("vkCreateSampler", mock_create_sampler);
MOCK("vkDestroySampler", mock_destroy_sampler);
MOCK("vkCreateDescriptorSetLayout", mock_create_set_layout);
MOCK("vkDestroyDevice", mock_destroy_device);
MOCK("vkGetCalibratedTimestampsEXT", mock_timestamps);
return NULL;
}
/* The loader's link for one vkCreateDevice call, then the caller's own chain. */
static VkResult create(const void *chain, const VkPhysicalDeviceFeatures *enabled, VkDevice *device) {
VkLayerDeviceLink link = {NULL, mock_gipa, mock_gdpa};
VkLayerDeviceCreateInfo loader = {VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, chain, VK_LAYER_LINK_INFO, {&link}};
VkDeviceCreateInfo info = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, &loader, 0, 0, NULL, 0, NULL, 0, NULL, enabled};
PFN_vkCreateDevice create_device = (PFN_vkCreateDevice)vkGetInstanceProcAddr((VkInstance)&mock_instance, "vkCreateDevice");
return create_device((VkPhysicalDevice)&mock_physical, &info, NULL, device);
}
int main(void) {
VkNegotiateLayerInterface negotiate = {LAYER_NEGOTIATE_INTERFACE_STRUCT, NULL, 2, NULL, NULL, NULL};
assert(vkNegotiateLoaderLayerInterfaceVersion(&negotiate) == VK_SUCCESS);
VkLayerInstanceLink instance_link = {NULL, mock_gipa, NULL};
VkLayerInstanceCreateInfo instance_loader = {VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO, NULL, VK_LAYER_LINK_INFO,
{&instance_link}};
VkInstanceCreateInfo instance_info = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pNext = &instance_loader};
VkInstance instance;
PFN_vkCreateInstance create_instance_fn = (PFN_vkCreateInstance)vkGetInstanceProcAddr(NULL, "vkCreateInstance");
assert(create_instance_fn(&instance_info, NULL, &instance) == VK_SUCCESS);
/* The emulated bit is reported... */
VkPhysicalDeviceFeatures features;
((PFN_vkGetPhysicalDeviceFeatures)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures"))(
(VkPhysicalDevice)&mock_physical, &features);
assert(features.textureCompressionBC);
/* ...and cleared before the driver, through pEnabledFeatures... */
VkDevice device;
VkPhysicalDeviceFeatures legacy = {.textureCompressionBC = VK_TRUE};
assert(create(NULL, &legacy, &device) == VK_SUCCESS && !driver_saw_bc && legacy.textureCompressionBC);
/* ...and through a VkPhysicalDeviceFeatures2 behind another structure, leaving the caller's chain intact. */
VkPhysicalDeviceVulkan12Features vk12 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES};
VkPhysicalDeviceFeatures2 features2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, &vk12,
{.textureCompressionBC = VK_TRUE}};
VkPhysicalDeviceTimelineSemaphoreFeatures timeline = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
&features2, VK_TRUE};
VkPhysicalDeviceFeatures2 features2_before = features2;
VkPhysicalDeviceTimelineSemaphoreFeatures timeline_before = timeline;
VkDevice chained;
assert(create(&timeline, NULL, &chained) == VK_SUCCESS && !driver_saw_bc);
assert(!memcmp(&features2, &features2_before, sizeof(features2)));
assert(!memcmp(&timeline, &timeline_before, sizeof(timeline)));
/* A structure newer than the headers this was built with cannot be copied: the chain passes as it
* is and the driver refuses the bit, without the caller's structures being written. */
struct { VkStructureType sType; const void *pNext; uint32_t payload; } future = {(VkStructureType)0x7ffffff0, &features2, 7};
VkDevice unused;
assert(create(&future, NULL, &unused) == VK_ERROR_FEATURE_NOT_PRESENT);
assert(!memcmp(&features2, &features2_before, sizeof(features2)) && future.pNext == &features2);
/* Compute layouts get a plain sampler in place of a YCbCr one. */
PFN_vkCreateSampler create_sampler_fn = (PFN_vkCreateSampler)vkGetDeviceProcAddr(device, "vkCreateSampler");
PFN_vkDestroySampler destroy_sampler_fn = (PFN_vkDestroySampler)vkGetDeviceProcAddr(device, "vkDestroySampler");
PFN_vkCreateDescriptorSetLayout create_layout = (PFN_vkCreateDescriptorSetLayout)vkGetDeviceProcAddr(device, "vkCreateDescriptorSetLayout");
VkSamplerYcbcrConversionInfo conversion = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, NULL, (VkSamplerYcbcrConversion)1};
VkSamplerCreateInfo ycbcr_info = {.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, .pNext = &conversion};
VkSamplerCreateInfo plain_info = {.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
VkSampler ycbcr;
assert(create_sampler_fn(device, &ycbcr_info, NULL, &ycbcr) == VK_SUCCESS);
VkSampler immutable[2] = {ycbcr, ycbcr};
VkDescriptorSetLayoutBinding binding = {4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2, VK_SHADER_STAGE_COMPUTE_BIT, immutable};
VkDescriptorSetLayoutCreateInfo layout_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, 1, &binding};
VkDescriptorSetLayout layout;
assert(create_layout(device, &layout_info, NULL, &layout) == VK_SUCCESS);
assert(driver_layout_samplers[0] != ycbcr && immutable[0] == ycbcr);
/* A destroyed YCbCr sampler's handle, reused for a plain sampler, is left alone. */
destroy_sampler_fn(device, ycbcr, NULL);
next_sampler = (uint64_t)ycbcr;
VkSampler reused;
assert(create_sampler_fn(device, &plain_info, NULL, &reused) == VK_SUCCESS && reused == ycbcr);
immutable[0] = immutable[1] = reused;
assert(create_layout(device, &layout_info, NULL, &layout) == VK_SUCCESS && driver_layout_samplers[0] == reused);
/* Registrations belong to their device and go with it. */
VkSampler other;
assert(create_sampler_fn(chained, &ycbcr_info, NULL, &other) == VK_SUCCESS && ycbcr_count == 1);
((PFN_vkDestroyDevice)vkGetDeviceProcAddr(chained, "vkDestroyDevice"))(chained, NULL);
assert(ycbcr_count == 0);
/* The KHR calibrated-timestamp entry points reach the EXT ones. */
uint32_t domains = 0;
PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT time_domains = (PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsKHR");
assert(time_domains((VkPhysicalDevice)&mock_physical, &domains, NULL) == VK_SUCCESS && domains == 2);
VkCalibratedTimestampInfoEXT stamp = {VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, NULL, VK_TIME_DOMAIN_DEVICE_EXT};
uint64_t value = 0, deviation = 0;
PFN_vkGetCalibratedTimestampsEXT timestamps = (PFN_vkGetCalibratedTimestampsEXT)vkGetDeviceProcAddr(device, "vkGetCalibratedTimestampsKHR");
assert(timestamps(device, 1, &stamp, &value, &deviation) == VK_SUCCESS && value == 42);
puts("xclipse layer ok");
return 0;
}