About Social Code
aboutsummaryrefslogtreecommitdiff
path: root/src/frygon/vulkan/fgvk_physical_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/frygon/vulkan/fgvk_physical_device.c')
-rw-r--r--src/frygon/vulkan/fgvk_physical_device.c573
1 files changed, 573 insertions, 0 deletions
diff --git a/src/frygon/vulkan/fgvk_physical_device.c b/src/frygon/vulkan/fgvk_physical_device.c
new file mode 100644
index 00000000000..44b9b63135e
--- /dev/null
+++ b/src/frygon/vulkan/fgvk_physical_device.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright © 2025 Lucas Francisco Fryzek
+ * SPDX-License-Identifier: MIT
+ */
+#include "fgvk_physical_device.h"
+
+#include "fgcc.h"
+#include "vk_sync_dummy.h"
+
+static void
+fgvk_get_device_info(struct fg_device_info *info) {
+ info->device_id = 0x0001;
+ snprintf(info->device_name, sizeof(info->device_name), "Frygon GFX1");
+}
+
+static void
+fgvk_get_device_properties(const struct fgvk_instance *instance,
+ struct vk_properties *properties)
+{
+ *properties = (struct vk_properties) {
+ .apiVersion = VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION),
+ .driverVersion = vk_get_driver_version(),
+ .vendorID = 0xF5C5,
+ .deviceID = 0x0001,
+ .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
+
+ /* Vulkan 1.0 limits */
+ .maxImageDimension1D = 16384,
+ .maxImageDimension2D = 16384,
+ .maxImageDimension3D = 16384,
+ .maxImageDimensionCube = 0x8000,
+ .maxImageArrayLayers = 2048,
+ .maxTexelBufferElements = 128 * 1024 * 1024,
+ .maxUniformBufferRange = 65536,
+ .maxStorageBufferRange = UINT32_MAX,
+ .maxPushConstantsSize = 4096,
+ .maxMemoryAllocationCount = 4096,
+ .maxSamplerAllocationCount = 4000,
+ .bufferImageGranularity = 0x10000, // TODO
+ .sparseAddressSpaceSize = 0, // TODO
+ .maxBoundDescriptorSets = 8, // TODO
+ .maxPerStageDescriptorSamplers = 8, // TODO
+ .maxPerStageDescriptorUniformBuffers = 8, // TODO
+ .maxPerStageDescriptorStorageBuffers = 8, // TODO
+ .maxPerStageDescriptorSampledImages = 8, // TODO
+ .maxPerStageDescriptorStorageImages = 8, // TODO
+ .maxPerStageDescriptorInputAttachments = 8, // TODO
+ .maxPerStageResources = UINT32_MAX,
+ .maxDescriptorSetSamplers = 8, // TODO
+ .maxDescriptorSetUniformBuffers = 8, // TODO
+ .maxDescriptorSetUniformBuffersDynamic = 0, // TODO
+ .maxDescriptorSetStorageBuffers = 8, // TODO
+ .maxDescriptorSetStorageBuffersDynamic = 0, // TODO
+ .maxDescriptorSetSampledImages = 8, // TODO
+ .maxDescriptorSetStorageImages = 8, // TODO
+ .maxDescriptorSetInputAttachments = 8, // TODO
+ .maxVertexInputAttributes = 32,
+ .maxVertexInputBindings = 32,
+ .maxVertexInputAttributeOffset = 2047,
+ .maxVertexInputBindingStride = 2048,
+ .maxVertexOutputComponents = 128,
+ .maxTessellationGenerationLevel = 64,
+ .maxTessellationPatchSize = 32,
+ .maxTessellationControlPerVertexInputComponents = 128,
+ .maxTessellationControlPerVertexOutputComponents = 128,
+ .maxTessellationControlPerPatchOutputComponents = 120,
+ .maxTessellationControlTotalOutputComponents = 4216,
+ .maxTessellationEvaluationInputComponents = 128,
+ .maxTessellationEvaluationOutputComponents = 128,
+ .maxGeometryShaderInvocations = 32,
+ .maxGeometryInputComponents = 128,
+ .maxGeometryOutputComponents = 128,
+ .maxGeometryOutputVertices = 1024,
+ .maxGeometryTotalOutputComponents = 1024,
+ .maxFragmentInputComponents = 128,
+ .maxFragmentOutputAttachments = 8, // TODO
+ .maxFragmentDualSrcAttachments = 1,
+ .maxFragmentCombinedOutputResources = 16,
+ /* Nvidia limits this to 48kB for consistency reasons, we could lift the
+ * limit if we wanted to.
+ */
+ .maxComputeSharedMemorySize = 64 * 1024, // TODO
+ .maxComputeWorkGroupCount = {0x7fffffff, 65535, 65535},
+ .maxComputeWorkGroupInvocations = 1024,
+ .maxComputeWorkGroupSize = {1024, 1024, 64},
+ .subPixelPrecisionBits = 8,
+ .subTexelPrecisionBits = 8,
+ .mipmapPrecisionBits = 8,
+ .maxDrawIndexedIndexValue = UINT32_MAX,
+ .maxDrawIndirectCount = UINT32_MAX,
+ .maxSamplerLodBias = 15,
+ .maxSamplerAnisotropy = 16,
+ .maxViewports = 8,
+ .maxViewportDimensions = { 32768, 32768 },
+ .viewportBoundsRange = { -65536, 65536 },
+ .viewportSubPixelBits = 8,
+ .minMemoryMapAlignment = 4096, // TODO
+ .minTexelBufferOffsetAlignment = 8,
+ .minUniformBufferOffsetAlignment = 8,
+ .minStorageBufferOffsetAlignment = 8,
+ .minTexelOffset = -8,
+ .maxTexelOffset = 7,
+ .minTexelGatherOffset = -32,
+ .maxTexelGatherOffset = 31,
+ .minInterpolationOffset = -0.5,
+ .maxInterpolationOffset = 0.4375,
+ .subPixelInterpolationOffsetBits = 4,
+ .maxFramebufferHeight = 16384,
+ .maxFramebufferWidth = 16384,
+ .maxFramebufferLayers = 2048,
+ .framebufferColorSampleCounts = 1,
+ .framebufferDepthSampleCounts = 1,
+ .framebufferNoAttachmentsSampleCounts = 1,
+ .framebufferStencilSampleCounts = 1,
+ .maxColorAttachments = 8,
+ .sampledImageColorSampleCounts = 1,
+ .sampledImageIntegerSampleCounts = 1,
+ .sampledImageDepthSampleCounts = 1,
+ .sampledImageStencilSampleCounts = 1,
+ .storageImageSampleCounts = 1,
+ .maxSampleMaskWords = 1,
+ .timestampComputeAndGraphics = true,
+ /* FIXME: Is timestamp period actually 1? */
+ .timestampPeriod = 1.0f,
+ .maxClipDistances = 8,
+ .maxCullDistances = 8,
+ .maxCombinedClipAndCullDistances = 8,
+ .discreteQueuePriorities = 2,
+ .pointSizeRange = { 1.0, 2047.94 },
+ .lineWidthRange = { 1, 64 },
+ .pointSizeGranularity = 0.0625,
+ .lineWidthGranularity = 0.0625,
+ .strictLines = true,
+ .standardSampleLocations = true,
+ .optimalBufferCopyOffsetAlignment = 1,
+ .optimalBufferCopyRowPitchAlignment = 1,
+ /* Default to 64 if we don't know the atom size */
+ .nonCoherentAtomSize = 64,
+
+ /* Vulkan 1.0 sparse properties */
+ .sparseResidencyNonResidentStrict = true,
+ .sparseResidencyAlignedMipSize = VK_FALSE,
+ .sparseResidencyStandard2DBlockShape = true,
+ .sparseResidencyStandard2DMultisampleBlockShape = true,
+ .sparseResidencyStandard3DBlockShape = true,
+
+#if 0
+ /* Vulkan 1.1 properties */
+ .subgroupSize = 32,
+ .subgroupSupportedStages = VK_SHADER_STAGE_VERTEX_BIT |
+ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
+ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT |
+ VK_SHADER_STAGE_GEOMETRY_BIT |
+ VK_SHADER_STAGE_FRAGMENT_BIT |
+ VK_SHADER_STAGE_COMPUTE_BIT,
+ .subgroupSupportedOperations = VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
+ VK_SUBGROUP_FEATURE_BALLOT_BIT |
+ VK_SUBGROUP_FEATURE_BASIC_BIT |
+ VK_SUBGROUP_FEATURE_CLUSTERED_BIT |
+ VK_SUBGROUP_FEATURE_QUAD_BIT |
+ VK_SUBGROUP_FEATURE_ROTATE_BIT_KHR |
+ VK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT_KHR |
+ VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
+ VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
+ VK_SUBGROUP_FEATURE_VOTE_BIT,
+ .subgroupQuadOperationsInAllStages = false,
+ .pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY,
+ .maxMultiviewViewCount = NVK_MAX_MULTIVIEW_VIEW_COUNT,
+ .maxMultiviewInstanceIndex = UINT32_MAX,
+ .maxPerSetDescriptors = UINT32_MAX,
+ .maxMemoryAllocationSize = (1u << 31),
+
+ /* Vulkan 1.2 properties */
+ .supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT |
+ VK_RESOLVE_MODE_AVERAGE_BIT |
+ VK_RESOLVE_MODE_MIN_BIT |
+ VK_RESOLVE_MODE_MAX_BIT,
+ .supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT |
+ VK_RESOLVE_MODE_MIN_BIT |
+ VK_RESOLVE_MODE_MAX_BIT,
+ .independentResolveNone = true,
+ .independentResolve = true,
+ .driverID = VK_DRIVER_ID_MESA_NVK,
+ .conformanceVersion =
+ nvk_is_conformant(info) ? (VkConformanceVersion) { 1, 4, 3, 0 }
+ : (VkConformanceVersion) { 0, 0, 0, 0 },
+ .denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
+ .roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
+ .shaderSignedZeroInfNanPreserveFloat16 = true,
+ .shaderSignedZeroInfNanPreserveFloat32 = true,
+ .shaderSignedZeroInfNanPreserveFloat64 = true,
+ .shaderDenormPreserveFloat16 = true,
+ .shaderDenormPreserveFloat32 = true,
+ .shaderDenormPreserveFloat64 = true,
+ .shaderDenormFlushToZeroFloat16 = false,
+ .shaderDenormFlushToZeroFloat32 = true,
+ .shaderDenormFlushToZeroFloat64 = false,
+ .shaderRoundingModeRTEFloat16 = true,
+ .shaderRoundingModeRTEFloat32 = true,
+ .shaderRoundingModeRTEFloat64 = true,
+ .shaderRoundingModeRTZFloat16 = false,
+ .shaderRoundingModeRTZFloat32 = true,
+ .shaderRoundingModeRTZFloat64 = true,
+ .maxUpdateAfterBindDescriptorsInAllPools = UINT32_MAX,
+ .shaderUniformBufferArrayNonUniformIndexingNative = true,
+ .shaderSampledImageArrayNonUniformIndexingNative = info->cls_eng3d >= TURING_A,
+ .shaderStorageBufferArrayNonUniformIndexingNative = true,
+ .shaderStorageImageArrayNonUniformIndexingNative = info->cls_eng3d >= TURING_A,
+ .shaderInputAttachmentArrayNonUniformIndexingNative = false,
+ .robustBufferAccessUpdateAfterBind = true,
+ .quadDivergentImplicitLod = info->cls_eng3d >= TURING_A,
+ .maxPerStageDescriptorUpdateAfterBindSamplers = NVK_MAX_DESCRIPTORS,
+ .maxPerStageDescriptorUpdateAfterBindUniformBuffers = NVK_MAX_DESCRIPTORS,
+ .maxPerStageDescriptorUpdateAfterBindStorageBuffers = NVK_MAX_DESCRIPTORS,
+ .maxPerStageDescriptorUpdateAfterBindSampledImages = NVK_MAX_DESCRIPTORS,
+ .maxPerStageDescriptorUpdateAfterBindStorageImages = NVK_MAX_DESCRIPTORS,
+ .maxPerStageDescriptorUpdateAfterBindInputAttachments = NVK_MAX_DESCRIPTORS,
+ .maxPerStageUpdateAfterBindResources = UINT32_MAX,
+ .maxDescriptorSetUpdateAfterBindSamplers = NVK_MAX_DESCRIPTORS,
+ .maxDescriptorSetUpdateAfterBindUniformBuffers = NVK_MAX_DESCRIPTORS,
+ .maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2,
+ .maxDescriptorSetUpdateAfterBindStorageBuffers = NVK_MAX_DESCRIPTORS,
+ .maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2,
+ .maxDescriptorSetUpdateAfterBindSampledImages = NVK_MAX_DESCRIPTORS,
+ .maxDescriptorSetUpdateAfterBindStorageImages = NVK_MAX_DESCRIPTORS,
+ .maxDescriptorSetUpdateAfterBindInputAttachments = NVK_MAX_DESCRIPTORS,
+ .filterMinmaxSingleComponentFormats = info->cls_eng3d >= MAXWELL_B,
+ .filterMinmaxImageComponentMapping = info->cls_eng3d >= MAXWELL_B,
+ .maxTimelineSemaphoreValueDifference = UINT64_MAX,
+ .framebufferIntegerColorSampleCounts = sample_counts,
+
+ /* Vulkan 1.3 properties */
+ .minSubgroupSize = 32,
+ .maxSubgroupSize = 32,
+ .maxComputeWorkgroupSubgroups = 1024 / 32,
+ .requiredSubgroupSizeStages = 0,
+ .maxInlineUniformBlockSize = NVK_MAX_INLINE_UNIFORM_BLOCK_SIZE,
+ .maxPerStageDescriptorInlineUniformBlocks = 32,
+ .maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = 32,
+ .maxDescriptorSetInlineUniformBlocks = 6 * 32,
+ .maxDescriptorSetUpdateAfterBindInlineUniformBlocks = 6 * 32,
+ .maxInlineUniformTotalSize = 1 << 16,
+ .integerDotProduct4x8BitPackedUnsignedAccelerated
+ = info->cls_eng3d >= VOLTA_A,
+ .integerDotProduct4x8BitPackedSignedAccelerated
+ = info->cls_eng3d >= VOLTA_A,
+ .integerDotProduct4x8BitPackedMixedSignednessAccelerated
+ = info->cls_eng3d >= VOLTA_A,
+ .storageTexelBufferOffsetAlignmentBytes = NVK_MIN_TEXEL_BUFFER_ALIGNMENT,
+ .storageTexelBufferOffsetSingleTexelAlignment = true,
+ .uniformTexelBufferOffsetAlignmentBytes = NVK_MIN_TEXEL_BUFFER_ALIGNMENT,
+ .uniformTexelBufferOffsetSingleTexelAlignment = true,
+ .maxBufferSize = NVK_MAX_BUFFER_SIZE,
+
+ /* Vulkan 1.4 properties */
+ .lineSubPixelPrecisionBits = 8,
+ .maxVertexAttribDivisor = UINT32_MAX,
+ .supportsNonZeroFirstInstance = true,
+ .maxPushDescriptors = NVK_MAX_PUSH_DESCRIPTORS,
+ .dynamicRenderingLocalReadDepthStencilAttachments = true,
+ .dynamicRenderingLocalReadMultisampledAttachments = true,
+ .earlyFragmentMultisampleCoverageAfterSampleCounting = true,
+ .earlyFragmentSampleMaskTestBeforeSampleCounting = true,
+ .depthStencilSwizzleOneSupport = true,
+ .polygonModePointSize = true,
+ .nonStrictSinglePixelWideLinesUseParallelogram = false,
+ .nonStrictWideLinesUseParallelogram = false,
+ .blockTexelViewCompatibleMultipleLayers = true,
+ .maxCombinedImageSamplerDescriptorCount = NVK_MAX_IMAGE_PLANES,
+ .fragmentShadingRateClampCombinerInputs = false, /* TODO */
+ .defaultRobustnessStorageBuffers =
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT,
+ .defaultRobustnessUniformBuffers =
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT,
+ .defaultRobustnessVertexInputs =
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT,
+ .defaultRobustnessImages =
+ VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT,
+
+ /* VK_KHR_cooperative_matrix */
+ .cooperativeMatrixSupportedStages = VK_SHADER_STAGE_COMPUTE_BIT,
+
+ /* VK_KHR_discard_rectangles */
+ .maxDiscardRectangles = NVK_MAX_DISCARD_RECTANGLES,
+
+ /* VK_KHR_compute_shader_derivatives */
+ .meshAndTaskShaderDerivatives = false,
+
+ /* VK_KHR_pipeline_binary
+ *
+ * InternalCache properties are set by
+ * nvk_physical_device_init_pipeline_cache()
+ */
+ .pipelineBinaryCompressedData = false,
+
+ /* VK_EXT_conservative_rasterization */
+ .primitiveOverestimationSize = info->cls_eng3d >= VOLTA_A ? 1.0f / 512.0f : 0.0,
+ .maxExtraPrimitiveOverestimationSize = 0.75,
+ .extraPrimitiveOverestimationSizeGranularity = 0.25,
+ .primitiveUnderestimation = info->cls_eng3d >= VOLTA_A,
+ .conservativePointAndLineRasterization = true,
+ .degenerateLinesRasterized = info->cls_eng3d >= VOLTA_A,
+ .degenerateTrianglesRasterized = info->cls_eng3d >= PASCAL_A,
+ .fullyCoveredFragmentShaderInputVariable = false,
+ .conservativeRasterizationPostDepthCoverage = info->cls_eng3d >= MAXWELL_B,
+
+ /* VK_EXT_custom_border_color */
+ .maxCustomBorderColorSamplers = 4000,
+
+ /* VK_EXT_descriptor_buffer */
+ .combinedImageSamplerDescriptorSingleArray = true,
+ .bufferlessPushDescriptors = true,
+ .allowSamplerImageViewPostSubmitCreation = false,
+ .descriptorBufferOffsetAlignment = nvk_min_cbuf_alignment(info),
+ .maxDescriptorBufferBindings = 32,
+ .maxResourceDescriptorBufferBindings = 32,
+ .maxSamplerDescriptorBufferBindings = 32,
+ .maxEmbeddedImmutableSamplerBindings = 32,
+ .maxEmbeddedImmutableSamplers = 4000,
+ .bufferCaptureReplayDescriptorDataSize = sizeof(uint64_t),
+ .imageCaptureReplayDescriptorDataSize = 0,
+ .imageViewCaptureReplayDescriptorDataSize =
+ sizeof(struct nvk_image_view_capture),
+ .samplerCaptureReplayDescriptorDataSize =
+ sizeof(struct nvk_sampler_capture),
+ .accelerationStructureCaptureReplayDescriptorDataSize = 0, // todo
+ .samplerDescriptorSize = sizeof(struct nvk_sampled_image_descriptor),
+ .combinedImageSamplerDescriptorSize = sizeof(struct nvk_sampled_image_descriptor),
+ .sampledImageDescriptorSize = sizeof(struct nvk_sampled_image_descriptor),
+ .storageImageDescriptorSize = sizeof(struct nvk_storage_image_descriptor),
+ .uniformTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor),
+ .robustUniformTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor),
+ .storageTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor),
+ .robustStorageTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor),
+ .uniformBufferDescriptorSize = sizeof(union nvk_buffer_descriptor),
+ .robustUniformBufferDescriptorSize = sizeof(union nvk_buffer_descriptor),
+ .storageBufferDescriptorSize = sizeof(union nvk_buffer_descriptor),
+ .robustStorageBufferDescriptorSize = sizeof(union nvk_buffer_descriptor),
+ .inputAttachmentDescriptorSize = sizeof(struct nvk_sampled_image_descriptor),
+ .accelerationStructureDescriptorSize = 0,
+ .maxSamplerDescriptorBufferRange = UINT32_MAX,
+ .maxResourceDescriptorBufferRange = UINT32_MAX,
+ .samplerDescriptorBufferAddressSpaceSize = UINT32_MAX,
+ .resourceDescriptorBufferAddressSpaceSize = UINT32_MAX,
+ .descriptorBufferAddressSpaceSize = UINT32_MAX,
+
+ /* VK_EXT_device_generated_commands */
+ .maxIndirectPipelineCount = UINT32_MAX,
+ .maxIndirectShaderObjectCount = UINT32_MAX,
+ .maxIndirectSequenceCount = 1 << 20,
+ .maxIndirectCommandsTokenCount = 16,
+ .maxIndirectCommandsTokenOffset = 2047,
+ .maxIndirectCommandsIndirectStride = 1 << 12,
+ .supportedIndirectCommandsInputModes =
+ VK_INDIRECT_COMMANDS_INPUT_MODE_VULKAN_INDEX_BUFFER_EXT |
+ VK_INDIRECT_COMMANDS_INPUT_MODE_DXGI_INDEX_BUFFER_EXT,
+ .supportedIndirectCommandsShaderStages =
+ NVK_SHADER_STAGE_GRAPHICS_BITS | VK_SHADER_STAGE_COMPUTE_BIT,
+ .supportedIndirectCommandsShaderStagesPipelineBinding =
+ NVK_SHADER_STAGE_GRAPHICS_BITS | VK_SHADER_STAGE_COMPUTE_BIT,
+ .supportedIndirectCommandsShaderStagesShaderBinding =
+ NVK_SHADER_STAGE_GRAPHICS_BITS | VK_SHADER_STAGE_COMPUTE_BIT,
+ .deviceGeneratedCommandsTransformFeedback = true,
+ .deviceGeneratedCommandsMultiDrawIndirectCount = info->cls_eng3d >= TURING_A,
+
+ /* VK_EXT_extended_dynamic_state3 */
+ .dynamicPrimitiveTopologyUnrestricted = true,
+
+ /* VK_EXT_graphics_pipeline_library */
+ .graphicsPipelineLibraryFastLinking = true,
+ .graphicsPipelineLibraryIndependentInterpolationDecoration = true,
+
+ /* VK_KHR_maintenance7 */
+ .robustFragmentShadingRateAttachmentAccess = false,
+ .separateDepthStencilAttachmentAccess = false,
+ .maxDescriptorSetTotalUniformBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2,
+ .maxDescriptorSetTotalStorageBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2,
+ .maxDescriptorSetTotalBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS,
+ .maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2,
+ .maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2,
+ .maxDescriptorSetUpdateAfterBindTotalBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS,
+
+ /* VK_KHR_maintenance9 */
+ .image2DViewOf3DSparse = false,
+ .defaultVertexAttributeValue =
+ VK_DEFAULT_VERTEX_ATTRIBUTE_VALUE_ZERO_ZERO_ZERO_ZERO_KHR,
+
+ /* VK_KHR_maintenance10 */
+ .rgba4OpaqueBlackSwizzled = true,
+ .resolveSrgbFormatAppliesTransferFunction = true,
+ .resolveSrgbFormatSupportsTransferFunctionControl = true,
+
+ /* VK_EXT_legacy_vertex_attributes */
+ .nativeUnalignedPerformance = true,
+
+ /* VK_EXT_map_memory_placed */
+ .minPlacedMemoryMapAlignment = os_page_size,
+
+ /* VK_EXT_multi_draw */
+ .maxMultiDrawCount = UINT32_MAX,
+
+ /* VK_EXT_nested_command_buffer */
+ .maxCommandBufferNestingLevel = UINT32_MAX,
+
+ /* VK_EXT_pci_bus_info */
+ .pciDomain = info->pci.domain,
+ .pciBus = info->pci.bus,
+ .pciDevice = info->pci.dev,
+ .pciFunction = info->pci.func,
+
+ /* VK_EXT_physical_device_drm gets populated later */
+
+ /* VK_EXT_provoking_vertex */
+ .provokingVertexModePerPipeline = true,
+ .transformFeedbackPreservesTriangleFanProvokingVertex = true,
+
+ /* VK_EXT_robustness2 */
+ .robustStorageBufferAccessSizeAlignment = NVK_SSBO_BOUNDS_CHECK_ALIGNMENT,
+ .robustUniformBufferAccessSizeAlignment = nvk_min_cbuf_alignment(info),
+
+ /* VK_EXT_sample_locations
+ *
+ * There's a weird HW issue with per-sample interpolation for 1x. It
+ * always interpolates at (0.5, 0.5) so we just disable custom sample
+ * locations for 1x.
+ */
+ .sampleLocationSampleCounts = sample_counts & ~VK_SAMPLE_COUNT_1_BIT,
+ .maxSampleLocationGridSize = (VkExtent2D){ 1, 1 },
+ .sampleLocationCoordinateRange[0] = 0.0f,
+ .sampleLocationCoordinateRange[1] = 0.9375f,
+ .sampleLocationSubPixelBits = 4,
+ .variableSampleLocations = true,
+
+ /* VK_EXT_shader_object */
+ .shaderBinaryVersion = 0,
+
+ /* VK_EXT_transform_feedback */
+ .maxTransformFeedbackStreams = 4,
+ .maxTransformFeedbackBuffers = 4,
+ .maxTransformFeedbackBufferSize = UINT32_MAX,
+ .maxTransformFeedbackStreamDataSize = 2048,
+ .maxTransformFeedbackBufferDataSize = 512,
+ .maxTransformFeedbackBufferDataStride = 2048,
+ .transformFeedbackQueries = true,
+ .transformFeedbackStreamsLinesTriangles = false,
+ .transformFeedbackRasterizationStreamSelect = true,
+ .transformFeedbackDraw = true,
+
+ /* VK_KHR_fragment_shader_barycentric */
+ .triStripVertexOrderIndependentOfProvokingVertex = false,
+
+ /* VK_KHR_fragment_shading_rate */
+ .minFragmentShadingRateAttachmentTexelSize = { 16, 16 },
+ .maxFragmentShadingRateAttachmentTexelSize = { 16, 16 },
+ .maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1,
+ .primitiveFragmentShadingRateWithMultipleViewports = info->cls_eng3d >= AMPERE_B,
+ .layeredShadingRateAttachments = true,
+ .fragmentShadingRateNonTrivialCombinerOps = true,
+ .maxFragmentSize = { 4, 4 },
+ .maxFragmentSizeAspectRatio = 2,
+ .maxFragmentShadingRateCoverageSamples = 16,
+ .maxFragmentShadingRateRasterizationSamples = 16,
+ .fragmentShadingRateWithShaderDepthStencilWrites = true,
+ .fragmentShadingRateWithSampleMask = true,
+ .fragmentShadingRateWithShaderSampleMask = true,
+ .fragmentShadingRateWithConservativeRasterization = true,
+ //.fragmentShadingRateWithFragmentShaderInterlock = true,
+ .fragmentShadingRateWithCustomSampleLocations = true,
+ .fragmentShadingRateStrictMultiplyCombiner = true,
+
+ /* VK_MESA_image_alignment_control */
+ .supportedImageAlignmentMask = (4 * 1024) | (16 * 1024) | (64 * 1024),
+
+ /* VK_NV_shader_sm_builtins */
+ .shaderSMCount = (uint32_t)info->tpc_count * info->mp_per_tpc,
+ .shaderWarpsPerSM = info->max_warps_per_mp,
+#endif
+ };
+
+ snprintf(properties->deviceName, sizeof(properties->deviceName), "Frygon GFX1");
+}
+
+VkResult
+fgvk_physical_device_enumerate(struct vk_instance *_instance)
+{
+ VkResult result = VK_SUCCESS;
+ struct fgvk_instance *instance = (struct fgvk_instance *)_instance;
+
+ struct fgvk_physical_device *device =
+ vk_zalloc(&instance->vk.alloc, sizeof(*device), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (!device)
+ return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ struct vk_physical_device_dispatch_table dispatch_table;
+ vk_physical_device_dispatch_table_from_entrypoints
+ (&dispatch_table, &fgvk_physical_device_entrypoints, true);
+ //vk_physical_device_dispatch_table_from_entrypoints(
+ // &dispatch_table, &wsi_physical_device_entrypoints, false);
+
+ struct vk_properties properties;
+ fgvk_get_device_properties(instance, &properties);
+
+ result = vk_physical_device_init(&device->vk, &instance->vk, NULL, NULL,
+ &properties, &dispatch_table);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ fgvk_get_device_info(&device->info);
+
+ device->fgcc = fgcc_compiler_create(&device->info);
+ device->sync_types[0] = &vk_sync_dummy_type;
+ device->sync_types[1] = NULL;
+ device->vk.supported_sync_types = device->sync_types;
+
+ list_addtail(&device->vk.link, &instance->vk.physical_devices.list);
+
+ return VK_SUCCESS;
+
+fail:
+ vk_physical_device_finish(&device->vk);
+ vk_free(&instance->vk.alloc, device);
+ return result;
+}
+
+void
+fgvk_physical_device_destroy(struct vk_physical_device *pdevice)
+{
+ struct fgvk_physical_device *pdev =
+ container_of(pdevice, struct fgvk_physical_device, vk);
+
+ vk_physical_device_finish(&pdev->vk);
+ vk_free(&pdev->vk.instance->alloc, pdev);
+}
+
+VKAPI_ATTR void VKAPI_CALL
+fgvk_GetPhysicalDeviceMemoryProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
+{
+ //VK_FROM_HANDLE(fgvk_physical_device, pdev, physicalDevice);
+
+ pMemoryProperties->memoryProperties.memoryHeapCount = 1;
+ pMemoryProperties->memoryProperties.memoryHeaps[0] = (VkMemoryHeap) {
+ .size = 256*1024*1024,
+ .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
+ };
+
+ pMemoryProperties->memoryProperties.memoryTypeCount = 1;
+ pMemoryProperties->memoryProperties.memoryTypes[0] = (VkMemoryType) {
+ .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+ .heapIndex = 0,
+ };
+}
+
+VKAPI_ATTR void VKAPI_CALL
+fgvk_GetPhysicalDeviceQueueFamilyProperties2(
+ VkPhysicalDevice physicalDevice,
+ uint32_t *pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2 *pQueueFamilyProperties)
+{
+ VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out, pQueueFamilyProperties,
+ pQueueFamilyPropertyCount);
+
+ vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) {
+ p->queueFamilyProperties.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
+ p->queueFamilyProperties.queueCount = 1;
+ p->queueFamilyProperties.timestampValidBits = 64;
+ p->queueFamilyProperties.minImageTransferGranularity = (VkExtent3D){1, 1, 1};
+ }
+}