X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fzink%2Fzink_screen.c;h=71b7345dc88d331d553743ca03e47ed5d19251b5;hb=e5e657768c3eae23e80cef8073a6f33497ba2512;hp=049362b6519ceca100ccb3b4d7481b8daee0c404;hpb=bc80900b6c8970a62e2161bee0ec3053852b1636;p=mesa.git diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 049362b6519..71b7345dc88 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: @@ -111,6 +116,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; #endif + case PIPE_CAP_TEXTURE_MULTISAMPLE: + return 1; + case PIPE_CAP_TEXTURE_SWIZZLE: return 1; @@ -122,11 +130,7 @@ 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: - return 0; /* TODO: re-enable after implementing nir_texop_txd */ - case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: case PIPE_CAP_VERTEX_SHADER_SATURATE: return 1; @@ -143,11 +147,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; @@ -159,9 +160,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 120; + return 130; #if 0 /* TODO: Enable me */ case PIPE_CAP_COMPUTE: @@ -182,6 +186,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 */ @@ -192,7 +202,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; @@ -212,6 +222,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: @@ -257,10 +270,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; @@ -294,6 +305,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 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: @@ -382,9 +396,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); @@ -405,6 +425,8 @@ zink_get_shader_param(struct pipe_screen *pscreen, case PIPE_SHADER_CAP_SUBROUTINES: case PIPE_SHADER_CAP_INT64_ATOMICS: case PIPE_SHADER_CAP_FP16: + case PIPE_SHADER_CAP_FP16_DERIVATIVES: + case PIPE_SHADER_CAP_INT16: return 0; /* not implemented */ case PIPE_SHADER_CAP_PREFERRED_IR: @@ -436,8 +458,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: @@ -454,157 +480,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, - [PIPE_FORMAT_B8G8R8X8_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_DXT1_SRGB] = VK_FORMAT_BC1_RGB_SRGB_BLOCK, - [PIPE_FORMAT_DXT1_SRGBA] = VK_FORMAT_BC1_RGBA_SRGB_BLOCK, - [PIPE_FORMAT_DXT3_SRGBA] = VK_FORMAT_BC2_SRGB_BLOCK, - [PIPE_FORMAT_DXT5_SRGBA] = VK_FORMAT_BC3_SRGB_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, -}; - -static bool -is_depth_format_supported(struct zink_screen *screen, VkFormat format) -{ - VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(screen->pdev, format, &props); - return (props.linearTilingFeatures | props.optimalTilingFeatures) & - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; -} - -VkFormat -zink_get_format(struct zink_screen *screen, enum pipe_format format) -{ - VkFormat ret = formats[format]; - - if (ret == VK_FORMAT_X8_D24_UNORM_PACK32 && - !screen->have_X8_D24_UNORM_PACK32) { - assert(is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT)); - return VK_FORMAT_D32_SFLOAT; - } - - if (ret == VK_FORMAT_D24_UNORM_S8_UINT && - !screen->have_D24_UNORM_S8_UINT) { - assert(is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT_S8_UINT)); - return VK_FORMAT_D32_SFLOAT_S8_UINT; - } - - return ret; -} - static VkSampleCountFlagBits vk_sample_count_flags(uint32_t sample_count) { @@ -637,42 +512,44 @@ zink_is_format_supported(struct pipe_screen *pscreen, VkFormat vkformat = zink_get_format(screen, format); if (vkformat == VK_FORMAT_UNDEFINED) - return FALSE; + return false; 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; } } @@ -682,34 +559,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 (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 false; } - return TRUE; + return true; } static void @@ -843,10 +720,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_cond_render_ext = false; if (!screen) return NULL; @@ -856,14 +763,12 @@ 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 = is_depth_format_supported(screen, - VK_FORMAT_X8_D24_UNORM_PACK32); - screen->have_D24_UNORM_S8_UINT = is_depth_format_supported(screen, - VK_FORMAT_D24_UNORM_S8_UINT); + 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, @@ -881,10 +786,32 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd) 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; + } FREE(extensions); } } + VkPhysicalDeviceFeatures2 feats = {}; + VkPhysicalDeviceConditionalRenderingFeaturesEXT cond_render_feats = {}; + + feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + 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; + } + vkGetPhysicalDeviceFeatures2(screen->pdev, &feats); + memcpy(&screen->feats, &feats.features, sizeof(screen->feats)); + if (have_cond_render_ext && cond_render_feats.conditionalRendering) + screen->have_EXT_conditional_rendering = true; + + VkPhysicalDeviceProperties2 props = {}; + props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + 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"); @@ -902,8 +829,11 @@ 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[3] = { + /* extensions don't have bool members in pEnabledFeatures. + * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct + */ + dci.pNext = &feats; + const char *extensions[4] = { VK_KHR_MAINTENANCE1_EXTENSION_NAME, }; num_extensions = 1; @@ -917,6 +847,10 @@ zink_internal_create_screen(struct sw_winsys *winsys, int 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; + assert(num_extensions <= ARRAY_SIZE(extensions)); dci.ppEnabledExtensionNames = extensions; @@ -924,6 +858,9 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd) 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;