mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix, Test] (BackendLoader, DirectGLES, DirectVulkan, GLImpl): answer the layer and viewport-index provoking-vertex conventions from the backend
This commit is contained in:
@@ -384,6 +384,20 @@ namespace MobileGL {
|
||||
// hand glslang a workable gl_MaxClipDistances.
|
||||
Int MaxClipDistances = 8;
|
||||
Int MaxViewports = 16;
|
||||
// GL_LAYER_PROVOKING_VERTEX / GL_VIEWPORT_INDEX_PROVOKING_VERTEX: which vertex of a
|
||||
// primitive supplies gl_Layer and gl_ViewportIndex. GL 4.6 table 23.65 makes
|
||||
// GL_UNDEFINED_VERTEX a legal answer for both, and it is the honest default - naming
|
||||
// a convention is a statement about behaviour, so a backend that does not pin one
|
||||
// must not claim it does. DirectGLES fills the layer one from the ES 3.2 query and
|
||||
// the viewport one from GL_OES_viewport_array, and leaves UNDEFINED where the
|
||||
// capability is absent: without the viewport array extension only viewport 0 is ever
|
||||
// rasterized, so no convention selects anything. DirectVulkan keeps UNDEFINED for
|
||||
// both - which vertex provokes is decided per pipeline by
|
||||
// VulkanRenderer::SelectProvokingVertexMode out of VK_EXT_provoking_vertex,
|
||||
// provokingVertexModePerPipeline and the topology, so no single convention is true
|
||||
// of the backend.
|
||||
GLenum LayerProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
GLenum ViewportIndexProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
Int MaxViewportWidth = 16384;
|
||||
Int MaxViewportHeight = 16384;
|
||||
Float ViewportBoundsRangeMin = 0.0f;
|
||||
|
||||
@@ -1336,6 +1336,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
m_dynamicParameters.MaxColorAttachments = m_GLESCapabilities.MaxColorAttachments;
|
||||
m_dynamicParameters.MaxClipDistances = m_GLESCapabilities.MaxClipDistances;
|
||||
m_dynamicParameters.MaxViewports = m_GLESCapabilities.MaxViewports;
|
||||
// Whatever the driver said about which vertex supplies gl_Layer, and GL_UNDEFINED_VERTEX
|
||||
// for gl_ViewportIndex on every driver without GL_OES_viewport_array - which is both test
|
||||
// devices. That is not a shortfall being hidden: without the extension only viewport 0 is
|
||||
// ever rasterized, so no vertex "selects" a viewport index and naming a convention would
|
||||
// describe behaviour this backend does not implement.
|
||||
m_dynamicParameters.LayerProvokingVertex = m_GLESCapabilities.LayerProvokingVertex;
|
||||
m_dynamicParameters.ViewportIndexProvokingVertex = m_GLESCapabilities.ViewportIndexProvokingVertex;
|
||||
m_dynamicParameters.MaxViewportWidth = m_GLESCapabilities.MaxViewportWidth;
|
||||
m_dynamicParameters.MaxViewportHeight = m_GLESCapabilities.MaxViewportHeight;
|
||||
m_dynamicParameters.ViewportBoundsRangeMin = m_GLESCapabilities.ViewportBoundsRangeMin;
|
||||
|
||||
@@ -912,6 +912,15 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
m_dynamicParameters.MaxClipDistances =
|
||||
m_vulkanCaps.SupportsShaderClipDistance ? std::max(m_vulkanCaps.MaxClipDistances, 0) : 0;
|
||||
m_dynamicParameters.MaxViewports = m_vulkanCaps.MaxViewports;
|
||||
// Assigned explicitly rather than left to the struct's defaults, like every other
|
||||
// parameter here, so a second fill cannot inherit a stale value. GL_UNDEFINED_VERTEX is
|
||||
// the truthful answer for DirectVulkan and a legal one (GL 4.6 table 23.65): which vertex
|
||||
// provokes is chosen per pipeline by VulkanRenderer::SelectProvokingVertexMode out of
|
||||
// VK_EXT_provoking_vertex, provokingVertexModePerPipeline and the topology, so there is no
|
||||
// one convention to name. Vulkan's own default is FIRST, which is the opposite of the
|
||||
// GL_LAST_VERTEX_CONVENTION this used to claim unconditionally.
|
||||
m_dynamicParameters.LayerProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
m_dynamicParameters.ViewportIndexProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
m_dynamicParameters.MaxViewportWidth = m_vulkanCaps.MaxViewportWidth;
|
||||
m_dynamicParameters.MaxViewportHeight = m_vulkanCaps.MaxViewportHeight;
|
||||
m_dynamicParameters.ViewportBoundsRangeMin = m_vulkanCaps.ViewportBoundsRangeMin;
|
||||
|
||||
@@ -1572,9 +1572,6 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_LINE_WIDTH:
|
||||
*params = static_cast<GLint>(MG_State::pGLContext->GetLineWidth());
|
||||
return;
|
||||
case GL_LAYER_PROVOKING_VERTEX:
|
||||
*params = GL_LAST_VERTEX_CONVENTION;
|
||||
return;
|
||||
case GL_LOGIC_OP_MODE:
|
||||
*params = static_cast<GLint>(MG_Util::ConvertLogicOperationToGLEnum(MG_State::pGLContext->GetLogicOp()));
|
||||
return;
|
||||
@@ -2117,9 +2114,6 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
params[3] = vp.w();
|
||||
return;
|
||||
}
|
||||
case GL_VIEWPORT_INDEX_PROVOKING_VERTEX:
|
||||
*params = GL_LAST_VERTEX_CONVENTION;
|
||||
return;
|
||||
case GL_MAX_ELEMENT_INDEX:
|
||||
*params = 1024 * 1024; // TODO
|
||||
return;
|
||||
@@ -2207,6 +2201,20 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_MAX_CLIP_DISTANCES:
|
||||
*params = dynamicParameters.MaxClipDistances;
|
||||
break;
|
||||
// Both were a hard-coded GL_LAST_VERTEX_CONVENTION, derived from nothing. GL 4.6 table
|
||||
// 23.65 permits GL_UNDEFINED_VERTEX for either, and that is what the backends report
|
||||
// wherever they do not actually pin a convention - claiming one is a statement about
|
||||
// which vertex of a primitive supplies gl_Layer / gl_ViewportIndex, and DirectGLES
|
||||
// rasterizes only viewport 0 on a driver without GL_OES_viewport_array while
|
||||
// DirectVulkan picks its provoking mode per pipeline. KHR-GLxx.viewport_array.query
|
||||
// accepts all four values, and .provoking_vertex - which failed on both devices, in
|
||||
// OPPOSITE directions - stops verifying as soon as either answer is undefined.
|
||||
case GL_LAYER_PROVOKING_VERTEX:
|
||||
*params = static_cast<GLint>(dynamicParameters.LayerProvokingVertex);
|
||||
break;
|
||||
case GL_VIEWPORT_INDEX_PROVOKING_VERTEX:
|
||||
*params = static_cast<GLint>(dynamicParameters.ViewportIndexProvokingVertex);
|
||||
break;
|
||||
case GL_MAX_COLOR_TEXTURE_SAMPLES:
|
||||
*params = std::max(dynamicParameters.MaxColorTextureSamples, GetAdvertisedMaxSamples());
|
||||
break;
|
||||
|
||||
@@ -57,6 +57,12 @@ namespace {
|
||||
GLint maxViewports = 32;
|
||||
GLint viewportSubpixelBits = 8;
|
||||
bool viewportArrayLimitsQueried = false;
|
||||
// GL_LAYER_PROVOKING_VERTEX is ES 3.2 core; GL_VIEWPORT_INDEX_PROVOKING_VERTEX comes with
|
||||
// GL_OES_viewport_array. Both must go unasked where they do not exist, and a driver answer
|
||||
// outside the four legal conventions must not be forwarded as one.
|
||||
GLint layerProvokingVertex = GL_FIRST_VERTEX_CONVENTION;
|
||||
GLint viewportIndexProvokingVertex = GL_LAST_VERTEX_CONVENTION;
|
||||
bool layerProvokingVertexQueried = false;
|
||||
// A driver rejecting one of the UNCONDITIONAL probes. GL_SMOOTH_LINE_WIDTH_RANGE is the
|
||||
// realistic one - it is desktop-only state that every GLES driver refuses - and it stands
|
||||
// in for the whole run: whatever it leaves behind must not reach the application.
|
||||
@@ -195,6 +201,14 @@ namespace {
|
||||
g_fake.viewportArrayLimitsQueried = true;
|
||||
*data = g_fake.viewportSubpixelBits;
|
||||
break;
|
||||
case GL_VIEWPORT_INDEX_PROVOKING_VERTEX:
|
||||
g_fake.viewportArrayLimitsQueried = true;
|
||||
*data = g_fake.viewportIndexProvokingVertex;
|
||||
break;
|
||||
case GL_LAYER_PROVOKING_VERTEX:
|
||||
g_fake.layerProvokingVertexQueried = true;
|
||||
*data = g_fake.layerProvokingVertex;
|
||||
break;
|
||||
case GL_MAX_COLOR_TEXTURE_SAMPLES:
|
||||
case GL_MAX_DEPTH_TEXTURE_SAMPLES:
|
||||
case GL_MAX_FRAMEBUFFER_SAMPLES:
|
||||
@@ -782,6 +796,62 @@ TEST(ViewportArrayCapabilities, TheLimitsAreOnlyAskedForWhenTheExtensionIsPresen
|
||||
EXPECT_EQ(withCaps.ViewportSubpixelBits, g_fake.viewportSubpixelBits);
|
||||
}
|
||||
|
||||
// GL_LAYER_PROVOKING_VERTEX and GL_VIEWPORT_INDEX_PROVOKING_VERTEX name which vertex of a
|
||||
// primitive supplies gl_Layer and gl_ViewportIndex. MobileGL used to answer a hard-coded
|
||||
// GL_LAST_VERTEX_CONVENTION for both, derived from nothing, and got it wrong on both test devices
|
||||
// in OPPOSITE directions. GL_UNDEFINED_VERTEX is a legal answer (GL 4.6 table 23.65) and it is
|
||||
// the honest one wherever the capability that would give the convention meaning is absent.
|
||||
TEST(ProvokingVertexConventions, AreTakenFromTheDriverOnlyWhereThePnameExists) {
|
||||
const auto funcs = MakeFakeGLESFunctions();
|
||||
|
||||
// ES 3.1, no viewport array: neither pname exists, so neither is asked for.
|
||||
ResetFakeDriver();
|
||||
g_fake.maxVertexSsboBlocks = 0;
|
||||
MobileGL::MG_External::GLESCapabilities es31Caps;
|
||||
ASSERT_TRUE(MobileGL::MG_Util::BackendLoader::FillInGLESCapabilities(es31Caps, funcs));
|
||||
EXPECT_FALSE(g_fake.layerProvokingVertexQueried);
|
||||
EXPECT_EQ(es31Caps.LayerProvokingVertex, static_cast<GLenum>(GL_UNDEFINED_VERTEX));
|
||||
EXPECT_EQ(es31Caps.ViewportIndexProvokingVertex, static_cast<GLenum>(GL_UNDEFINED_VERTEX));
|
||||
|
||||
// ES 3.2 with the viewport array: both exist and both driver answers come through verbatim.
|
||||
ResetFakeDriver();
|
||||
g_fake.maxVertexSsboBlocks = 0;
|
||||
g_fake.glesMinorVersion = 2;
|
||||
g_fake.extensions.emplace_back("GL_OES_viewport_array");
|
||||
MobileGL::MG_External::GLESCapabilities es32Caps;
|
||||
ASSERT_TRUE(MobileGL::MG_Util::BackendLoader::FillInGLESCapabilities(es32Caps, funcs));
|
||||
EXPECT_TRUE(g_fake.layerProvokingVertexQueried);
|
||||
EXPECT_EQ(es32Caps.LayerProvokingVertex, static_cast<GLenum>(GL_FIRST_VERTEX_CONVENTION));
|
||||
EXPECT_EQ(es32Caps.ViewportIndexProvokingVertex, static_cast<GLenum>(GL_LAST_VERTEX_CONVENTION));
|
||||
|
||||
// ES 3.2 WITHOUT the viewport array - the shape of both test devices. The layer convention is
|
||||
// real and comes from the driver; the viewport-index one describes a selection that never
|
||||
// happens, because only viewport 0 is ever rasterized, and stays undefined.
|
||||
ResetFakeDriver();
|
||||
g_fake.maxVertexSsboBlocks = 0;
|
||||
g_fake.glesMinorVersion = 2;
|
||||
MobileGL::MG_External::GLESCapabilities deviceLikeCaps;
|
||||
ASSERT_TRUE(MobileGL::MG_Util::BackendLoader::FillInGLESCapabilities(deviceLikeCaps, funcs));
|
||||
EXPECT_EQ(deviceLikeCaps.LayerProvokingVertex, static_cast<GLenum>(GL_FIRST_VERTEX_CONVENTION));
|
||||
EXPECT_EQ(deviceLikeCaps.ViewportIndexProvokingVertex, static_cast<GLenum>(GL_UNDEFINED_VERTEX));
|
||||
}
|
||||
|
||||
// A driver answering something that is not one of the four legal conventions must not have it
|
||||
// forwarded as one: GL_UNDEFINED_VERTEX describes "MobileGL cannot tell you" exactly.
|
||||
TEST(ProvokingVertexConventions, AnIllegalDriverAnswerBecomesUndefined) {
|
||||
ResetFakeDriver();
|
||||
g_fake.maxVertexSsboBlocks = 0;
|
||||
g_fake.glesMinorVersion = 2;
|
||||
g_fake.layerProvokingVertex = 0x1234;
|
||||
const auto funcs = MakeFakeGLESFunctions();
|
||||
|
||||
MobileGL::MG_External::GLESCapabilities caps;
|
||||
ASSERT_TRUE(MobileGL::MG_Util::BackendLoader::FillInGLESCapabilities(caps, funcs));
|
||||
|
||||
EXPECT_TRUE(g_fake.layerProvokingVertexQueried);
|
||||
EXPECT_EQ(caps.LayerProvokingVertex, static_cast<GLenum>(GL_UNDEFINED_VERTEX));
|
||||
}
|
||||
|
||||
// The multisample ceilings are ES 3.1 state; a driver that answers zero - or an older context
|
||||
// that answers nothing - must not have that reach GL_Getter, which would then reject the sample
|
||||
// count it just advertised.
|
||||
|
||||
@@ -665,6 +665,33 @@ TEST(DirectVulkanSanity, GatesClipDistancesOnTheShaderClipDistanceFeature) {
|
||||
EXPECT_EQ(backend.GetDynamicParameters().MaxClipDistances, 8);
|
||||
}
|
||||
|
||||
// GL_LAYER_PROVOKING_VERTEX / GL_VIEWPORT_INDEX_PROVOKING_VERTEX were a hard-coded
|
||||
// GL_LAST_VERTEX_CONVENTION for both backends, derived from nothing, and wrong on both test
|
||||
// devices in opposite directions. DirectGLES now forwards what its loader resolved; DirectVulkan
|
||||
// reports GL_UNDEFINED_VERTEX, which GL 4.6 table 23.65 permits and which is what the backend
|
||||
// honestly implements - the provoking mode is chosen per pipeline out of VK_EXT_provoking_vertex,
|
||||
// provokingVertexModePerPipeline and the topology.
|
||||
TEST(ProvokingVertexConventions, EachBackendReportsWhatItActuallyPins) {
|
||||
using namespace MobileGL;
|
||||
|
||||
MG_Backend::DirectGLES::BackendObject_DirectGLES glesBackend;
|
||||
MG_External::GLESCapabilities glesCaps;
|
||||
glesCaps.LayerProvokingVertex = GL_FIRST_VERTEX_CONVENTION;
|
||||
glesCaps.ViewportIndexProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
glesBackend.ApplyGLESCapabilitiesForTesting(glesCaps);
|
||||
EXPECT_EQ(glesBackend.GetDynamicParameters().LayerProvokingVertex,
|
||||
static_cast<GLenum>(GL_FIRST_VERTEX_CONVENTION));
|
||||
EXPECT_EQ(glesBackend.GetDynamicParameters().ViewportIndexProvokingVertex,
|
||||
static_cast<GLenum>(GL_UNDEFINED_VERTEX));
|
||||
|
||||
MG_Backend::DirectVulkan::BackendObject_DirectVulkan vkBackend;
|
||||
MG_External::VulkanCapabilities vkCaps;
|
||||
vkBackend.ApplyVulkanCapabilitiesForTesting(vkCaps);
|
||||
EXPECT_EQ(vkBackend.GetDynamicParameters().LayerProvokingVertex, static_cast<GLenum>(GL_UNDEFINED_VERTEX));
|
||||
EXPECT_EQ(vkBackend.GetDynamicParameters().ViewportIndexProvokingVertex,
|
||||
static_cast<GLenum>(GL_UNDEFINED_VERTEX));
|
||||
}
|
||||
|
||||
TEST(FragmentInterpolationCapabilities, PlumbsGLESAndBothVulkanPropertyPaths) {
|
||||
using namespace MobileGL;
|
||||
|
||||
|
||||
@@ -831,6 +831,35 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
return includesBase;
|
||||
}
|
||||
|
||||
// GL 4.6 table 23.65 admits exactly four answers for GL_LAYER_PROVOKING_VERTEX and
|
||||
// GL_VIEWPORT_INDEX_PROVOKING_VERTEX. Anything else means the driver wrote something MobileGL
|
||||
// cannot forward as a convention, and GL_UNDEFINED_VERTEX - a legal answer, not a placeholder
|
||||
// - is the accurate thing to say about it.
|
||||
static GLenum NormalizeProvokingVertexConvention(GLint driverValue) {
|
||||
switch (static_cast<GLenum>(driverValue)) {
|
||||
case GL_FIRST_VERTEX_CONVENTION:
|
||||
case GL_LAST_VERTEX_CONVENTION:
|
||||
case GL_PROVOKING_VERTEX:
|
||||
case GL_UNDEFINED_VERTEX:
|
||||
return static_cast<GLenum>(driverValue);
|
||||
default:
|
||||
return GL_UNDEFINED_VERTEX;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* ProvokingVertexConventionName(GLenum convention) {
|
||||
switch (convention) {
|
||||
case GL_FIRST_VERTEX_CONVENTION:
|
||||
return "GL_FIRST_VERTEX_CONVENTION";
|
||||
case GL_LAST_VERTEX_CONVENTION:
|
||||
return "GL_LAST_VERTEX_CONVENTION";
|
||||
case GL_PROVOKING_VERTEX:
|
||||
return "GL_PROVOKING_VERTEX";
|
||||
default:
|
||||
return "GL_UNDEFINED_VERTEX";
|
||||
}
|
||||
}
|
||||
|
||||
Bool FillInGLESCapabilities(MG_External::GLESCapabilities& caps, const MG_External::GLESFunctionsTable& glesFuncs) {
|
||||
if (!glesFuncs.glGetString || !glesFuncs.glGetIntegerv) {
|
||||
MGLOG_E("Required GLES functions are not loaded, cannot query capabilities");
|
||||
@@ -1073,6 +1102,11 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
// clipping program silently rendered nothing. The guarded probe below only ever widens it.
|
||||
GLint maxClipDistances = 0;
|
||||
GLint maxViewports = 16;
|
||||
// GL_UNDEFINED_VERTEX is what stands when the probes below cannot run, and it is a legal
|
||||
// answer rather than a placeholder: with neither geometry shaders nor a viewport array
|
||||
// there is no layered or multi-viewport draw for a convention to describe.
|
||||
GLenum layerProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
GLenum viewportIndexProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
GLfloat minFragmentInterpolationOffset = -0.5f;
|
||||
GLfloat maxFragmentInterpolationOffset = 0.4375f;
|
||||
GLint fragmentInterpolationOffsetBits = 4;
|
||||
@@ -1263,6 +1297,21 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
}
|
||||
}
|
||||
glesFuncs.glGetIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDims);
|
||||
// GL_LAYER_PROVOKING_VERTEX is ES 3.2 core (it arrives with geometry shaders, which is
|
||||
// what gl_Layer needs). Ask the driver where the pname exists rather than asserting a
|
||||
// convention: it is a statement about which vertex of a primitive supplies gl_Layer, and
|
||||
// MobileGL forwards the geometry stage to the driver rather than implementing the
|
||||
// selection itself, so the driver's answer IS MobileGL's answer. Below ES 3.2 there are
|
||||
// no layered draws to have a convention for and GL_UNDEFINED_VERTEX stands, which GL 4.6
|
||||
// table 23.65 explicitly permits.
|
||||
if (esAtLeast32) {
|
||||
GLint driverLayerConvention = static_cast<GLint>(GL_UNDEFINED_VERTEX);
|
||||
drainErrors();
|
||||
glesFuncs.glGetIntegerv(GL_LAYER_PROVOKING_VERTEX, &driverLayerConvention);
|
||||
if (!drainErrors()) {
|
||||
layerProvokingVertex = NormalizeProvokingVertexConvention(driverLayerConvention);
|
||||
}
|
||||
}
|
||||
// GL_MAX_VIEWPORTS (0x825B), GL_VIEWPORT_SUBPIXEL_BITS (0x825C) and GL_VIEWPORT_BOUNDS_RANGE
|
||||
// (0x825D) all arrive with GL_OES_viewport_array and exist nowhere in ES core, so on the
|
||||
// drivers DirectGLES actually runs on all three raise GL_INVALID_ENUM. The values MobileGL
|
||||
@@ -1272,9 +1321,11 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
// hold), floors GL_SUBPIXEL_BITS at its own 4, and the bounds range is clamped to the core
|
||||
// minimum below. What changes is that the errors stop being manufactured.
|
||||
if (caps.SupportsViewportArray) {
|
||||
GLint driverViewportIndexConvention = static_cast<GLint>(GL_UNDEFINED_VERTEX);
|
||||
drainErrors();
|
||||
glesFuncs.glGetIntegerv(GL_MAX_VIEWPORTS, &maxViewports);
|
||||
glesFuncs.glGetIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &viewportSubpixelBits);
|
||||
glesFuncs.glGetIntegerv(GL_VIEWPORT_INDEX_PROVOKING_VERTEX, &driverViewportIndexConvention);
|
||||
if (glesFuncs.glGetFloatv) {
|
||||
glesFuncs.glGetFloatv(GL_VIEWPORT_BOUNDS_RANGE, viewportBoundsRange);
|
||||
}
|
||||
@@ -1285,6 +1336,9 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
viewportSubpixelBits = 0;
|
||||
viewportBoundsRange[0] = -32768.0f;
|
||||
viewportBoundsRange[1] = 32767.0f;
|
||||
} else {
|
||||
viewportIndexProvokingVertex =
|
||||
NormalizeProvokingVertexConvention(driverViewportIndexConvention);
|
||||
}
|
||||
}
|
||||
if (caps.SupportsShaderMultisampleInterpolation && glesFuncs.glGetFloatv) {
|
||||
@@ -1452,6 +1506,8 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
// extension the probe above never ran at all - so the flag, not the local, decides.
|
||||
caps.MaxClipDistances = caps.SupportsClipDistance ? std::max(maxClipDistances, 0) : 0;
|
||||
caps.MaxViewports = maxViewports;
|
||||
caps.LayerProvokingVertex = layerProvokingVertex;
|
||||
caps.ViewportIndexProvokingVertex = viewportIndexProvokingVertex;
|
||||
caps.MaxViewportWidth = maxViewportDims[0];
|
||||
caps.MaxViewportHeight = maxViewportDims[1];
|
||||
// Only ever WIDER than the core minimum: a driver that answered the query is allowed to
|
||||
@@ -1543,6 +1599,9 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
MGLOG_I(" GL_VIEWPORT_BOUNDS_RANGE: [%.3f, %.3f]", caps.ViewportBoundsRangeMin,
|
||||
caps.ViewportBoundsRangeMax);
|
||||
MGLOG_I(" GL_VIEWPORT_SUBPIXEL_BITS: %d", caps.ViewportSubpixelBits);
|
||||
MGLOG_I(" GL_LAYER_PROVOKING_VERTEX: %s", ProvokingVertexConventionName(caps.LayerProvokingVertex));
|
||||
MGLOG_I(" GL_VIEWPORT_INDEX_PROVOKING_VERTEX: %s",
|
||||
ProvokingVertexConventionName(caps.ViewportIndexProvokingVertex));
|
||||
|
||||
caps.IndirectDrawInstanceIdIncludesBaseInstance =
|
||||
ProbeIndirectInstanceIdIncludesBaseInstance(caps, glesFuncs);
|
||||
|
||||
@@ -1280,6 +1280,11 @@ namespace MobileGL {
|
||||
// in FillInGLESCapabilities.
|
||||
Int MaxClipDistances = 0;
|
||||
Int MaxViewports = 16;
|
||||
// GL_LAYER_PROVOKING_VERTEX (ES 3.2 core) and GL_VIEWPORT_INDEX_PROVOKING_VERTEX
|
||||
// (GL_OES_viewport_array). GL_UNDEFINED_VERTEX is a legal answer for both and is what
|
||||
// a driver that has neither is honestly saying.
|
||||
GLenum LayerProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
GLenum ViewportIndexProvokingVertex = GL_UNDEFINED_VERTEX;
|
||||
Int MaxViewportWidth = 16384;
|
||||
Int MaxViewportHeight = 16384;
|
||||
Float ViewportBoundsRangeMin = 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user