mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 18:13:23 +09:00
[Feat] (GL): advertise ARB_cull_distance where the backend has cull distances
This commit is contained in:
@@ -316,6 +316,10 @@ namespace MobileGL {
|
||||
struct AdvertisedFeatureSupport {
|
||||
// ES 3.2 or GL_EXT_tessellation_shader; VkPhysicalDeviceFeatures::tessellationShader.
|
||||
Bool TessellationShader = false;
|
||||
// At least one cull distance: GL_EXT_clip_cull_distance with a non-zero
|
||||
// GL_MAX_CULL_DISTANCES; VkPhysicalDeviceFeatures::shaderCullDistance with a non-zero
|
||||
// maxCullDistances.
|
||||
Bool CullDistance = false;
|
||||
};
|
||||
|
||||
// Coarse GPU vendor identity for gating device-specific quirks. Detected from the
|
||||
|
||||
@@ -842,7 +842,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
capabilities.SupportsDrawIndirect,
|
||||
capabilities.SupportsDrawIndirect && capabilities.SupportsBaseInstance,
|
||||
capabilities.SupportsTextureView, capabilities.SupportsTextureCubeMapArray,
|
||||
AdvertisedFeatureSupport{.TessellationShader = capabilities.SupportsTessellationShader});
|
||||
AdvertisedFeatureSupport{.TessellationShader = capabilities.SupportsTessellationShader,
|
||||
.CullDistance = capabilities.MaxCullDistances > 0});
|
||||
// Exactly what InitCapabilities forwards into the dynamic parameters: the base
|
||||
// extension and _primitive when the driver has them, _attachment not yet.
|
||||
auto& extensions = MutableRendererInfo().RendererGLInfo.Extensions;
|
||||
@@ -1523,6 +1524,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (features.TessellationShader) {
|
||||
extensions.push_back(E_GL_ARB_tessellation_shader);
|
||||
}
|
||||
// gl_CullDistance goes through GL_EXT_clip_cull_distance, whose cull half the loader only
|
||||
// reports where the driver answers a non-zero GL_MAX_CULL_DISTANCES.
|
||||
if (features.CullDistance) {
|
||||
extensions.push_back(E_GL_ARB_cull_distance);
|
||||
}
|
||||
// Minecraft 26.3 checks this prerequisite before it even considers
|
||||
// GL_ARB_multi_draw_indirect. ES 3.1 supplies both single-draw entry points; the loader
|
||||
// folds the version and pointer checks into SupportsDrawIndirect.
|
||||
|
||||
@@ -925,6 +925,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
if (features.TessellationShader) {
|
||||
extensions.push_back(E_GL_ARB_tessellation_shader);
|
||||
}
|
||||
// Follows the shaderCullDistance device feature, the same gate GL_MAX_CULL_DISTANCES uses.
|
||||
if (features.CullDistance) {
|
||||
extensions.push_back(E_GL_ARB_cull_distance);
|
||||
}
|
||||
// Vulkan's drawIndirectFirstInstance feature is optional. Direct base-instance calls work
|
||||
// without it, but ARB_base_instance also promises non-zero firstInstance in GPU indirect
|
||||
// commands; the renderer supplies true only when that word is legal and gl_InstanceID can
|
||||
@@ -1106,7 +1110,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
pVulkanRenderer && pVulkanRenderer->IsSamplerAnisotropySupported(),
|
||||
pVulkanRenderer && pVulkanRenderer->IsNonZeroIndirectBaseInstanceSupported(),
|
||||
m_vulkanCaps.SupportsImageCubeArray,
|
||||
AdvertisedFeatureSupport{.TessellationShader = m_vulkanCaps.SupportsTessellationShader});
|
||||
AdvertisedFeatureSupport{.TessellationShader = m_vulkanCaps.SupportsTessellationShader,
|
||||
.CullDistance = m_vulkanCaps.SupportsShaderCullDistance &&
|
||||
m_vulkanCaps.MaxCullDistances > 0});
|
||||
// GL_EXT_fragment_shading_rate rides on VK_KHR_fragment_shading_rate's pipeline rate, and
|
||||
// its _primitive companion on the primitive rate; both only when the renderer enabled them.
|
||||
// _attachment is not advertised: no framebuffer carries a rate attachment to this backend.
|
||||
|
||||
@@ -1281,6 +1281,27 @@ TEST(CoreSurfaceAdvertisement, BatchIsUnconditionalAndTessellationFollowsTheDevi
|
||||
MobileGL::E_GL_ARB_tessellation_shader));
|
||||
}
|
||||
|
||||
// ARB_cull_distance follows the backend's cull-distance capability, never the context version.
|
||||
TEST(CoreSurfaceAdvertisement, CullDistanceFollowsTheDevice) {
|
||||
const auto contains = [](const MobileGL::Vector<MobileGL::GLExtension>& extensions,
|
||||
MobileGL::GLExtension wanted) {
|
||||
return std::find(extensions.begin(), extensions.end(), wanted) != extensions.end();
|
||||
};
|
||||
EXPECT_FALSE(contains(MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false,
|
||||
false, false),
|
||||
MobileGL::E_GL_ARB_cull_distance));
|
||||
EXPECT_FALSE(contains(MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false,
|
||||
false),
|
||||
MobileGL::E_GL_ARB_cull_distance));
|
||||
const MobileGL::MG_Backend::AdvertisedFeatureSupport cull{.CullDistance = true};
|
||||
EXPECT_TRUE(contains(MobileGL::MG_Backend::DirectGLES::BuildAdvertisedExtensions(false, false, false, false,
|
||||
false, false, cull),
|
||||
MobileGL::E_GL_ARB_cull_distance));
|
||||
EXPECT_TRUE(contains(MobileGL::MG_Backend::DirectVulkan::BuildAdvertisedExtensions(false, false, false, false,
|
||||
false, cull),
|
||||
MobileGL::E_GL_ARB_cull_distance));
|
||||
}
|
||||
|
||||
// ES 3.2 has tessellation in core; ES 3.1 only through GL_EXT_tessellation_shader. Either way the
|
||||
// patch-size entry point has to have resolved.
|
||||
TEST(TessellationCapabilities, FollowTheVersionOrTheExtension) {
|
||||
|
||||
Reference in New Issue
Block a user