X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fzink%2Fzink_screen.c;h=36c89e68324843c5a4cf5b732b466bc060192a77;hb=75b59bb1d6573bd7b16758e528a265623889e551;hp=260d4bf90db3551bd75463e47b9125fb048619d6;hpb=4480aefc38ab9bbac965d36942ee8c0111a4f988;p=mesa.git diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 260d4bf90db..36c89e68324 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -31,13 +31,13 @@ #include "os/os_process.h" #include "util/u_debug.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_screen.h" #include "util/u_string.h" -#include "state_tracker/sw_winsys.h" +#include "frontend/sw_winsys.h" static const struct debug_named_value debug_options[] = { @@ -80,8 +80,11 @@ static int get_video_mem(struct zink_screen *screen) { VkDeviceSize size = 0; - for (uint32_t i = 0; i < screen->mem_props.memoryHeapCount; ++i) - size += screen->mem_props.memoryHeaps[i].size; + for (uint32_t i = 0; i < screen->mem_props.memoryHeapCount; ++i) { + if (screen->mem_props.memoryHeaps[i].flags & + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + size += screen->mem_props.memoryHeaps[i].size; + } return (int)(size >> 20); } @@ -95,6 +98,8 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: + if (!screen->feats.dualSrcBlend) + return 0; return screen->props.limits.maxFragmentDualSrcAttachments; case PIPE_CAP_POINT_SPRITE: @@ -104,8 +109,15 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return screen->props.limits.maxColorAttachments; case PIPE_CAP_OCCLUSION_QUERY: + return 1; + +#if 0 /* TODO: Enable me */ case PIPE_CAP_QUERY_TIME_ELAPSED: return 1; +#endif + + case PIPE_CAP_TEXTURE_MULTISAMPLE: + return 1; case PIPE_CAP_TEXTURE_SWIZZLE: return 1; @@ -118,8 +130,6 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1 + util_logbase2(screen->props.limits.maxImageDimensionCube); case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 1; - case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: case PIPE_CAP_VERTEX_SHADER_SATURATE: @@ -129,6 +139,12 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_INDEP_BLEND_FUNC: return 1; + case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: + return screen->have_EXT_transform_feedback ? screen->tf_props.maxTransformFeedbackBuffers : 0; + case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: + case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: + return 1; + case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: return screen->props.limits.maxImageArrayLayers; @@ -137,11 +153,8 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 0; #endif -#if 0 /* TODO: Enable me */ + case PIPE_CAP_TGSI_INSTANCEID: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: - return 1; -#endif - case PIPE_CAP_SEAMLESS_CUBE_MAP: return 1; @@ -153,9 +166,12 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: return 1; + case PIPE_CAP_CONDITIONAL_RENDER: + return screen->have_EXT_conditional_rendering; + case PIPE_CAP_GLSL_FEATURE_LEVEL: case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: - return 450; /* unsure (probably wrong) */ + return 130; #if 0 /* TODO: Enable me */ case PIPE_CAP_COMPUTE: @@ -165,8 +181,10 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: return screen->props.limits.minUniformBufferOffsetAlignment; +#if 0 /* TODO: Enable me */ case PIPE_CAP_QUERY_TIMESTAMP: return 1; +#endif case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: return screen->props.limits.minMemoryMapAlignment; @@ -174,6 +192,12 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CUBE_MAP_ARRAY: return screen->feats.imageCubeArray; + case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: + return 1; + + case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: + return screen->props.limits.minTexelBufferOffsetAlignment; + case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: return 0; /* unsure */ @@ -184,7 +208,7 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return PIPE_ENDIAN_NATIVE; /* unsure */ case PIPE_CAP_MAX_VIEWPORTS: - return screen->props.limits.maxViewports; + return 1; /* TODO: When GS is supported, use screen->props.limits.maxViewports */ case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: return 1; @@ -204,6 +228,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: return screen->props.limits.maxTexelGatherOffset; + case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: + return 1; + case PIPE_CAP_VENDOR_ID: return screen->props.vendorID; case PIPE_CAP_DEVICE_ID: @@ -214,7 +241,6 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VIDEO_MEMORY: return get_video_mem(screen); case PIPE_CAP_UMA: - /* inaccurate */ return screen->props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: @@ -225,6 +251,11 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; #endif +#if 0 /* TODO: Enable me */ + case PIPE_CAP_CLIP_HALFZ: + return 1; +#endif + #if 0 /* TODO: Enable me */ case PIPE_CAP_TEXTURE_FLOAT_LINEAR: case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: @@ -245,10 +276,8 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_PCI_FUNCTION: return 0; /* TODO: figure these out */ -#if 0 /* TODO: Enable me */ case PIPE_CAP_CULL_DISTANCE: return screen->feats.shaderCullDistance; -#endif case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: return screen->props.limits.viewportSubPixelBits; @@ -274,16 +303,27 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 0; case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: - return 1; + return 0; case PIPE_CAP_NIR_COMPACT_ARRAYS: return 1; + case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL: + return 1; + + case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED: + return 1; + case PIPE_CAP_FLATSHADE: case PIPE_CAP_ALPHA_TEST: case PIPE_CAP_CLIP_PLANES: + case PIPE_CAP_POINT_SIZE_FIXED: + case PIPE_CAP_TWO_SIDED_COLOR: return 0; + case PIPE_CAP_DMABUF: + return screen->have_KHR_external_memory_fd; + default: return u_pipe_screen_get_param_defaults(pscreen, param); } @@ -362,9 +402,15 @@ zink_get_shader_param(struct pipe_screen *pscreen, } case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: - /* this might be a bit simplistic... */ - return MIN2(screen->props.limits.maxPerStageDescriptorSamplers, - PIPE_MAX_SAMPLERS); + switch (shader) { + case PIPE_SHADER_VERTEX: + case PIPE_SHADER_FRAGMENT: + /* this might be a bit simplistic... */ + return MIN2(screen->props.limits.maxPerStageDescriptorSamplers, + PIPE_MAX_SAMPLERS); + default: + return 0; /* unsupported stage */ + } case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: return MIN2(screen->props.limits.maxUniformBufferRange, INT_MAX); @@ -375,14 +421,19 @@ zink_get_shader_param(struct pipe_screen *pscreen, case PIPE_SHADER_CAP_MAX_TEMPS: return INT_MAX; + case PIPE_SHADER_CAP_INTEGERS: + return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: case PIPE_SHADER_CAP_SUBROUTINES: - case PIPE_SHADER_CAP_INTEGERS: case PIPE_SHADER_CAP_INT64_ATOMICS: case PIPE_SHADER_CAP_FP16: + case PIPE_SHADER_CAP_FP16_DERIVATIVES: + case PIPE_SHADER_CAP_INT16: + case PIPE_SHADER_CAP_GLSL_16BIT_TEMPS: return 0; /* not implemented */ case PIPE_SHADER_CAP_PREFERRED_IR: @@ -414,8 +465,12 @@ zink_get_shader_param(struct pipe_screen *pscreen, return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI); case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: +#if 0 /* TODO: needs compiler support */ return MIN2(screen->props.limits.maxPerStageDescriptorStorageImages, PIPE_MAX_SHADER_IMAGES); +#else + return 0; +#endif case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS: @@ -432,128 +487,6 @@ zink_get_shader_param(struct pipe_screen *pscreen, return 0; } -static const VkFormat formats[PIPE_FORMAT_COUNT] = { -#define MAP_FORMAT_NORM(FMT) \ - [PIPE_FORMAT_ ## FMT ## _UNORM] = VK_FORMAT_ ## FMT ## _UNORM, \ - [PIPE_FORMAT_ ## FMT ## _SNORM] = VK_FORMAT_ ## FMT ## _SNORM, - -#define MAP_FORMAT_SCALED(FMT) \ - [PIPE_FORMAT_ ## FMT ## _USCALED] = VK_FORMAT_ ## FMT ## _USCALED, \ - [PIPE_FORMAT_ ## FMT ## _SSCALED] = VK_FORMAT_ ## FMT ## _SSCALED, - -#define MAP_FORMAT_INT(FMT) \ - [PIPE_FORMAT_ ## FMT ## _UINT] = VK_FORMAT_ ## FMT ## _UINT, \ - [PIPE_FORMAT_ ## FMT ## _SINT] = VK_FORMAT_ ## FMT ## _SINT, - -#define MAP_FORMAT_SRGB(FMT) \ - [PIPE_FORMAT_ ## FMT ## _SRGB] = VK_FORMAT_ ## FMT ## _SRGB, - -#define MAP_FORMAT_FLOAT(FMT) \ - [PIPE_FORMAT_ ## FMT ## _FLOAT] = VK_FORMAT_ ## FMT ## _SFLOAT, - - // one component - - // 8-bits - MAP_FORMAT_NORM(R8) - MAP_FORMAT_SCALED(R8) - MAP_FORMAT_INT(R8) - // 16-bits - MAP_FORMAT_NORM(R16) - MAP_FORMAT_SCALED(R16) - MAP_FORMAT_INT(R16) - MAP_FORMAT_FLOAT(R16) - // 32-bits - MAP_FORMAT_INT(R32) - MAP_FORMAT_FLOAT(R32) - - // two components - - // 8-bits - MAP_FORMAT_NORM(R8G8) - MAP_FORMAT_SCALED(R8G8) - MAP_FORMAT_INT(R8G8) - // 16-bits - MAP_FORMAT_NORM(R16G16) - MAP_FORMAT_SCALED(R16G16) - MAP_FORMAT_INT(R16G16) - MAP_FORMAT_FLOAT(R16G16) - // 32-bits - MAP_FORMAT_INT(R32G32) - MAP_FORMAT_FLOAT(R32G32) - - // three components - - // 8-bits - MAP_FORMAT_NORM(R8G8B8) - MAP_FORMAT_SCALED(R8G8B8) - MAP_FORMAT_INT(R8G8B8) - MAP_FORMAT_SRGB(R8G8B8) - // 16-bits - MAP_FORMAT_NORM(R16G16B16) - MAP_FORMAT_SCALED(R16G16B16) - MAP_FORMAT_INT(R16G16B16) - MAP_FORMAT_FLOAT(R16G16B16) - // 32-bits - MAP_FORMAT_INT(R32G32B32) - MAP_FORMAT_FLOAT(R32G32B32) - - // four components - - // 8-bits - MAP_FORMAT_NORM(R8G8B8A8) - MAP_FORMAT_SCALED(R8G8B8A8) - MAP_FORMAT_INT(R8G8B8A8) - MAP_FORMAT_SRGB(R8G8B8A8) - [PIPE_FORMAT_B8G8R8A8_UNORM] = VK_FORMAT_B8G8R8A8_UNORM, - MAP_FORMAT_SRGB(B8G8R8A8) - [PIPE_FORMAT_A8B8G8R8_SRGB] = VK_FORMAT_A8B8G8R8_SRGB_PACK32, - // 16-bits - MAP_FORMAT_NORM(R16G16B16A16) - MAP_FORMAT_SCALED(R16G16B16A16) - MAP_FORMAT_INT(R16G16B16A16) - MAP_FORMAT_FLOAT(R16G16B16A16) - // 32-bits - MAP_FORMAT_INT(R32G32B32A32) - MAP_FORMAT_FLOAT(R32G32B32A32) - - // other color formats - [PIPE_FORMAT_B5G6R5_UNORM] = VK_FORMAT_R5G6B5_UNORM_PACK16, - [PIPE_FORMAT_B5G5R5A1_UNORM] = VK_FORMAT_B5G5R5A1_UNORM_PACK16, - [PIPE_FORMAT_R11G11B10_FLOAT] = VK_FORMAT_B10G11R11_UFLOAT_PACK32, - [PIPE_FORMAT_R9G9B9E5_FLOAT] = VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, - [PIPE_FORMAT_R10G10B10A2_UNORM] = VK_FORMAT_A2B10G10R10_UNORM_PACK32, - [PIPE_FORMAT_B10G10R10A2_UNORM] = VK_FORMAT_A2R10G10B10_UNORM_PACK32, - [PIPE_FORMAT_R10G10B10A2_UINT] = VK_FORMAT_A2B10G10R10_UINT_PACK32, - [PIPE_FORMAT_B10G10R10A2_UINT] = VK_FORMAT_A2R10G10B10_UINT_PACK32, - - // depth/stencil formats - [PIPE_FORMAT_Z32_FLOAT] = VK_FORMAT_D32_SFLOAT, - [PIPE_FORMAT_Z32_FLOAT_S8X24_UINT] = VK_FORMAT_D32_SFLOAT_S8_UINT, - [PIPE_FORMAT_Z16_UNORM] = VK_FORMAT_D16_UNORM, - [PIPE_FORMAT_X8Z24_UNORM] = VK_FORMAT_X8_D24_UNORM_PACK32, - [PIPE_FORMAT_Z24_UNORM_S8_UINT] = VK_FORMAT_D24_UNORM_S8_UINT, - - // compressed formats - [PIPE_FORMAT_DXT1_RGB] = VK_FORMAT_BC1_RGB_UNORM_BLOCK, - [PIPE_FORMAT_DXT1_RGBA] = VK_FORMAT_BC1_RGBA_UNORM_BLOCK, - [PIPE_FORMAT_DXT3_RGBA] = VK_FORMAT_BC2_UNORM_BLOCK, - [PIPE_FORMAT_DXT5_RGBA] = VK_FORMAT_BC3_UNORM_BLOCK, - [PIPE_FORMAT_RGTC1_UNORM] = VK_FORMAT_BC4_UNORM_BLOCK, - [PIPE_FORMAT_RGTC1_SNORM] = VK_FORMAT_BC4_SNORM_BLOCK, - [PIPE_FORMAT_RGTC2_UNORM] = VK_FORMAT_BC5_UNORM_BLOCK, - [PIPE_FORMAT_RGTC2_SNORM] = VK_FORMAT_BC5_SNORM_BLOCK, - [PIPE_FORMAT_BPTC_RGBA_UNORM] = VK_FORMAT_BC7_UNORM_BLOCK, - [PIPE_FORMAT_BPTC_SRGBA] = VK_FORMAT_BC7_SRGB_BLOCK, - [PIPE_FORMAT_BPTC_RGB_FLOAT] = VK_FORMAT_BC6H_SFLOAT_BLOCK, - [PIPE_FORMAT_BPTC_RGB_UFLOAT] = VK_FORMAT_BC6H_UFLOAT_BLOCK, -}; - -VkFormat -zink_get_format(enum pipe_format format) -{ - return formats[format]; -} - static VkSampleCountFlagBits vk_sample_count_flags(uint32_t sample_count) { @@ -584,44 +517,46 @@ zink_is_format_supported(struct pipe_screen *pscreen, return screen->props.limits.framebufferNoAttachmentsSampleCounts & vk_sample_count_flags(sample_count); - VkFormat vkformat = formats[format]; + VkFormat vkformat = zink_get_format(screen, format); if (vkformat == VK_FORMAT_UNDEFINED) - return FALSE; + return false; - const struct util_format_description *desc = util_format_description(format); if (sample_count >= 1) { VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count); + if (!sample_mask) + return false; + const struct util_format_description *desc = util_format_description(format); if (util_format_is_depth_or_stencil(format)) { if (util_format_has_depth(desc)) { if (bind & PIPE_BIND_DEPTH_STENCIL && (screen->props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask) - return FALSE; + return false; if (bind & PIPE_BIND_SAMPLER_VIEW && (screen->props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask) - return FALSE; + return false; } if (util_format_has_stencil(desc)) { if (bind & PIPE_BIND_DEPTH_STENCIL && (screen->props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask) - return FALSE; + return false; if (bind & PIPE_BIND_SAMPLER_VIEW && (screen->props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask) - return FALSE; + return false; } } else if (util_format_is_pure_integer(format)) { if (bind & PIPE_BIND_RENDER_TARGET && !(screen->props.limits.framebufferColorSampleCounts & sample_mask)) - return FALSE; + return false; if (bind & PIPE_BIND_SAMPLER_VIEW && !(screen->props.limits.sampledImageIntegerSampleCounts & sample_mask)) - return FALSE; + return false; } else { if (bind & PIPE_BIND_RENDER_TARGET && !(screen->props.limits.framebufferColorSampleCounts & sample_mask)) - return FALSE; + return false; if (bind & PIPE_BIND_SAMPLER_VIEW && !(screen->props.limits.sampledImageColorSampleCounts & sample_mask)) - return FALSE; + return false; } } @@ -631,31 +566,34 @@ zink_is_format_supported(struct pipe_screen *pscreen, if (target == PIPE_BUFFER) { if (bind & PIPE_BIND_VERTEX_BUFFER && !(props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) - return FALSE; + return false; } else { /* all other targets are texture-targets */ if (bind & PIPE_BIND_RENDER_TARGET && !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) - return FALSE; + return false; if (bind & PIPE_BIND_BLENDABLE && !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) - return FALSE; + return false; if (bind & PIPE_BIND_SAMPLER_VIEW && !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) - return FALSE; + return false; if (bind & PIPE_BIND_DEPTH_STENCIL && !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) - return FALSE; + return false; } - if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC && - !screen->feats.textureCompressionBC) - return FALSE; + if (util_format_is_compressed(format)) { + const struct util_format_description *desc = util_format_description(format); + if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC && + !screen->feats.textureCompressionBC) + return false; + } - return TRUE; + return true; } static void @@ -789,10 +727,40 @@ zink_flush_frontbuffer(struct pipe_screen *pscreen, winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box); } +static bool +load_device_extensions(struct zink_screen *screen) +{ +#define GET_PROC_ADDR(x) do { \ + screen->vk_##x = (PFN_vk##x)vkGetDeviceProcAddr(screen->dev, "vk"#x); \ + if (!screen->vk_##x) \ + return false; \ + } while (0) + if (screen->have_EXT_transform_feedback) { + GET_PROC_ADDR(CmdBindTransformFeedbackBuffersEXT); + GET_PROC_ADDR(CmdBeginTransformFeedbackEXT); + GET_PROC_ADDR(CmdEndTransformFeedbackEXT); + GET_PROC_ADDR(CmdBeginQueryIndexedEXT); + GET_PROC_ADDR(CmdEndQueryIndexedEXT); + GET_PROC_ADDR(CmdDrawIndirectByteCountEXT); + } + if (screen->have_KHR_external_memory_fd) + GET_PROC_ADDR(GetMemoryFdKHR); + + if (screen->have_EXT_conditional_rendering) { + GET_PROC_ADDR(CmdBeginConditionalRenderingEXT); + GET_PROC_ADDR(CmdEndConditionalRenderingEXT); + } + +#undef GET_PROC_ADDR + + return true; +} + static struct pipe_screen * zink_internal_create_screen(struct sw_winsys *winsys, int fd) { struct zink_screen *screen = CALLOC_STRUCT(zink_screen); + bool have_tf_ext = false, have_cond_render_ext = false, have_EXT_index_type_uint8 = false; if (!screen) return NULL; @@ -802,10 +770,13 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd) screen->pdev = choose_pdev(screen->instance); screen->gfx_queue = find_gfx_queue(screen->pdev); - vkGetPhysicalDeviceProperties(screen->pdev, &screen->props); - vkGetPhysicalDeviceFeatures(screen->pdev, &screen->feats); vkGetPhysicalDeviceMemoryProperties(screen->pdev, &screen->mem_props); + screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen, + VK_FORMAT_X8_D24_UNORM_PACK32); + screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen, + VK_FORMAT_D24_UNORM_S8_UINT); + uint32_t num_extensions = 0; if (vkEnumerateDeviceExtensionProperties(screen->pdev, NULL, &num_extensions, NULL) == VK_SUCCESS && num_extensions > 0) { @@ -817,12 +788,69 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd) for (uint32_t i = 0; i < num_extensions; ++i) { if (!strcmp(extensions[i].extensionName, - VK_KHR_MAINTENANCE1_EXTENSION_NAME)) - screen->have_VK_KHR_maintenance1 = true; + VK_KHR_MAINTENANCE1_EXTENSION_NAME)) + screen->have_KHR_maintenance1 = true; + if (!strcmp(extensions[i].extensionName, + VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME)) + screen->have_KHR_external_memory_fd = true; + if (!strcmp(extensions[i].extensionName, + VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME)) + have_cond_render_ext = true; + if (!strcmp(extensions[i].extensionName, + VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) + have_tf_ext = true; + if (!strcmp(extensions[i].extensionName, + VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME)) + have_EXT_index_type_uint8 = true; + } FREE(extensions); } } + VkPhysicalDeviceFeatures2 feats = {}; + VkPhysicalDeviceTransformFeedbackFeaturesEXT tf_feats = {}; + VkPhysicalDeviceConditionalRenderingFeaturesEXT cond_render_feats = {}; + VkPhysicalDeviceIndexTypeUint8FeaturesEXT index_uint8_feats = {}; + + feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + if (have_tf_ext) { + tf_feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; + tf_feats.pNext = feats.pNext; + feats.pNext = &tf_feats; + } + if (have_cond_render_ext) { + cond_render_feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT; + cond_render_feats.pNext = feats.pNext; + feats.pNext = &cond_render_feats; + } + if (have_EXT_index_type_uint8) { + index_uint8_feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT; + index_uint8_feats.pNext = feats.pNext; + feats.pNext = &index_uint8_feats; + } + vkGetPhysicalDeviceFeatures2(screen->pdev, &feats); + memcpy(&screen->feats, &feats.features, sizeof(screen->feats)); + if (have_tf_ext && tf_feats.transformFeedback) + screen->have_EXT_transform_feedback = true; + if (have_cond_render_ext && cond_render_feats.conditionalRendering) + screen->have_EXT_conditional_rendering = true; + if (have_EXT_index_type_uint8 && index_uint8_feats.indexTypeUint8) + screen->have_EXT_index_type_uint8 = true; + + VkPhysicalDeviceProperties2 props = {}; + props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + if (screen->have_EXT_transform_feedback) { + screen->tf_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; + screen->tf_props.pNext = NULL; + props.pNext = &screen->tf_props; + } + vkGetPhysicalDeviceProperties2(screen->pdev, &props); + memcpy(&screen->props, &props.properties, sizeof(screen->props)); + + if (!screen->have_KHR_maintenance1) { + debug_printf("ZINK: VK_KHR_maintenance1 required!\n"); + goto fail; + } VkDeviceQueueCreateInfo qci = {}; float dummy = 0.0f; @@ -835,17 +863,43 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd) dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; dci.queueCreateInfoCount = 1; dci.pQueueCreateInfos = &qci; - dci.pEnabledFeatures = &screen->feats; - const char *extensions[] = { + /* extensions don't have bool members in pEnabledFeatures. + * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct + */ + dci.pNext = &feats; + const char *extensions[6] = { VK_KHR_MAINTENANCE1_EXTENSION_NAME, - VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, - VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, }; + num_extensions = 1; + + if (fd >= 0 && !screen->have_KHR_external_memory_fd) { + debug_printf("ZINK: KHR_external_memory_fd required!\n"); + goto fail; + } + + if (screen->have_KHR_external_memory_fd) { + extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME; + extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME; + } + + if (screen->have_EXT_conditional_rendering) + extensions[num_extensions++] = VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME; + + if (screen->have_EXT_index_type_uint8) + extensions[num_extensions++] = VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME; + + if (screen->have_EXT_transform_feedback) + extensions[num_extensions++] = VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME; + assert(num_extensions <= ARRAY_SIZE(extensions)); + dci.ppEnabledExtensionNames = extensions; - dci.enabledExtensionCount = ARRAY_SIZE(extensions); + dci.enabledExtensionCount = num_extensions; if (vkCreateDevice(screen->pdev, &dci, NULL, &screen->dev) != VK_SUCCESS) goto fail; + if (!load_device_extensions(screen)) + goto fail; + screen->winsys = winsys; screen->base.get_name = zink_get_name;