mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-18 09:08:31 +09:00
[Feat] (Backend, MGPipe): carry the six per-axis compute limits in DynamicBackendParameters so MGPCaps has every backend-owned indexed answer, and pin them against glGetIntegeri_v on both backends
- P-1: MGPCaps is DynamicBackendParameters by inclusion (plan B section 4.4.1), but that struct carried MaxComputeWorkGroupInvocations and no per-axis GL_MAX_COMPUTE_WORK_GROUP_COUNT / GL_MAX_COMPUTE_WORK_GROUP_SIZE - the six numbers that ARE the backend-owned indexed answers surviving the getter retirement (GL_Getter.cpp and CompileEnv.cpp ask GLFunctionsTable::GetIntegeri_v for exactly these, DirectVulkan answers them from VkPhysicalDeviceLimits), so the interface had a hole where its only genuine indexed carrier should be. DynamicBackendParameters now has MaxComputeWorkGroupCount[3] / MaxComputeWorkGroupSize[3] with the GL 4.3 minimums as the no-backend defaults; DirectGLES fills them from glGetIntegeri_v inside the loader's bracketed probe run (GLESCapabilities carries them, logged with the other limits) and DirectVulkan from maxComputeWorkGroupCount / maxComputeWorkGroupSize through the loader's SaturateToInt like every other limit. Raw driver answers, as the invocations limit is: the frontend floors them at the shared MIN_COMPUTE_WORK_GROUP_* minimums itself. - The GetIntegeri_v table path is untouched, as is GL_Getter and CompileEnv behaviour: retiring the getter in favour of the caps is P0.5, and this only makes sure the caps have what P0.5 needs. - PipeCalls.def's footer no longer claims that "only GL_COMPUTE_WORK_GROUP_SIZE is a real backend answer and it lives in MGPCaps": the six limits live in MGPCaps, and GL_COMPUTE_WORK_GROUP_SIZE is a frontend link artifact (ProgramObject::GetComputeLocalSize, what GL_Program.cpp answers from), which AdvertisedLimitsScenario.ComputeLocalSizeComesFromTheLinkedProgram already pins. The MGPCaps size assertion is a composition of sizeof(DynamicBackendParameters) and follows the struct. - AdvertisedLimitsScenario.ComputeWorkGroupLimitsAreTheCapsBlocksAnswer pins, on both lanes: answerability, the GL 4.3 floors, vector/indexed agreement, INVALID_VALUE past axis 2, and - through the new Harness/BackendCapsPeek translation unit, which is the one place the module looks past the GL API - that max(caps, minimum) equals the live glGetIntegeri_v answer axis by axis. Shown live by halving each backend's caps copy: both lanes fail with "MGPCaps carries 512 but glGetIntegeri_v answers 1024". On Android the module links the shipping .so (hidden visibility), so the peek returns false there and only the GL-visible half runs. ComputeWorkGroupCapabilities.TakesEveryAxisFromTheIndexedQuery in BackendLoaderTest pins the DirectGLES loader half against the fake driver, per axis and above the initialisers. - Verified: AdvertisedLimitsScenario 20/20 on DirectGLES and DirectVulkan (llvmpipe / lavapipe), BackendLoaderTest green.
This commit is contained in:
@@ -1145,6 +1145,8 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
GLint maxFragmentShaderStorageBlocks = 4;
|
||||
GLint maxComputeUniformBlocks = 12;
|
||||
GLint maxComputeWorkGroupInvocations = 128;
|
||||
GLint maxComputeWorkGroupCount[3] = {65535, 65535, 65535};
|
||||
GLint maxComputeWorkGroupSize[3] = {1024, 1024, 64};
|
||||
GLint maxShaderStorageBufferBindings = 8;
|
||||
GLint maxTextureBufferSize = 65536;
|
||||
GLint maxUniformBufferBindings = 24;
|
||||
@@ -1276,6 +1278,17 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
glesFuncs.glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedShaderStorageBlocks);
|
||||
glesFuncs.glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &maxComputeUniformBlocks);
|
||||
glesFuncs.glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &maxComputeWorkGroupInvocations);
|
||||
// The per-axis pair beside it, through the indexed query. ES 3.1 core like the
|
||||
// invocations limit, so it sits inside the same bracketed run: a 3.0 context rejects
|
||||
// it, the drain below swallows the error and the locals keep the GL 4.3 minimums.
|
||||
// These are the six backend-owned indexed answers that cross the MGPipe boundary in
|
||||
// MGPCaps (DynamicBackendParameters::MaxComputeWorkGroupCount/Size).
|
||||
if (glesFuncs.glGetIntegeri_v) {
|
||||
for (GLuint axis = 0; axis < 3; ++axis) {
|
||||
glesFuncs.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, axis, &maxComputeWorkGroupCount[axis]);
|
||||
glesFuncs.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, axis, &maxComputeWorkGroupSize[axis]);
|
||||
}
|
||||
}
|
||||
glesFuncs.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
|
||||
// GL_MAX_TEXTURE_BUFFER_SIZE is deliberately NOT batched here: like
|
||||
// GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT below, the pname only exists once buffer textures do,
|
||||
@@ -1584,6 +1597,10 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.MaxFragmentShaderStorageBlocks = maxFragmentShaderStorageBlocks;
|
||||
caps.MaxComputeUniformBlocks = maxComputeUniformBlocks;
|
||||
caps.MaxComputeWorkGroupInvocations = maxComputeWorkGroupInvocations;
|
||||
for (SizeT axis = 0; axis < 3; ++axis) {
|
||||
caps.MaxComputeWorkGroupCount[axis] = maxComputeWorkGroupCount[axis];
|
||||
caps.MaxComputeWorkGroupSize[axis] = maxComputeWorkGroupSize[axis];
|
||||
}
|
||||
caps.MaxShaderStorageBufferBindings = maxShaderStorageBufferBindings;
|
||||
caps.MaxTextureBufferSize = maxTextureBufferSize;
|
||||
// Through glesFuncs, like every other capability query here: a bare glGetIntegerv resolves
|
||||
@@ -1681,6 +1698,10 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
MGLOG_I(" GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: %d", caps.MaxFragmentShaderStorageBlocks);
|
||||
MGLOG_I(" GL_MAX_COMPUTE_UNIFORM_BLOCKS: %d", caps.MaxComputeUniformBlocks);
|
||||
MGLOG_I(" GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: %d", caps.MaxComputeWorkGroupInvocations);
|
||||
MGLOG_I(" GL_MAX_COMPUTE_WORK_GROUP_COUNT: %d %d %d", caps.MaxComputeWorkGroupCount[0],
|
||||
caps.MaxComputeWorkGroupCount[1], caps.MaxComputeWorkGroupCount[2]);
|
||||
MGLOG_I(" GL_MAX_COMPUTE_WORK_GROUP_SIZE: %d %d %d", caps.MaxComputeWorkGroupSize[0],
|
||||
caps.MaxComputeWorkGroupSize[1], caps.MaxComputeWorkGroupSize[2]);
|
||||
MGLOG_I(" GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: %d", caps.MaxShaderStorageBufferBindings);
|
||||
// Three distinct states, and the suffix must not conflate them: a driver answer, a floor
|
||||
// kept because there are no buffer textures to ask about, and a floor kept because the
|
||||
|
||||
@@ -1309,6 +1309,11 @@ namespace MobileGL {
|
||||
Int MaxFragmentShaderStorageBlocks = 4;
|
||||
Int MaxComputeUniformBlocks = 12;
|
||||
Int MaxComputeWorkGroupInvocations = 128;
|
||||
// GL_MAX_COMPUTE_WORK_GROUP_COUNT / _SIZE per axis, as the driver answers
|
||||
// glGetIntegeri_v. Raw: the frontend floors them at the GL minimums itself. The
|
||||
// initialisers are those minimums, for a context that rejects the query.
|
||||
Int MaxComputeWorkGroupCount[3] = {65535, 65535, 65535};
|
||||
Int MaxComputeWorkGroupSize[3] = {1024, 1024, 64};
|
||||
Int MaxShaderStorageBufferBindings = 8;
|
||||
Int MaxTextureBufferSize = 65536;
|
||||
// GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT; 1 means the offset is unconstrained.
|
||||
|
||||
@@ -196,6 +196,10 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.MaxCombinedShaderStorageBlocks = SaturateToInt(p.limits.maxDescriptorSetStorageBuffers);
|
||||
caps.MaxComputeUniformBlocks = SaturateToInt(p.limits.maxPerStageDescriptorUniformBuffers);
|
||||
caps.MaxComputeWorkGroupInvocations = SaturateToInt(p.limits.maxComputeWorkGroupInvocations);
|
||||
for (SizeT axis = 0; axis < 3; ++axis) {
|
||||
caps.MaxComputeWorkGroupCount[axis] = SaturateToInt(p.limits.maxComputeWorkGroupCount[axis]);
|
||||
caps.MaxComputeWorkGroupSize[axis] = SaturateToInt(p.limits.maxComputeWorkGroupSize[axis]);
|
||||
}
|
||||
caps.MaxShaderStorageBufferBindings = SaturateToInt(p.limits.maxDescriptorSetStorageBuffers);
|
||||
caps.MaxTextureBufferSize = SaturateToInt(p.limits.maxTexelBufferElements);
|
||||
caps.TextureBufferOffsetAlignment =
|
||||
@@ -333,6 +337,10 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.MaxCombinedShaderStorageBlocks = SaturateToInt(properties.limits.maxDescriptorSetStorageBuffers);
|
||||
caps.MaxComputeUniformBlocks = SaturateToInt(properties.limits.maxPerStageDescriptorUniformBuffers);
|
||||
caps.MaxComputeWorkGroupInvocations = SaturateToInt(properties.limits.maxComputeWorkGroupInvocations);
|
||||
for (SizeT axis = 0; axis < 3; ++axis) {
|
||||
caps.MaxComputeWorkGroupCount[axis] = SaturateToInt(properties.limits.maxComputeWorkGroupCount[axis]);
|
||||
caps.MaxComputeWorkGroupSize[axis] = SaturateToInt(properties.limits.maxComputeWorkGroupSize[axis]);
|
||||
}
|
||||
caps.MaxShaderStorageBufferBindings = SaturateToInt(properties.limits.maxDescriptorSetStorageBuffers);
|
||||
caps.MaxTextureBufferSize = SaturateToInt(properties.limits.maxTexelBufferElements);
|
||||
caps.TextureBufferOffsetAlignment =
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace MobileGL {
|
||||
Int MaxCombinedShaderStorageBlocks = 32;
|
||||
Int MaxComputeUniformBlocks = 12;
|
||||
Int MaxComputeWorkGroupInvocations = 128;
|
||||
// VkPhysicalDeviceLimits::maxComputeWorkGroupCount / maxComputeWorkGroupSize per
|
||||
// axis, saturated to Int like every other limit here. Raw: the frontend floors them
|
||||
// at the GL minimums itself.
|
||||
Int MaxComputeWorkGroupCount[3] = {65535, 65535, 65535};
|
||||
Int MaxComputeWorkGroupSize[3] = {1024, 1024, 64};
|
||||
Int MaxShaderStorageBufferBindings = 8;
|
||||
Int MaxTextureBufferSize = 65536;
|
||||
// GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT; 1 means the offset is unconstrained.
|
||||
|
||||
Reference in New Issue
Block a user