mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (SelfTest): stop optional-capability failures from declaring the whole backend unsupported, and log the POST report in chunks
This commit is contained in:
@@ -702,8 +702,11 @@ namespace MobileGL::MG_Util::SelfTest {
|
||||
// Every emit carries the extension-presence fact the old standalone
|
||||
// GL_EXT_disjoint_timer_query row showed, plus the probe outcome.
|
||||
const String extensionPresent = "GL_EXT_disjoint_timer_query extension present";
|
||||
// FailOptional: a driver that advertises the extension and then cannot serve a
|
||||
// query is broken in a way nothing substitutes for, but timing GPU work is not
|
||||
// something the backend needs in order to run.
|
||||
const auto fail = [&](const String& detail) {
|
||||
builder.Fail("Timer queries", extensionPresent + "; but " + detail + disabledNote);
|
||||
builder.FailOptional("Timer queries", extensionPresent + "; but " + detail + disabledNote);
|
||||
};
|
||||
|
||||
if (!glesFuncs.glGenQueries || !glesFuncs.glDeleteQueries || !glesFuncs.glBeginQuery ||
|
||||
@@ -837,8 +840,11 @@ namespace MobileGL::MG_Util::SelfTest {
|
||||
const String pathNote = native ? "GL_NV_shader_noperspective_interpolation present (native path)"
|
||||
: "GL_NV_shader_noperspective_interpolation absent (gl_Position.w / "
|
||||
"gl_FragCoord.w emulation path)";
|
||||
// FailOptional: a shaderpack that declares a noperspective varying renders it wrong
|
||||
// and nothing stands in for the interpolation, but everything that does not use one
|
||||
// is unaffected, so the backend still runs.
|
||||
const auto fail = [&](const String& detail) {
|
||||
builder.Fail("noperspective interpolation", pathNote + "; " + detail);
|
||||
builder.FailOptional("noperspective interpolation", pathNote + "; " + detail);
|
||||
};
|
||||
|
||||
if (!g.glCreateShader || !g.glShaderSource || !g.glCompileShader || !g.glGetShaderiv ||
|
||||
@@ -1336,8 +1342,10 @@ namespace MobileGL::MG_Util::SelfTest {
|
||||
const String timestampFacts =
|
||||
format("timestampValidBits = {} on the graphics queue family; timestampPeriod = {} ns per tick",
|
||||
timestampValidBits, timestampPeriod);
|
||||
// FailOptional, for the same reason as the GLES row: the backend does not need to
|
||||
// time GPU work in order to run.
|
||||
const auto fail = [&](const String& detail) {
|
||||
builder.Fail("Timer queries", timestampFacts + "; but " + detail + disabledNote);
|
||||
builder.FailOptional("Timer queries", timestampFacts + "; but " + detail + disabledNote);
|
||||
};
|
||||
const auto vkCreateDeviceFn =
|
||||
reinterpret_cast<PFN_vkCreateDevice>(getInstanceProcAddr(instance, "vkCreateDevice"));
|
||||
@@ -1557,7 +1565,13 @@ namespace MobileGL::MG_Util::SelfTest {
|
||||
Bool subgroupPropertiesAvailable,
|
||||
const VkPhysicalDeviceSubgroupProperties& subgroupProperties) {
|
||||
constexpr const char* RowName = "Subgroup first-reduction witness";
|
||||
const auto fail = [&](String detail) { builder.Fail(RowName, Move(detail)); };
|
||||
// FailOptional, not Fail. The witness reports whether the NATIVE subgroup
|
||||
// first-reduction works; when it does not, the renderer takes its non-subgroup
|
||||
// iteration path and draws the same image. Both an Adreno 830 and Mesa lavapipe
|
||||
// fail this row's topology check today while running the DirectVulkan backend
|
||||
// perfectly well, so a fatal verdict here would have the screen announce that a
|
||||
// backend the user is looking at through that very backend cannot run.
|
||||
const auto fail = [&](String detail) { builder.FailOptional(RowName, Move(detail)); };
|
||||
|
||||
if (!subgroupPropertiesAvailable) {
|
||||
fail("vkGetPhysicalDeviceProperties2 could not provide raw Vulkan subgroup properties");
|
||||
|
||||
@@ -239,13 +239,34 @@ public final class PostActivity extends Activity {
|
||||
nativeLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the whole report to logcat. The report is the only machine-readable form of the
|
||||
* POST, and logcat drops everything past roughly 4000 bytes of a single entry - which is
|
||||
* less than one backend section, so a one-call log silently truncated the report to about
|
||||
* the first dozen rows. Each chunk is prefixed with its index so a reader can reassemble
|
||||
* them in order (concatenate the payloads after the "] " separator).
|
||||
*/
|
||||
private static void logReport(String json) {
|
||||
if (json == null) {
|
||||
Log.i(TAG, "<null report>");
|
||||
return;
|
||||
}
|
||||
final int chunkSize = 3000;
|
||||
final int chunks = (json.length() + chunkSize - 1) / chunkSize;
|
||||
for (int index = 0; index < chunks; ++index) {
|
||||
final int start = index * chunkSize;
|
||||
final int end = Math.min(start + chunkSize, json.length());
|
||||
Log.i(TAG, "[" + (index + 1) + "/" + chunks + "] " + json.substring(start, end));
|
||||
}
|
||||
}
|
||||
|
||||
private static void runDriverPost() {
|
||||
String json = null;
|
||||
Throwable failure = null;
|
||||
try {
|
||||
ensureNativeLoaded();
|
||||
json = nativeRunDriverPost();
|
||||
Log.i(TAG, json == null ? "<null report>" : json);
|
||||
logReport(json);
|
||||
} catch (Throwable error) {
|
||||
Log.e(TAG, "Driver POST failed", error);
|
||||
failure = error;
|
||||
|
||||
Reference in New Issue
Block a user