diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp index 7daf5713..a1e7c356 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp @@ -753,7 +753,7 @@ namespace MobileGL::MG_Backend::DirectGLES { .TargetGLSLVersion = {4, 6, 0}, // Target Shading Language Version // Baseline advertisement (no runtime capabilities yet); reconciled once // the ES capabilities exist, see UpdateAdvertisedCapabilityExtensions. - .Extensions = BuildAdvertisedExtensions(false, false, false, false, false), + .Extensions = BuildAdvertisedExtensions(false, false, false, false, false, false), .IsCompatibilityProfile = false // Is Compatibility Profile }, .StaticBackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability @@ -778,7 +778,7 @@ namespace MobileGL::MG_Backend::DirectGLES { AreTimerQueriesSupported(), capabilities.SupportsTextureFilterAnisotropy, capabilities.SupportsDrawIndirect, capabilities.SupportsDrawIndirect && capabilities.SupportsBaseInstance, - capabilities.SupportsTextureView); + capabilities.SupportsTextureView, capabilities.SupportsTextureCubeMapArray); } } // namespace @@ -992,7 +992,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Vector BuildAdvertisedExtensions(Bool timerQueriesSupported, Bool anisotropicFilteringSupported, Bool drawIndirectSupported, Bool nonZeroIndirectBaseInstanceSupported, - Bool textureViewSupported) { + Bool textureViewSupported, Bool cubeMapArraySupported) { Vector extensions = { // The version tokens have to reach the version the backend actually claims: // TargetGLVersion is {4,3,0}, and a list that stopped at OpenGL40 told an @@ -1055,6 +1055,46 @@ namespace MobileGL::MG_Backend::DirectGLES { // object-label table are MobileGL's own state, not the host driver's - so it is as // available here as it is on DirectVulkan, which has advertised it all along. E_GL_KHR_debug, + // Core GL 3.0-4.3 plumbing that has been real here for as long as the backend has + // existed, and that was simply never named. None of these unlocks a single CTS case - + // the conformance suite reaches all of them through the version - so they are + // advertised for the OTHER consumer of this list: LWJGL builds GLCapabilities from the + // string set, and an application that gates its ENTRY POINTS on the string rather than + // on the version never resolves them and then calls through null. Each is backed by + // the entry points named beside it. + // + // glBindVertexArray / glGenVertexArrays / glDeleteVertexArrays / glIsVertexArray. + E_GL_ARB_vertex_array_object, + // The 14 glSamplerParameter* / glGetSamplerParameter* entry points, including the + // integer-valued Iiv/Iuiv forms. + E_GL_ARB_sampler_objects, + // glMapBufferRange + glFlushMappedBufferRange, which ARB_buffer_storage's persistent + // maps are already built on top of. + E_GL_ARB_map_buffer_range, + // glCopyBufferSubData plus the GL_COPY_READ_BUFFER / GL_COPY_WRITE_BUFFER targets. + E_GL_ARB_copy_buffer, + // glCopyImageSubData, wired to a real backend hook on both backends. + E_GL_ARB_copy_image, + // GL_TEXTURE_SWIZZLE_{R,G,B,A,RGBA}, which this backend syncs through to the ES + // driver's identical parameters. + E_GL_ARB_texture_swizzle, + // GL_INT_2_10_10_10_REV / GL_UNSIGNED_INT_2_10_10_10_REV on glVertexAttribPointer plus + // the eight glVertexAttribP* entry points. + E_GL_ARB_vertex_type_2_10_10_10_rev, + // The R/RG internal formats. Named separately from the float ones because an + // application may check either. + E_GL_ARB_texture_rg, + // GL_DEPTH_COMPONENT32F and GL_DEPTH32F_STENCIL8. + E_GL_ARB_depth_buffer_float, + // The floating-point colour formats. Unlike the rest of this block this string DOES + // gate CTS cases - KHR-GL4*.internalformat.texture2d.*{16f,32f} is keyed on it with no + // core-version fallback, so eight cases per version list were NotSupported on formats + // the backend has always had. + E_GL_ARB_texture_float, + // glViewportArrayv / glViewportIndexedf{,v} / glScissorArrayv / glScissorIndexed{,v} / + // glDepthRangeArrayv / glDepthRangeIndexed / glGetFloati_v / glGetDoublei_v, over the + // 16 viewports GL_MAX_VIEWPORTS reports and the per-viewport routing emulation. + E_GL_ARB_viewport_array, // Advertised with GL_NUM_PROGRAM_BINARY_FORMATS = 0, which the // extension explicitly permits. It is also the only thing that // exposes glProgramParameteri before GL 4.1. @@ -1103,6 +1143,18 @@ namespace MobileGL::MG_Backend::DirectGLES { if (timerQueriesSupported && !MG_Config::Features.DisableTimerQuery) { extensions.push_back(E_GL_ARB_timer_query); } + // Cube map arrays are core from GL 4.0 and from ES 3.2, but on a pre-ES-3.2 driver without + // EXT/OES_texture_cube_map_array there is nothing underneath: the texture gets no storage + // and a samplerCubeArray shader does not even compile, which is exactly what the POST + // reports. So the string follows the host capability rather than the version. + // + // It is worth naming even though cube map arrays are core at the version claimed, because + // KHR-GL4*.texture_gather.plain-gather-*-cube-array checks the STRING and has no + // core-version fallback - five cases per version list sat NotSupported on a device that + // supports the feature. + if (cubeMapArraySupported) { + extensions.push_back(E_GL_ARB_texture_cube_map_array); + } // Only advertised when the host ES driver has EXT/OES_texture_view. ES has no core // texture views at any version and no honest emulation exists: a view is a SECOND NAME // over the SAME storage, so that writes through either are visible through the other and diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h index 07463120..8f3fd0c6 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h @@ -83,7 +83,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Vector BuildAdvertisedExtensions(Bool timerQueriesSupported, Bool anisotropicFilteringSupported, Bool drawIndirectSupported, Bool nonZeroIndirectBaseInstanceSupported, - Bool textureViewSupported); + Bool textureViewSupported, Bool cubeMapArraySupported); // Format: , OpenGL ES . — the exact string an // initialized backend returns from GetBackendAPIVersionString (and that ends up diff --git a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp index 0e632946..3019ba6f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp @@ -504,7 +504,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { .TargetGLSLVersion = {4, 6, 0}, // Baseline advertisement (no runtime-gated capabilities); a live // backend reconciles its copy in UpdateAdvertisedExtensions. - .Extensions = BuildAdvertisedExtensions(false, false, false, false), + .Extensions = BuildAdvertisedExtensions(false, false, false, false, false), .IsCompatibilityProfile = false}, .StaticBackendCapability = {.AllowVSOnlyPrograms = false}}; return rendererInfo; @@ -512,7 +512,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { Vector BuildAdvertisedExtensions(Bool shaderSubgroupSupported, Bool timerQueriesSupported, Bool anisotropicFilteringSupported, - Bool nonZeroIndirectBaseInstanceSupported) { + Bool nonZeroIndirectBaseInstanceSupported, + Bool cubeMapArraySupported) { Vector extensions = { // The version tokens have to reach the version the backend actually claims: // TargetGLVersion is {4,3,0}, and a list that stopped at OpenGL40 told an @@ -571,6 +572,46 @@ namespace MobileGL::MG_Backend::DirectVulkan { // ALTERNATIVE to a 3.3 context when deciding whether instanced rendering is // available, so withholding it makes MobileGL look less capable than it is. E_GL_ARB_instanced_arrays, + // Core GL 3.0-4.3 plumbing that has been real here for as long as the backend has + // existed, and that was simply never named. None of these unlocks a single CTS case - + // the conformance suite reaches all of them through the version - so they are + // advertised for the OTHER consumer of this list: LWJGL builds GLCapabilities from the + // string set, and an application that gates its ENTRY POINTS on the string rather than + // on the version never resolves them and then calls through null. Each is backed by + // the entry points named beside it. Kept identical to the DirectGLES block so the two + // backends do not disagree about what MobileGL is. + // + // glBindVertexArray / glGenVertexArrays / glDeleteVertexArrays / glIsVertexArray. + E_GL_ARB_vertex_array_object, + // The 14 glSamplerParameter* / glGetSamplerParameter* entry points, including the + // integer-valued Iiv/Iuiv forms. + E_GL_ARB_sampler_objects, + // glMapBufferRange + glFlushMappedBufferRange, which ARB_buffer_storage's persistent + // maps are already built on top of. + E_GL_ARB_map_buffer_range, + // glCopyBufferSubData plus the GL_COPY_READ_BUFFER / GL_COPY_WRITE_BUFFER targets. + E_GL_ARB_copy_buffer, + // glCopyImageSubData, wired to a real backend hook on both backends. + E_GL_ARB_copy_image, + // GL_TEXTURE_SWIZZLE_{R,G,B,A,RGBA}, which map onto a VkImageView's component swizzle. + E_GL_ARB_texture_swizzle, + // GL_INT_2_10_10_10_REV / GL_UNSIGNED_INT_2_10_10_10_REV on glVertexAttribPointer plus + // the eight glVertexAttribP* entry points. + E_GL_ARB_vertex_type_2_10_10_10_rev, + // The R/RG internal formats. Named separately from the float ones because an + // application may check either. + E_GL_ARB_texture_rg, + // GL_DEPTH_COMPONENT32F and GL_DEPTH32F_STENCIL8. + E_GL_ARB_depth_buffer_float, + // The floating-point colour formats. Unlike the rest of this block this string DOES + // gate CTS cases - KHR-GL4*.internalformat.texture2d.*{16f,32f} is keyed on it with no + // core-version fallback, so eight cases per version list were NotSupported on formats + // the backend has always had. + E_GL_ARB_texture_float, + // glViewportArrayv / glViewportIndexedf{,v} / glScissorArrayv / glScissorIndexed{,v} / + // glDepthRangeArrayv / glDepthRangeIndexed / glGetFloati_v / glGetDoublei_v, over the + // 16 viewports GL_MAX_VIEWPORTS reports. + E_GL_ARB_viewport_array, // Advertised with GL_NUM_PROGRAM_BINARY_FORMATS = 0, which the // extension explicitly permits. It is also the only thing that // exposes glProgramParameteri before GL 4.1. @@ -623,6 +664,17 @@ namespace MobileGL::MG_Backend::DirectVulkan { extensions.push_back(E_GL_EXT_texture_filter_anisotropic); extensions.push_back(E_GL_ARB_texture_filter_anisotropic); } + // A cube map array is a 6n-layer VkImage viewed as VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, and that + // view type cannot be created without the imageCubeArray device feature - so the string + // follows the feature, not the version, exactly as the per-layer attachment bit does. + // + // Worth naming even though cube map arrays are core at the version claimed, because + // KHR-GL4*.texture_gather.plain-gather-*-cube-array checks the STRING and has no + // core-version fallback - five cases per version list sat NotSupported on a device that + // supports the feature. + if (cubeMapArraySupported) { + extensions.push_back(E_GL_ARB_texture_cube_map_array); + } return extensions; } @@ -753,7 +805,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { m_rendererInfo.RendererGLInfo.Extensions = BuildAdvertisedExtensions( subgroupSupportAdvertised, pVulkanRenderer && pVulkanRenderer->IsTimerQuerySupported(), pVulkanRenderer && pVulkanRenderer->IsSamplerAnisotropySupported(), - pVulkanRenderer && pVulkanRenderer->IsNonZeroIndirectBaseInstanceSupported()); + pVulkanRenderer && pVulkanRenderer->IsNonZeroIndirectBaseInstanceSupported(), + m_vulkanCaps.SupportsImageCubeArray); } void BackendObject_DirectVulkan::UpdateDynamicBackendParameters() { diff --git a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.h b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.h index c64d57cb..91c6e54c 100644 --- a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.h +++ b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.h @@ -75,7 +75,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { // the detected device support (passing an already-gated value is harmless). Vector BuildAdvertisedExtensions(Bool shaderSubgroupSupported, Bool timerQueriesSupported, Bool anisotropicFilteringSupported, - Bool nonZeroIndirectBaseInstanceSupported); + Bool nonZeroIndirectBaseInstanceSupported, + Bool cubeMapArraySupported); // Format: , Vulkan , Driver — the exact // string an initialized backend returns from GetBackendAPIVersionString (and that diff --git a/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp b/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp index 7b5706a9..80046586 100644 --- a/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp +++ b/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp @@ -1087,22 +1087,76 @@ TEST(TextureAnisotropyCapabilities, ExtensionIsAdvertisedOnlyWhenTheHostDriverSu return std::find(extensions.begin(), extensions.end(), wanted) != extensions.end(); }; - const auto without = MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false); + const auto without = MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false, false); EXPECT_FALSE(contains(without, MobileGL::E_GL_EXT_texture_filter_anisotropic)); EXPECT_FALSE(contains(without, MobileGL::E_GL_ARB_texture_filter_anisotropic)); - const auto with = MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, true, false, false, false); + const auto with = MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, true, false, false, false, false); EXPECT_TRUE(contains(with, MobileGL::E_GL_EXT_texture_filter_anisotropic)); EXPECT_TRUE(contains(with, MobileGL::E_GL_ARB_texture_filter_anisotropic)); // Same rule on the Vulkan backend, where the gate is the samplerAnisotropy device feature. - const auto vkWithout = MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false); + const auto vkWithout = MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false, false); EXPECT_FALSE(contains(vkWithout, MobileGL::E_GL_EXT_texture_filter_anisotropic)); - const auto vkWith = MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, true, false); + const auto vkWith = MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, true, false, false); EXPECT_TRUE(contains(vkWith, MobileGL::E_GL_EXT_texture_filter_anisotropic)); EXPECT_TRUE(contains(vkWith, MobileGL::E_GL_ARB_texture_filter_anisotropic)); } +// Cube map arrays are core at the version MobileGL claims, but there is nothing underneath on a +// pre-ES-3.2 driver without EXT/OES_texture_cube_map_array, and no VK_IMAGE_VIEW_TYPE_CUBE_ARRAY +// without the imageCubeArray feature. The string has to follow the capability on both backends - +// and it has to BE there when the capability is, because KHR-GL4*.texture_gather.*-cube-array +// gates on the string with no core-version fallback. +TEST(CubeMapArrayAdvertisement, FollowsTheHostCapabilityOnBothBackends) { + const auto contains = [](const MobileGL::Vector& extensions, + MobileGL::GLExtension wanted) { + return std::find(extensions.begin(), extensions.end(), wanted) != extensions.end(); + }; + + const auto esWithout = + MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false, false); + EXPECT_FALSE(contains(esWithout, MobileGL::E_GL_ARB_texture_cube_map_array)); + const auto esWith = + MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false, true); + EXPECT_TRUE(contains(esWith, MobileGL::E_GL_ARB_texture_cube_map_array)); + + const auto vkWithout = MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false, + false); + EXPECT_FALSE(contains(vkWithout, MobileGL::E_GL_ARB_texture_cube_map_array)); + const auto vkWith = MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false, true); + EXPECT_TRUE(contains(vkWith, MobileGL::E_GL_ARB_texture_cube_map_array)); +} + +// The core-plumbing strings carry no capability gate: they name entry points that have been real +// on both backends for as long as the backends have existed, and an application that gates its +// entry-point resolution on the string (LWJGL does) would otherwise call through null. Pinned +// together so a future edit cannot quietly drop one, and pinned on BOTH backends so the two +// cannot disagree about what MobileGL is. +TEST(CorePlumbingAdvertisement, IsUnconditionalAndIdenticalOnBothBackends) { + const auto contains = [](const MobileGL::Vector& extensions, + MobileGL::GLExtension wanted) { + return std::find(extensions.begin(), extensions.end(), wanted) != extensions.end(); + }; + const MobileGL::GLExtension expected[] = { + MobileGL::E_GL_ARB_sync, MobileGL::E_GL_ARB_shader_atomic_counters, + MobileGL::E_GL_ARB_vertex_array_object, MobileGL::E_GL_ARB_sampler_objects, + MobileGL::E_GL_ARB_map_buffer_range, MobileGL::E_GL_ARB_copy_buffer, + MobileGL::E_GL_ARB_copy_image, MobileGL::E_GL_ARB_texture_swizzle, + MobileGL::E_GL_ARB_vertex_type_2_10_10_10_rev, MobileGL::E_GL_ARB_texture_rg, + MobileGL::E_GL_ARB_depth_buffer_float, MobileGL::E_GL_ARB_texture_float, + MobileGL::E_GL_ARB_viewport_array}; + + // Every gate off: none of these may depend on one. + const auto es = MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false, + false); + const auto vk = MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false, false); + for (const auto extension : expected) { + EXPECT_TRUE(contains(es, extension)) << "DirectGLES stopped advertising extension " << extension; + EXPECT_TRUE(contains(vk, extension)) << "DirectVulkan stopped advertising extension " << extension; + } +} + // Minecraft 26.3 checks ARB_draw_indirect before it considers the already-advertised // ARB_multi_draw_indirect, then separately requires ARB_base_instance before enabling its terrain // indirect path. Pin both strings and, just as importantly, the non-zero firstInstance gate. @@ -1113,27 +1167,27 @@ TEST(IndirectDrawAdvertisement, MatchesEachBackendsUsableCommandSemantics) { }; const auto esWithoutIndirect = - MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false); + MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false, false); EXPECT_FALSE(contains(esWithoutIndirect, MobileGL::E_GL_ARB_draw_indirect)); EXPECT_FALSE(contains(esWithoutIndirect, MobileGL::E_GL_ARB_base_instance)); const auto esWithoutBaseInstance = - MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, true, false, false); + MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, true, false, false, false); EXPECT_TRUE(contains(esWithoutBaseInstance, MobileGL::E_GL_ARB_draw_indirect)); EXPECT_FALSE(contains(esWithoutBaseInstance, MobileGL::E_GL_ARB_base_instance)); const auto esWithBoth = - MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, true, true, false); + MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, true, true, false, false); EXPECT_TRUE(contains(esWithBoth, MobileGL::E_GL_ARB_draw_indirect)); EXPECT_TRUE(contains(esWithBoth, MobileGL::E_GL_ARB_base_instance)); const auto vkWithoutBaseInstance = - MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false); + MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false, false); EXPECT_TRUE(contains(vkWithoutBaseInstance, MobileGL::E_GL_ARB_draw_indirect)); EXPECT_FALSE(contains(vkWithoutBaseInstance, MobileGL::E_GL_ARB_base_instance)); const auto vkWithBoth = - MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, true); + MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, true, false); EXPECT_TRUE(contains(vkWithBoth, MobileGL::E_GL_ARB_draw_indirect)); EXPECT_TRUE(contains(vkWithBoth, MobileGL::E_GL_ARB_base_instance)); } diff --git a/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp b/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp index 098d9ed4..44b73cc9 100644 --- a/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp +++ b/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp @@ -516,17 +516,17 @@ TEST_F(ParallelShaderCompileTest, MaxShaderCompilerThreadsIgnoresTheCurrentBudge TEST_F(ParallelShaderCompileTest, BothBackendsAdvertiseTheExtensionIffAsyncIsEnabled) { { const AsyncModeScope async(true); - EXPECT_TRUE(Advertises(MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false), + EXPECT_TRUE(Advertises(MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false, false), E_GL_KHR_parallel_shader_compile)); - EXPECT_TRUE(Advertises(MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false), + EXPECT_TRUE(Advertises(MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false, false), E_GL_KHR_parallel_shader_compile)); } { const AsyncModeScope async(false); - EXPECT_FALSE(Advertises(MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false), + EXPECT_FALSE(Advertises(MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false, false, false), E_GL_KHR_parallel_shader_compile)) << "MOBILEGL_ASYNC_SHADER_COMPILE=0 must withdraw the extension, not only the threading"; - EXPECT_FALSE(Advertises(MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false), + EXPECT_FALSE(Advertises(MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false, false), E_GL_KHR_parallel_shader_compile)) << "MOBILEGL_ASYNC_SHADER_COMPILE=0 must withdraw the extension, not only the threading"; } diff --git a/MobileGL/MG_Util/SelfTest/DriverPost.cpp b/MobileGL/MG_Util/SelfTest/DriverPost.cpp index 7e8ef6c9..fdca43d4 100644 --- a/MobileGL/MG_Util/SelfTest/DriverPost.cpp +++ b/MobileGL/MG_Util/SelfTest/DriverPost.cpp @@ -1269,7 +1269,7 @@ namespace MobileGL::MG_Util::SelfTest { summary.caps.SupportsDisjointTimerQuery, summary.caps.SupportsTextureFilterAnisotropy, summary.caps.SupportsDrawIndirect, summary.caps.SupportsDrawIndirect && summary.caps.SupportsBaseInstance, - summary.caps.SupportsTextureView)); + summary.caps.SupportsTextureView, summary.caps.SupportsTextureCubeMapArray)); } AppendMobileGLReportedRows(builder, MG_Backend::DirectGLES::GetRendererIdentity(), backendApiVersionString, advertisedExtensions); @@ -2009,6 +2009,7 @@ namespace MobileGL::MG_Util::SelfTest { Bool samplerAnisotropySupported = false; Bool drawIndirectFirstInstanceSupported = false; Bool shaderDrawParametersSupported = false; + Bool imageCubeArraySupported = false; }; } // namespace @@ -2300,6 +2301,7 @@ namespace MobileGL::MG_Util::SelfTest { VkPhysicalDeviceFeatures features{}; vkGetPhysicalDeviceFeaturesFn(physicalDevice, &features); summary.samplerAnisotropySupported = features.samplerAnisotropy == VK_TRUE; + summary.imageCubeArraySupported = features.imageCubeArray == VK_TRUE; summary.drawIndirectFirstInstanceSupported = features.drawIndirectFirstInstance == VK_TRUE; if (features.multiDrawIndirect == VK_TRUE) { builder.Pass("multiDrawIndirect", "indirect multi-draw batches run as single native commands"); @@ -2721,7 +2723,8 @@ namespace MobileGL::MG_Util::SelfTest { summary.deviceName, summary.apiVersionString, summary.driverVersionString); advertisedExtensions = JoinAdvertisedExtensions(MG_Backend::DirectVulkan::BuildAdvertisedExtensions( summary.shaderSubgroupUsable, summary.timerQueriesSupported, summary.samplerAnisotropySupported, - summary.drawIndirectFirstInstanceSupported && summary.shaderDrawParametersSupported)); + summary.drawIndirectFirstInstanceSupported && summary.shaderDrawParametersSupported, + summary.imageCubeArraySupported)); } AppendMobileGLReportedRows(builder, MG_Backend::DirectVulkan::GetRendererIdentity(), backendApiVersionString, advertisedExtensions);