WASM: Set CONFIG_MAX_INSTANCES to a small value + hack the GLSL.

Temporary fix until spec constants arrive.

Second attempt, fixes #5859.
This commit is contained in:
Philip Rideout
2022-08-24 16:24:25 -07:00
parent 39cb238065
commit fe3790cb9c
3 changed files with 39 additions and 0 deletions
+1
View File
@@ -5,6 +5,7 @@ A new header is inserted each time a *tag* is created.
## main branch
- WebGL: reduce max instance count to work around Chrome issues [⚠️ **Recompile Materials**]
- engine: rework material/shader sampler binding code [⚠️ **Recompile Materials**]
## v1.26.0
@@ -131,6 +131,34 @@ void OpenGLProgram::compileShaders(OpenGLContext& context,
}
}
#ifdef __EMSCRIPTEN__
// HACK ALERT
// ----------
// The values below are based on CONFIG_MAX_INSTANCES, which is not accessible here.
// Since matc cannot know if it's building for WebGL, we replace the constant at run
// time. This will go away after we support specialization constants. The name of the
// struct field might be changed by the GLSL optimizer, so we search for any codeline
// that has the pattern: "PerRenderableData(.*)[64]"
const std::string_view type = "PerRenderableData";
const std::string_view source = "[64]";
const std::string_view target = "[8] ";
assert_invariant(source.size() == target.size());
const size_t npos = std::string_view::npos;
for (size_t typePos = shaderView.find(type); typePos != npos;) {
size_t newlinePos = shaderView.find('\n', typePos + type.size());
std::string_view codeline = shaderView.substr(typePos, newlinePos - typePos);
if (size_t sourcePos = codeline.find(source, type.size()); sourcePos != npos) {
if (temp.empty()) {
temp = shaderView;
}
target.copy(temp.data() + typePos + sourcePos, target.size());
shaderView = temp;
break;
}
typePos = shaderView.find(type, newlinePos + 1);
}
#endif
// Tragically, OpenGL 4.1 doesn't support unpackHalf2x16 and
// MacOS doesn't support GL_ARB_shading_language_packing
if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL) {
@@ -65,8 +65,18 @@ constexpr size_t CONFIG_MAX_SHADOW_CASCADES = 4;
// instances, and shadow casting spotlights.
constexpr size_t CONFIG_MINSPEC_UBO_SIZE = 16384;
// HACK ALERT
// ----------
// If you modify the values below, you will need to update the hack in OpenGLProgram.cpp!
// The maximum number of instances that Filament automatically creates as an optimization.
// Use a much smaller number for WebGL as a workaround for the following Chrome issues:
// https://crbug.com/1348017 Compiling GLSL is very slow with struct arrays
// https://crbug.com/1348363 Lighting looks wrong with D3D11 but not OpenGL
#if defined(__EMSCRIPTEN__)
constexpr size_t CONFIG_MAX_INSTANCES = 8;
#else
constexpr size_t CONFIG_MAX_INSTANCES = 64;
#endif
// The maximum number of bones that can be associated with a single renderable.
// We store 32 bytes per bone. Must be a power-of-two, and must fit within CONFIG_MINSPEC_UBO_SIZE.