panvk: Move the VkPhysicalDevice logic to panvk_physical_device.{c,h}

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Reviewed-by: Rebecca Mckeever <rebecca.mckeever@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28170>
This commit is contained in:
Boris Brezillon 2023-12-19 19:44:49 +01:00 committed by Marge Bot
parent afdca26091
commit ac34183ec3
17 changed files with 1330 additions and 1305 deletions

View file

@ -42,10 +42,10 @@ libpanvk_files = files(
'panvk_device_memory.c',
'panvk_descriptor_set.c',
'panvk_event.c',
'panvk_formats.c',
'panvk_image.c',
'panvk_instance.c',
'panvk_mempool.c',
'panvk_physical_device.c',
'panvk_pipeline.c',
'panvk_private.h',
'panvk_query.c',

View file

@ -28,6 +28,7 @@
#include "panvk_buffer.h"
#include "panvk_cmd_pool.h"
#include "panvk_physical_device.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"

View file

@ -29,6 +29,7 @@
#include "panvk_device_memory.h"
#include "panvk_image.h"
#include "panvk_instance.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
#include "panvk_queue.h"
@ -65,705 +66,6 @@
#include <wayland-client.h>
#endif
static int
panvk_device_get_cache_uuid(uint16_t family, void *uuid)
{
uint32_t mesa_timestamp;
uint16_t f = family;
if (!disk_cache_get_function_timestamp(panvk_device_get_cache_uuid,
&mesa_timestamp))
return -1;
memset(uuid, 0, VK_UUID_SIZE);
memcpy(uuid, &mesa_timestamp, 4);
memcpy((char *)uuid + 4, &f, 2);
snprintf((char *)uuid + 6, VK_UUID_SIZE - 10, "pan");
return 0;
}
static void
panvk_get_driver_uuid(void *uuid)
{
memset(uuid, 0, VK_UUID_SIZE);
snprintf(uuid, VK_UUID_SIZE, "panfrost");
}
static void
panvk_get_device_uuid(void *uuid)
{
memset(uuid, 0, VK_UUID_SIZE);
}
#define PANVK_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION)
static void
panvk_get_device_extensions(const struct panvk_physical_device *device,
struct vk_device_extension_table *ext)
{
*ext = (struct vk_device_extension_table){
.KHR_copy_commands2 = true,
.KHR_shader_expect_assume = true,
.KHR_storage_buffer_storage_class = true,
.KHR_descriptor_update_template = true,
#ifdef PANVK_USE_WSI_PLATFORM
.KHR_swapchain = true,
#endif
.KHR_synchronization2 = true,
.KHR_variable_pointers = true,
.EXT_custom_border_color = true,
.EXT_index_type_uint8 = true,
.EXT_vertex_attribute_divisor = true,
};
}
static void
panvk_get_features(const struct panvk_physical_device *device,
struct vk_features *features)
{
*features = (struct vk_features){
/* Vulkan 1.0 */
.robustBufferAccess = true,
.fullDrawIndexUint32 = true,
.independentBlend = true,
.logicOp = true,
.wideLines = true,
.largePoints = true,
.textureCompressionETC2 = true,
.textureCompressionASTC_LDR = true,
.shaderUniformBufferArrayDynamicIndexing = true,
.shaderSampledImageArrayDynamicIndexing = true,
.shaderStorageBufferArrayDynamicIndexing = true,
.shaderStorageImageArrayDynamicIndexing = true,
/* Vulkan 1.1 */
.storageBuffer16BitAccess = false,
.uniformAndStorageBuffer16BitAccess = false,
.storagePushConstant16 = false,
.storageInputOutput16 = false,
.multiview = false,
.multiviewGeometryShader = false,
.multiviewTessellationShader = false,
.variablePointersStorageBuffer = true,
.variablePointers = true,
.protectedMemory = false,
.samplerYcbcrConversion = false,
.shaderDrawParameters = false,
/* Vulkan 1.2 */
.samplerMirrorClampToEdge = false,
.drawIndirectCount = false,
.storageBuffer8BitAccess = false,
.uniformAndStorageBuffer8BitAccess = false,
.storagePushConstant8 = false,
.shaderBufferInt64Atomics = false,
.shaderSharedInt64Atomics = false,
.shaderFloat16 = false,
.shaderInt8 = false,
.descriptorIndexing = false,
.shaderInputAttachmentArrayDynamicIndexing = false,
.shaderUniformTexelBufferArrayDynamicIndexing = false,
.shaderStorageTexelBufferArrayDynamicIndexing = false,
.shaderUniformBufferArrayNonUniformIndexing = false,
.shaderSampledImageArrayNonUniformIndexing = false,
.shaderStorageBufferArrayNonUniformIndexing = false,
.shaderStorageImageArrayNonUniformIndexing = false,
.shaderInputAttachmentArrayNonUniformIndexing = false,
.shaderUniformTexelBufferArrayNonUniformIndexing = false,
.shaderStorageTexelBufferArrayNonUniformIndexing = false,
.descriptorBindingUniformBufferUpdateAfterBind = false,
.descriptorBindingSampledImageUpdateAfterBind = false,
.descriptorBindingStorageImageUpdateAfterBind = false,
.descriptorBindingStorageBufferUpdateAfterBind = false,
.descriptorBindingUniformTexelBufferUpdateAfterBind = false,
.descriptorBindingStorageTexelBufferUpdateAfterBind = false,
.descriptorBindingUpdateUnusedWhilePending = false,
.descriptorBindingPartiallyBound = false,
.descriptorBindingVariableDescriptorCount = false,
.runtimeDescriptorArray = false,
.samplerFilterMinmax = false,
.scalarBlockLayout = false,
.imagelessFramebuffer = false,
.uniformBufferStandardLayout = false,
.shaderSubgroupExtendedTypes = false,
.separateDepthStencilLayouts = false,
.hostQueryReset = false,
.timelineSemaphore = false,
.bufferDeviceAddress = true,
.bufferDeviceAddressCaptureReplay = false,
.bufferDeviceAddressMultiDevice = false,
.vulkanMemoryModel = false,
.vulkanMemoryModelDeviceScope = false,
.vulkanMemoryModelAvailabilityVisibilityChains = false,
.shaderOutputViewportIndex = false,
.shaderOutputLayer = false,
.subgroupBroadcastDynamicId = false,
/* Vulkan 1.3 */
.robustImageAccess = false,
.inlineUniformBlock = false,
.descriptorBindingInlineUniformBlockUpdateAfterBind = false,
.pipelineCreationCacheControl = false,
.privateData = true,
.shaderDemoteToHelperInvocation = false,
.shaderTerminateInvocation = false,
.subgroupSizeControl = false,
.computeFullSubgroups = false,
.synchronization2 = true,
.textureCompressionASTC_HDR = false,
.shaderZeroInitializeWorkgroupMemory = false,
.dynamicRendering = false,
.shaderIntegerDotProduct = false,
.maintenance4 = false,
/* VK_EXT_index_type_uint8 */
.indexTypeUint8 = true,
/* VK_EXT_vertex_attribute_divisor */
.vertexAttributeInstanceRateDivisor = true,
.vertexAttributeInstanceRateZeroDivisor = true,
/* VK_EXT_depth_clip_enable */
.depthClipEnable = true,
/* VK_EXT_4444_formats */
.formatA4R4G4B4 = true,
.formatA4B4G4R4 = true,
/* VK_EXT_custom_border_color */
.customBorderColors = true,
.customBorderColorWithoutFormat = true,
/* VK_KHR_shader_expect_assume */
.shaderExpectAssume = true,
};
}
void
panvk_physical_device_finish(struct panvk_physical_device *device)
{
panvk_wsi_finish(device);
pan_kmod_dev_destroy(device->kmod.dev);
if (device->master_fd != -1)
close(device->master_fd);
vk_physical_device_finish(&device->vk);
}
VkResult
panvk_physical_device_init(struct panvk_physical_device *device,
struct panvk_instance *instance,
drmDevicePtr drm_device)
{
const char *path = drm_device->nodes[DRM_NODE_RENDER];
VkResult result = VK_SUCCESS;
drmVersionPtr version;
int fd;
int master_fd = -1;
if (!getenv("PAN_I_WANT_A_BROKEN_VULKAN_DRIVER")) {
return vk_errorf(
instance, VK_ERROR_INCOMPATIBLE_DRIVER,
"WARNING: panvk is not a conformant vulkan implementation, "
"pass PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1 if you know what you're doing.");
}
fd = open(path, O_RDWR | O_CLOEXEC);
if (fd < 0) {
return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
"failed to open device %s", path);
}
version = drmGetVersion(fd);
if (!version) {
close(fd);
return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
"failed to query kernel driver version for device %s",
path);
}
if (strcmp(version->name, "panfrost")) {
drmFreeVersion(version);
close(fd);
return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
"device %s does not use the panfrost kernel driver",
path);
}
drmFreeVersion(version);
if (instance->debug_flags & PANVK_DEBUG_STARTUP)
vk_logi(VK_LOG_NO_OBJS(instance), "Found compatible device '%s'.", path);
struct vk_device_extension_table supported_extensions;
panvk_get_device_extensions(device, &supported_extensions);
struct vk_features supported_features;
panvk_get_features(device, &supported_features);
struct vk_physical_device_dispatch_table dispatch_table;
vk_physical_device_dispatch_table_from_entrypoints(
&dispatch_table, &panvk_physical_device_entrypoints, true);
vk_physical_device_dispatch_table_from_entrypoints(
&dispatch_table, &wsi_physical_device_entrypoints, false);
result =
vk_physical_device_init(&device->vk, &instance->vk, &supported_extensions,
&supported_features, NULL, &dispatch_table);
if (result != VK_SUCCESS) {
vk_error(instance, result);
goto fail;
}
if (instance->vk.enabled_extensions.KHR_display) {
master_fd = open(drm_device->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC);
if (master_fd >= 0) {
/* TODO: free master_fd is accel is not working? */
}
}
device->master_fd = master_fd;
device->kmod.dev = pan_kmod_dev_create(fd, PAN_KMOD_DEV_FLAG_OWNS_FD,
&instance->kmod.allocator);
pan_kmod_dev_query_props(device->kmod.dev, &device->kmod.props);
unsigned arch = pan_arch(device->kmod.props.gpu_prod_id);
device->model = panfrost_get_model(device->kmod.props.gpu_prod_id,
device->kmod.props.gpu_variant);
device->formats.all = panfrost_format_table(arch);
device->formats.blendable = panfrost_blendable_format_table(arch);
if (arch <= 5 || arch >= 8) {
result = vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
"%s not supported", device->model->name);
goto fail;
}
memset(device->name, 0, sizeof(device->name));
sprintf(device->name, "%s", device->model->name);
if (panvk_device_get_cache_uuid(device->kmod.props.gpu_prod_id,
device->cache_uuid)) {
result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"cannot generate UUID");
goto fail_close_device;
}
vk_warn_non_conformant_implementation("panvk");
panvk_get_driver_uuid(&device->device_uuid);
panvk_get_device_uuid(&device->device_uuid);
device->drm_syncobj_type = vk_drm_syncobj_get_type(device->kmod.dev->fd);
/* We don't support timelines in the uAPI yet and we don't want it getting
* suddenly turned on by vk_drm_syncobj_get_type() without us adding panvk
* code for it first.
*/
device->drm_syncobj_type.features &= ~VK_SYNC_FEATURE_TIMELINE;
device->sync_types[0] = &device->drm_syncobj_type;
device->sync_types[1] = NULL;
device->vk.supported_sync_types = device->sync_types;
result = panvk_wsi_init(device);
if (result != VK_SUCCESS) {
vk_error(instance, result);
goto fail_close_device;
}
return VK_SUCCESS;
fail_close_device:
pan_kmod_dev_destroy(device->kmod.dev);
fail:
if (fd != -1)
close(fd);
if (master_fd != -1)
close(master_fd);
return result;
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2 *pProperties)
{
VK_FROM_HANDLE(panvk_physical_device, pdevice, physicalDevice);
/* HW supports MSAA 4, 8 and 16, but we limit ourselves to MSAA 4 for now. */
VkSampleCountFlags sample_counts =
VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
const VkPhysicalDeviceLimits limits = {
/* Maximum texture dimension is 2^16. */
.maxImageDimension1D = (1 << 16),
.maxImageDimension2D = (1 << 16),
.maxImageDimension3D = (1 << 16),
.maxImageDimensionCube = (1 << 16),
.maxImageArrayLayers = (1 << 16),
/* Currently limited by the 1D texture size, which is 2^16.
* TODO: If we expose buffer views as 2D textures, we can increase the
* limit.
*/
.maxTexelBufferElements = (1 << 16),
/* Each uniform entry is 16-byte and the number of entries is encoded in a
* 12-bit field, with the minus(1) modifier, which gives 2^20.
*/
.maxUniformBufferRange = 1 << 20,
/* Storage buffer access is lowered to globals, so there's no limit here,
* except for the SW-descriptor we use to encode storage buffer
* descriptors, where the size is a 32-bit field.
*/
.maxStorageBufferRange = UINT32_MAX,
/* 128 bytes of push constants, so we're aligned with the minimum Vulkan
* requirements.
*/
.maxPushConstantsSize = 128,
/* There's no HW limit here. Should we advertize something smaller? */
.maxMemoryAllocationCount = UINT32_MAX,
/* Again, no hardware limit, but most drivers seem to advertive 64k. */
.maxSamplerAllocationCount = 64 * 1024,
/* A cache line. */
.bufferImageGranularity = 64,
/* Sparse binding not supported yet. */
.sparseAddressSpaceSize = 0,
/* Software limit. Pick the minimum required by Vulkan, because Bifrost
* GPUs don't have unified descriptor tables, which forces us to
* agregatte all descriptors from all sets and dispatch them to per-type
* descriptor tables emitted at draw/dispatch time.
* The more sets we support the more copies we are likely to have to do
* at draw time.
*/
.maxBoundDescriptorSets = 4,
/* MALI_RENDERER_STATE::sampler_count is 16-bit. */
.maxPerStageDescriptorSamplers = UINT16_MAX,
.maxDescriptorSetSamplers = UINT16_MAX,
/* MALI_RENDERER_STATE::uniform_buffer_count is 8-bit. We reserve 32 slots
* for our internal UBOs.
*/
.maxPerStageDescriptorUniformBuffers = UINT8_MAX - 32,
.maxDescriptorSetUniformBuffers = UINT8_MAX - 32,
/* SSBOs are limited by the size of a uniform buffer which contains our
* panvk_ssbo_desc objects.
* panvk_ssbo_desc is 16-byte, and each uniform entry in the Mali UBO is
* 16-byte too. The number of entries is encoded in a 12-bit field, with
* a minus(1) modifier, which gives a maximum of 2^12 SSBO
* descriptors.
*/
.maxPerStageDescriptorStorageBuffers = 1 << 12,
.maxDescriptorSetStorageBuffers = 1 << 12,
/* MALI_RENDERER_STATE::sampler_count is 16-bit. */
.maxPerStageDescriptorSampledImages = UINT16_MAX,
.maxDescriptorSetSampledImages = UINT16_MAX,
/* MALI_ATTRIBUTE::buffer_index is 9-bit, and each image takes two
* MALI_ATTRIBUTE_BUFFER slots, which gives a maximum of (1 << 8) images.
*/
.maxPerStageDescriptorStorageImages = 1 << 8,
.maxDescriptorSetStorageImages = 1 << 8,
/* A maximum of 8 color render targets, and one depth-stencil render
* target.
*/
.maxPerStageDescriptorInputAttachments = 9,
.maxDescriptorSetInputAttachments = 9,
/* Could be the sum of all maxPerStageXxx values, but we limit ourselves
* to 2^16 to make things simpler.
*/
.maxPerStageResources = 1 << 16,
/* Software limits to keep VkCommandBuffer tracking sane. */
.maxDescriptorSetUniformBuffersDynamic = 16,
.maxDescriptorSetStorageBuffersDynamic = 8,
/* Software limit to keep VkCommandBuffer tracking sane. The HW supports
* up to 2^9 vertex attributes.
*/
.maxVertexInputAttributes = 16,
.maxVertexInputBindings = 16,
/* MALI_ATTRIBUTE::offset is 32-bit. */
.maxVertexInputAttributeOffset = UINT32_MAX,
/* MALI_ATTRIBUTE_BUFFER::stride is 32-bit. */
.maxVertexInputBindingStride = UINT32_MAX,
/* 32 vec4 varyings. */
.maxVertexOutputComponents = 128,
/* Tesselation shaders not supported. */
.maxTessellationGenerationLevel = 0,
.maxTessellationPatchSize = 0,
.maxTessellationControlPerVertexInputComponents = 0,
.maxTessellationControlPerVertexOutputComponents = 0,
.maxTessellationControlPerPatchOutputComponents = 0,
.maxTessellationControlTotalOutputComponents = 0,
.maxTessellationEvaluationInputComponents = 0,
.maxTessellationEvaluationOutputComponents = 0,
/* Geometry shaders not supported. */
.maxGeometryShaderInvocations = 0,
.maxGeometryInputComponents = 0,
.maxGeometryOutputComponents = 0,
.maxGeometryOutputVertices = 0,
.maxGeometryTotalOutputComponents = 0,
/* 32 vec4 varyings. */
.maxFragmentInputComponents = 128,
/* 8 render targets. */
.maxFragmentOutputAttachments = 8,
/* We don't support dual source blending yet. */
.maxFragmentDualSrcAttachments = 0,
/* 8 render targets, 2^12 storage buffers and 2^8 storage images (see
* above).
*/
.maxFragmentCombinedOutputResources = 8 + (1 << 12) + (1 << 8),
/* MALI_LOCAL_STORAGE::wls_size_{base,scale} allows us to have up to
* (7 << 30) bytes of shared memory, but we cap it to 32K as it doesn't
* really make sense to expose this amount of memory, especially since
* it's backed by global memory anyway.
*/
.maxComputeSharedMemorySize = 32768,
/* Software limit to meet Vulkan 1.0 requirements. We split the
* dispatch in several jobs if it's too big.
*/
.maxComputeWorkGroupCount = {65535, 65535, 65535},
/* We have 10 bits to encode the local-size, and there's a minus(1)
* modifier, so, a size of 1 takes no bit.
*/
.maxComputeWorkGroupInvocations = 1 << 10,
.maxComputeWorkGroupSize = {1 << 10, 1 << 10, 1 << 10},
/* 8-bit subpixel precision. */
.subPixelPrecisionBits = 8,
.subTexelPrecisionBits = 8,
.mipmapPrecisionBits = 8,
/* Software limit. */
.maxDrawIndexedIndexValue = UINT32_MAX,
/* Make it one for now. */
.maxDrawIndirectCount = 1,
.maxSamplerLodBias = 255,
.maxSamplerAnisotropy = 16,
.maxViewports = 1,
/* Same as the framebuffer limit. */
.maxViewportDimensions = {(1 << 14), (1 << 14)},
/* Encoded in a 16-bit signed integer. */
.viewportBoundsRange = {INT16_MIN, INT16_MAX},
.viewportSubPixelBits = 0,
/* Align on a page. */
.minMemoryMapAlignment = 4096,
/* Some compressed texture formats require 128-byte alignment. */
.minTexelBufferOffsetAlignment = 64,
/* Always aligned on a uniform slot (vec4). */
.minUniformBufferOffsetAlignment = 16,
/* Lowered to global accesses, which happen at the 32-bit granularity. */
.minStorageBufferOffsetAlignment = 4,
/* Signed 4-bit value. */
.minTexelOffset = -8,
.maxTexelOffset = 7,
.minTexelGatherOffset = -8,
.maxTexelGatherOffset = 7,
.minInterpolationOffset = -0.5,
.maxInterpolationOffset = 0.5,
.subPixelInterpolationOffsetBits = 8,
.maxFramebufferWidth = (1 << 14),
.maxFramebufferHeight = (1 << 14),
.maxFramebufferLayers = 256,
.framebufferColorSampleCounts = sample_counts,
.framebufferDepthSampleCounts = sample_counts,
.framebufferStencilSampleCounts = sample_counts,
.framebufferNoAttachmentsSampleCounts = sample_counts,
.maxColorAttachments = 8,
.sampledImageColorSampleCounts = sample_counts,
.sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT,
.sampledImageDepthSampleCounts = sample_counts,
.sampledImageStencilSampleCounts = sample_counts,
.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
.maxSampleMaskWords = 1,
.timestampComputeAndGraphics = false,
.timestampPeriod = 0,
.maxClipDistances = 0,
.maxCullDistances = 0,
.maxCombinedClipAndCullDistances = 0,
.discreteQueuePriorities = 1,
.pointSizeRange = {0.125, 4095.9375},
.lineWidthRange = {0.0, 7.9921875},
.pointSizeGranularity = (1.0 / 16.0),
.lineWidthGranularity = (1.0 / 128.0),
.strictLines = false,
.standardSampleLocations = true,
.optimalBufferCopyOffsetAlignment = 64,
.optimalBufferCopyRowPitchAlignment = 64,
.nonCoherentAtomSize = 64,
};
pProperties->properties = (VkPhysicalDeviceProperties){
.apiVersion = PANVK_API_VERSION,
.driverVersion = vk_get_driver_version(),
/* Arm vendor ID. */
.vendorID = 0x13b5,
/* Collect arch_major, arch_minor, arch_rev and product_major,
* as done by the Arm driver.
*/
.deviceID = pdevice->kmod.props.gpu_prod_id << 16,
.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
.limits = limits,
.sparseProperties = {0},
};
strcpy(pProperties->properties.deviceName, pdevice->name);
memcpy(pProperties->properties.pipelineCacheUUID, pdevice->cache_uuid,
VK_UUID_SIZE);
VkPhysicalDeviceVulkan11Properties core_1_1 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
.deviceLUIDValid = false,
.pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES,
.maxMultiviewViewCount = 0,
.maxMultiviewInstanceIndex = 0,
.protectedNoFault = false,
/* Make sure everything is addressable by a signed 32-bit int, and
* our largest descriptors are 96 bytes. */
.maxPerSetDescriptors = (1ull << 31) / 96,
/* Our buffer size fields allow only this much */
.maxMemoryAllocationSize = 0xFFFFFFFFull,
};
memcpy(core_1_1.driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
memcpy(core_1_1.deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
const VkPhysicalDeviceVulkan12Properties core_1_2 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES,
};
const VkPhysicalDeviceVulkan13Properties core_1_3 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES,
};
vk_foreach_struct(ext, pProperties->pNext) {
if (vk_get_physical_device_core_1_1_property_ext(ext, &core_1_1))
continue;
if (vk_get_physical_device_core_1_2_property_ext(ext, &core_1_2))
continue;
if (vk_get_physical_device_core_1_3_property_ext(ext, &core_1_3))
continue;
switch (ext->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
(VkPhysicalDevicePushDescriptorPropertiesKHR *)ext;
properties->maxPushDescriptors = 0;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *properties =
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
/* We will have to restrict this a bit for multiview */
properties->maxVertexAttribDivisor = UINT32_MAX;
break;
}
default:
break;
}
}
}
static const VkQueueFamilyProperties panvk_queue_family_properties = {
.queueFlags =
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT,
.queueCount = 1,
.timestampValidBits = 0,
.minImageTransferGranularity = {1, 1, 1},
};
VKAPI_ATTR void VKAPI_CALL
panvk_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 = panvk_queue_family_properties;
}
}
static uint64_t
panvk_get_system_heap_size()
{
struct sysinfo info;
sysinfo(&info);
uint64_t total_ram = (uint64_t)info.totalram * info.mem_unit;
/* We don't want to burn too much ram with the GPU. If the user has 4GiB
* or less, we use at most half. If they have more than 4GiB, we use 3/4.
*/
uint64_t available_ram;
if (total_ram <= 4ull * 1024 * 1024 * 1024)
available_ram = total_ram / 2;
else
available_ram = total_ram * 3 / 4;
return available_ram;
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceMemoryProperties2(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
{
pMemoryProperties->memoryProperties = (VkPhysicalDeviceMemoryProperties){
.memoryHeapCount = 1,
.memoryHeaps[0].size = panvk_get_system_heap_size(),
.memoryHeaps[0].flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
.memoryTypeCount = 1,
.memoryTypes[0].propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
.memoryTypes[0].heapIndex = 0,
};
}
struct panvk_priv_bo *
panvk_priv_bo_create(struct panvk_device *dev, size_t size, uint32_t flags,
const struct VkAllocationCallbacks *alloc,
@ -864,78 +166,3 @@ panvk_priv_bo_destroy(struct panvk_priv_bo *priv_bo,
pan_kmod_bo_put(priv_bo->bo);
vk_free2(&dev->vk.alloc, alloc, priv_bo);
}
#define DEVICE_PER_ARCH_FUNCS(_ver) \
VkResult panvk_v##_ver##_create_device( \
struct panvk_physical_device *physical_device, \
const VkDeviceCreateInfo *pCreateInfo, \
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice); \
\
void panvk_v##_ver##_destroy_device( \
struct panvk_device *device, const VkAllocationCallbacks *pAllocator)
DEVICE_PER_ARCH_FUNCS(6);
DEVICE_PER_ARCH_FUNCS(7);
VKAPI_ATTR VkResult VKAPI_CALL
panvk_CreateDevice(VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
{
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
unsigned arch = pan_arch(physical_device->kmod.props.gpu_prod_id);
VkResult result = VK_ERROR_INITIALIZATION_FAILED;
panvk_arch_dispatch_ret(arch, create_device, result, physical_device,
pCreateInfo, pAllocator, pDevice);
return result;
}
VKAPI_ATTR void VKAPI_CALL
panvk_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
{
VK_FROM_HANDLE(panvk_device, device, _device);
struct panvk_physical_device *physical_device =
to_panvk_physical_device(device->vk.physical);
unsigned arch = pan_arch(physical_device->kmod.props.gpu_prod_id);
panvk_arch_dispatch(arch, destroy_device, device, pAllocator);
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceExternalSemaphoreProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
VkExternalSemaphoreProperties *pExternalSemaphoreProperties)
{
if ((pExternalSemaphoreInfo->handleType ==
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT ||
pExternalSemaphoreInfo->handleType ==
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) {
pExternalSemaphoreProperties->exportFromImportedHandleTypes =
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT |
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
pExternalSemaphoreProperties->compatibleHandleTypes =
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT |
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
pExternalSemaphoreProperties->externalSemaphoreFeatures =
VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
} else {
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
}
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceExternalFenceProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
VkExternalFenceProperties *pExternalFenceProperties)
{
pExternalFenceProperties->exportFromImportedHandleTypes = 0;
pExternalFenceProperties->compatibleHandleTypes = 0;
pExternalFenceProperties->externalFenceFeatures = 0;
}

View file

@ -1,485 +0,0 @@
/*
* Copyright © 2021 Collabora Ltd.
*
* Derived from tu_formats.c which is:
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "panvk_private.h"
#include "panfrost/lib/pan_texture.h"
#include "util/format_r11g11b10f.h"
#include "util/format_srgb.h"
#include "util/half_float.h"
#include "vk_format.h"
#include "vk_util.h"
static void
get_format_properties(struct panvk_physical_device *physical_device,
VkFormat format, VkFormatProperties *out_properties)
{
VkFormatFeatureFlags tex = 0, buffer = 0;
enum pipe_format pfmt = vk_format_to_pipe_format(format);
const struct panfrost_format fmt = physical_device->formats.all[pfmt];
if (!pfmt || !fmt.hw)
goto end;
/* 3byte formats are not supported by the buffer <-> image copy helpers. */
if (util_format_get_blocksize(pfmt) == 3)
goto end;
/* We don't support compressed formats yet: this is causing trouble when
* doing a vkCmdCopyImage() between a compressed and a non-compressed format
* on a tiled/AFBC resource.
*/
if (util_format_is_compressed(pfmt))
goto end;
buffer |=
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
if (fmt.bind & PAN_BIND_VERTEX_BUFFER)
buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
if (fmt.bind & PAN_BIND_SAMPLER_VIEW) {
tex |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT |
VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
/* Integer formats only support nearest filtering */
if (!util_format_is_scaled(pfmt) && !util_format_is_pure_integer(pfmt))
tex |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
tex |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
}
/* SNORM rendering isn't working yet, disable */
if (fmt.bind & PAN_BIND_RENDER_TARGET && !util_format_is_snorm(pfmt)) {
tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_BLIT_DST_BIT;
tex |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
/* Can always blend via blend shaders */
tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
}
if (fmt.bind & PAN_BIND_DEPTH_STENCIL)
tex |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
end:
out_properties->linearTilingFeatures = tex;
out_properties->optimalTilingFeatures = tex;
out_properties->bufferFeatures = buffer;
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
VkFormat format,
VkFormatProperties *pFormatProperties)
{
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
get_format_properties(physical_device, format, pFormatProperties);
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
VkFormat format,
VkFormatProperties2 *pFormatProperties)
{
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
get_format_properties(physical_device, format,
&pFormatProperties->formatProperties);
VkDrmFormatModifierPropertiesListEXT *list = vk_find_struct(
pFormatProperties->pNext, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT);
if (list) {
VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out,
list->pDrmFormatModifierProperties,
&list->drmFormatModifierCount);
vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out,
mod_props)
{
mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
mod_props->drmFormatModifierPlaneCount = 1;
}
}
}
static VkResult
get_image_format_properties(struct panvk_physical_device *physical_device,
const VkPhysicalDeviceImageFormatInfo2 *info,
VkImageFormatProperties *pImageFormatProperties,
VkFormatFeatureFlags *p_feature_flags)
{
VkFormatProperties format_props;
VkFormatFeatureFlags format_feature_flags;
VkExtent3D maxExtent;
uint32_t maxMipLevels;
uint32_t maxArraySize;
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
enum pipe_format format = vk_format_to_pipe_format(info->format);
get_format_properties(physical_device, info->format, &format_props);
switch (info->tiling) {
case VK_IMAGE_TILING_LINEAR:
format_feature_flags = format_props.linearTilingFeatures;
break;
case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
/* The only difference between optimal and linear is currently whether
* depth/stencil attachments are allowed on depth/stencil formats.
* There's no reason to allow importing depth/stencil textures, so just
* disallow it and then this annoying edge case goes away.
*
* TODO: If anyone cares, we could enable this by looking at the
* modifier and checking if it's LINEAR or not.
*/
if (util_format_is_depth_or_stencil(format))
goto unsupported;
assert(format_props.optimalTilingFeatures ==
format_props.linearTilingFeatures);
FALLTHROUGH;
case VK_IMAGE_TILING_OPTIMAL:
format_feature_flags = format_props.optimalTilingFeatures;
break;
default:
unreachable("bad VkPhysicalDeviceImageFormatInfo2");
}
if (format_feature_flags == 0)
goto unsupported;
if (info->type != VK_IMAGE_TYPE_2D &&
util_format_is_depth_or_stencil(format))
goto unsupported;
switch (info->type) {
default:
unreachable("bad vkimage type");
case VK_IMAGE_TYPE_1D:
maxExtent.width = 16384;
maxExtent.height = 1;
maxExtent.depth = 1;
maxMipLevels = 15; /* log2(maxWidth) + 1 */
maxArraySize = 2048;
break;
case VK_IMAGE_TYPE_2D:
maxExtent.width = 16384;
maxExtent.height = 16384;
maxExtent.depth = 1;
maxMipLevels = 15; /* log2(maxWidth) + 1 */
maxArraySize = 2048;
break;
case VK_IMAGE_TYPE_3D:
maxExtent.width = 2048;
maxExtent.height = 2048;
maxExtent.depth = 2048;
maxMipLevels = 12; /* log2(maxWidth) + 1 */
maxArraySize = 1;
break;
}
if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
info->type == VK_IMAGE_TYPE_2D &&
(format_feature_flags &
(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
!(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
!(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
}
if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
if (!(format_feature_flags &
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
goto unsupported;
}
}
*pImageFormatProperties = (VkImageFormatProperties){
.maxExtent = maxExtent,
.maxMipLevels = maxMipLevels,
.maxArrayLayers = maxArraySize,
.sampleCounts = sampleCounts,
/* FINISHME: Accurately calculate
* VkImageFormatProperties::maxResourceSize.
*/
.maxResourceSize = UINT32_MAX,
};
if (p_feature_flags)
*p_feature_flags = format_feature_flags;
return VK_SUCCESS;
unsupported:
*pImageFormatProperties = (VkImageFormatProperties){
.maxExtent = {0, 0, 0},
.maxMipLevels = 0,
.maxArrayLayers = 0,
.sampleCounts = 0,
.maxResourceSize = 0,
};
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
VKAPI_ATTR VkResult VKAPI_CALL
panvk_GetPhysicalDeviceImageFormatProperties(
VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
VkImageTiling tiling, VkImageUsageFlags usage,
VkImageCreateFlags createFlags,
VkImageFormatProperties *pImageFormatProperties)
{
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
const VkPhysicalDeviceImageFormatInfo2 info = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
.pNext = NULL,
.format = format,
.type = type,
.tiling = tiling,
.usage = usage,
.flags = createFlags,
};
return get_image_format_properties(physical_device, &info,
pImageFormatProperties, NULL);
}
static VkResult
panvk_get_external_image_format_properties(
const struct panvk_physical_device *physical_device,
const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
VkExternalMemoryHandleTypeFlagBits handleType,
VkExternalMemoryProperties *external_properties)
{
VkExternalMemoryFeatureFlagBits flags = 0;
VkExternalMemoryHandleTypeFlags export_flags = 0;
VkExternalMemoryHandleTypeFlags compat_flags = 0;
/* From the Vulkan 1.1.98 spec:
*
* If handleType is not compatible with the format, type, tiling,
* usage, and flags specified in VkPhysicalDeviceImageFormatInfo2,
* then vkGetPhysicalDeviceImageFormatProperties2 returns
* VK_ERROR_FORMAT_NOT_SUPPORTED.
*/
switch (handleType) {
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
switch (pImageFormatInfo->type) {
case VK_IMAGE_TYPE_2D:
flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
compat_flags = export_flags =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
break;
default:
return vk_errorf(
physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
"VkExternalMemoryTypeFlagBits(0x%x) unsupported for VkImageType(%d)",
handleType, pImageFormatInfo->type);
}
break;
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
break;
default:
return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
"VkExternalMemoryTypeFlagBits(0x%x) unsupported",
handleType);
}
*external_properties = (VkExternalMemoryProperties){
.externalMemoryFeatures = flags,
.exportFromImportedHandleTypes = export_flags,
.compatibleHandleTypes = compat_flags,
};
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL
panvk_GetPhysicalDeviceImageFormatProperties2(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceImageFormatInfo2 *base_info,
VkImageFormatProperties2 *base_props)
{
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL;
VkExternalImageFormatProperties *external_props = NULL;
VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
VkFormatFeatureFlags format_feature_flags;
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
VkResult result;
result = get_image_format_properties(physical_device, base_info,
&base_props->imageFormatProperties,
&format_feature_flags);
if (result != VK_SUCCESS)
return result;
/* Extract input structs */
vk_foreach_struct_const(s, base_info->pNext) {
switch (s->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
external_info = (const void *)s;
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT:
image_view_info = (const void *)s;
break;
default:
break;
}
}
/* Extract output structs */
vk_foreach_struct(s, base_props->pNext) {
switch (s->sType) {
case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
external_props = (void *)s;
break;
case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:
cubic_props = (void *)s;
break;
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
ycbcr_props = (void *)s;
break;
default:
break;
}
}
/* From the Vulkan 1.0.42 spec:
*
* If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
* behave as if VkPhysicalDeviceExternalImageFormatInfo was not
* present and VkExternalImageFormatProperties will be ignored.
*/
if (external_info && external_info->handleType != 0) {
result = panvk_get_external_image_format_properties(
physical_device, base_info, external_info->handleType,
&external_props->externalMemoryProperties);
if (result != VK_SUCCESS)
goto fail;
}
if (cubic_props) {
/* note: blob only allows cubic filtering for 2D and 2D array views
* its likely we can enable it for 1D and CUBE, needs testing however
*/
if ((image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D ||
image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) &&
(format_feature_flags &
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) {
cubic_props->filterCubic = true;
cubic_props->filterCubicMinmax = true;
} else {
cubic_props->filterCubic = false;
cubic_props->filterCubicMinmax = false;
}
}
if (ycbcr_props)
ycbcr_props->combinedImageSamplerDescriptorCount = 1;
return VK_SUCCESS;
fail:
if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
/* From the Vulkan 1.0.42 spec:
*
* If the combination of parameters to
* vkGetPhysicalDeviceImageFormatProperties2 is not supported by
* the implementation for use in vkCreateImage, then all members of
* imageFormatProperties will be filled with zero.
*/
base_props->imageFormatProperties = (VkImageFormatProperties){};
}
return result;
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceSparseImageFormatProperties(
VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling,
uint32_t *pNumProperties, VkSparseImageFormatProperties *pProperties)
{
/* Sparse images are not yet supported. */
*pNumProperties = 0;
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceSparseImageFormatProperties2(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
uint32_t *pPropertyCount, VkSparseImageFormatProperties2 *pProperties)
{
/* Sparse images are not yet supported. */
*pPropertyCount = 0;
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetPhysicalDeviceExternalBufferProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
VkExternalBufferProperties *pExternalBufferProperties)
{
panvk_stub();
}

View file

@ -31,6 +31,7 @@
#include "panvk_device_memory.h"
#include "panvk_image.h"
#include "panvk_instance.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
#include "drm-uapi/drm_fourcc.h"

View file

@ -14,6 +14,7 @@
#include "panvk_entrypoints.h"
#include "panvk_instance.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
static const struct debug_control panvk_debug_options[] = {

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
/*
* Copyright © 2021 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#ifndef PANVK_PHYSICAL_DEVICE_H
#define PANVK_PHYSICAL_DEVICE_H
#include <stdint.h>
#include "panvk_instance.h"
#include "vk_physical_device.h"
#include "vk_sync.h"
#include "wsi_common.h"
#include "lib/kmod/pan_kmod.h"
struct panfrost_model;
struct pan_blendable_format;
struct panfrost_format;
struct panvk_instance;
struct panvk_physical_device {
struct vk_physical_device vk;
struct {
struct pan_kmod_dev *dev;
struct pan_kmod_dev_props props;
} kmod;
const struct panfrost_model *model;
struct {
const struct pan_blendable_format *blendable;
const struct panfrost_format *all;
} formats;
char name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
uint8_t driver_uuid[VK_UUID_SIZE];
uint8_t device_uuid[VK_UUID_SIZE];
uint8_t cache_uuid[VK_UUID_SIZE];
struct vk_sync_type drm_syncobj_type;
const struct vk_sync_type *sync_types[2];
struct wsi_device wsi_device;
int master_fd;
};
VK_DEFINE_HANDLE_CASTS(panvk_physical_device, vk.base, VkPhysicalDevice,
VK_OBJECT_TYPE_PHYSICAL_DEVICE)
static inline struct panvk_physical_device *
to_panvk_physical_device(struct vk_physical_device *phys_dev)
{
return container_of(phys_dev, struct panvk_physical_device, vk);
}
VkResult panvk_physical_device_init(struct panvk_physical_device *device,
struct panvk_instance *instance,
drmDevicePtr drm_device);
void panvk_physical_device_finish(struct panvk_physical_device *device);
#endif

View file

@ -72,6 +72,7 @@
#include "panvk_instance.h"
#include "panvk_macros.h"
#include "panvk_mempool.h"
#include "panvk_physical_device.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_shader.h"
@ -187,52 +188,9 @@ struct panvk_meta {
} copy;
};
struct panvk_physical_device {
struct vk_physical_device vk;
struct {
struct pan_kmod_dev *dev;
struct pan_kmod_dev_props props;
} kmod;
const struct panfrost_model *model;
struct {
const struct pan_blendable_format *blendable;
const struct panfrost_format *all;
} formats;
char name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
uint8_t driver_uuid[VK_UUID_SIZE];
uint8_t device_uuid[VK_UUID_SIZE];
uint8_t cache_uuid[VK_UUID_SIZE];
struct vk_sync_type drm_syncobj_type;
const struct vk_sync_type *sync_types[2];
struct wsi_device wsi_device;
int master_fd;
};
static inline struct panvk_physical_device *
to_panvk_physical_device(struct vk_physical_device *phys_dev)
{
return container_of(phys_dev, struct panvk_physical_device, vk);
}
VkResult panvk_wsi_init(struct panvk_physical_device *physical_device);
void panvk_wsi_finish(struct panvk_physical_device *physical_device);
uint32_t panvk_physical_device_api_version(struct panvk_physical_device *dev);
bool
panvk_physical_device_extension_supported(struct panvk_physical_device *dev,
const char *name);
void panvk_physical_device_finish(struct panvk_physical_device *device);
VkResult panvk_physical_device_init(struct panvk_physical_device *device,
struct panvk_instance *instance,
drmDevicePtr drm_device);
#define PANVK_MAX_QUEUE_FAMILIES 1
struct panvk_device {
@ -446,8 +404,6 @@ void panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf);
VK_DEFINE_HANDLE_CASTS(panvk_cmd_buffer, vk.base, VkCommandBuffer,
VK_OBJECT_TYPE_COMMAND_BUFFER)
VK_DEFINE_HANDLE_CASTS(panvk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
VK_DEFINE_HANDLE_CASTS(panvk_physical_device, vk.base, VkPhysicalDevice,
VK_OBJECT_TYPE_PHYSICAL_DEVICE)
#ifdef PAN_ARCH
#include "panvk_vX_cmd_buffer.h"

View file

@ -34,6 +34,7 @@
#include "panvk_image.h"
#include "panvk_image_view.h"
#include "panvk_instance.h"
#include "panvk_physical_device.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"

View file

@ -14,6 +14,7 @@
#include "panvk_instance.h"
#include "panvk_macros.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
#include "panvk_queue.h"

View file

@ -27,6 +27,7 @@
#include "pan_props.h"
#include "panvk_image.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
static void

View file

@ -28,6 +28,7 @@
#include "pan_shader.h"
#include "panvk_image.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
#include "panvk_vX_meta.h"

View file

@ -30,6 +30,7 @@
#include "panvk_buffer.h"
#include "panvk_image.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
static mali_ptr

View file

@ -17,6 +17,7 @@
#include "panvk_image.h"
#include "panvk_image_view.h"
#include "panvk_instance.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
#include "panvk_queue.h"

View file

@ -30,6 +30,7 @@
#include "genxml/gen_macros.h"
#include "panvk_instance.h"
#include "panvk_physical_device.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "panvk_shader.h"

View file

@ -26,6 +26,7 @@
*/
#include "panvk_instance.h"
#include "panvk_physical_device.h"
#include "panvk_private.h"
#include "vk_util.h"