Skip to content

Commit 79f5686

Browse files
committed
FL0 materials are always compile via spirv-cross
1 parent 115c2cf commit 79f5686

File tree

12 files changed

+64
-97
lines changed

12 files changed

+64
-97
lines changed

filament/src/materials/blitLow.mat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ vertex {
3434

3535
fragment {
3636
void postProcess(inout PostProcessInputs postProcess) {
37-
#if FILAMENT_EFFECTIVE_VERSION == 100
38-
postProcess.color = texture2D(materialParams_color, variable_vertex.xy);
37+
#if MATERIAL_FEATURE_LEVEL == 0
38+
postProcess.color = texture(materialParams_color, variable_vertex.xy);
3939
#else
4040
postProcess.color = textureLod(materialParams_color, variable_vertex.xy, materialParams.levelOfDetail);
4141
#endif

filament/src/materials/skybox.mat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fragment {
3737
sky = materialParams.color;
3838
} else {
3939
#if MATERIAL_FEATURE_LEVEL == 0
40-
sky = vec4(textureCube(materialParams_skybox, variable_eyeDirection.xyz).rgb, 1.0);
40+
sky = vec4(texture(materialParams_skybox, variable_eyeDirection.xyz).rgb, 1.0);
4141
#else
4242
sky = vec4(textureLod(materialParams_skybox, variable_eyeDirection.xyz, 0.0).rgb, 1.0);
4343
sky.rgb *= frameUniforms.iblLuminance;

libs/filagui/src/materials/uiBlit.mat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fragment {
2222
prepareMaterial(material);
2323
vec2 uv = getUV0();
2424
uv.y = 1.0 - uv.y;
25-
vec4 albedo = texture2D(materialParams_albedo, uv);
25+
vec4 albedo = texture(materialParams_albedo, uv);
2626
material.baseColor = getColor() * albedo;
2727
material.baseColor.rgb *= material.baseColor.a;
2828
}

libs/filagui/src/materials/uiBlitExternal.mat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fragment {
2222
prepareMaterial(material);
2323
vec2 uv = getUV0();
2424
uv.y = 1.0 - uv.y;
25-
vec4 albedo = texture2D(materialParams_albedo, uv);
25+
vec4 albedo = texture(materialParams_albedo, uv);
2626
material.baseColor = getColor() * albedo;
2727
material.baseColor.rgb *= material.baseColor.a;
2828
}

libs/filamat/src/GLSLPostProcessor.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,38 @@ bool GLSLPostProcessor::fullOptimization(const TShader& tShader,
950950
if (found != std::string::npos) {
951951
str.replace(found, clipDistanceDefinition.length(), "");
952952
}
953+
954+
// Validate the transpiled ESSL1 shader dynamically before considering it successful.
955+
// This proactively catches unsupported SPIR-V -> ESSL1 translation quirks (like textureLod)
956+
// at compile-time since we can't easily test all variants on physical GLES 2.0 devices.
957+
if (config.featureLevel == 0) {
958+
// preampitively forbid spirv-cross from cheating and polyfilling disabled features
959+
auto const& exts = glslCompiler.get_required_extensions();
960+
for (auto const& ext : exts) {
961+
if (ext != "GL_OES_standard_derivatives" &&
962+
ext != "GL_OES_EGL_image_external" &&
963+
ext != "GL_EXT_shader_framebuffer_fetch" &&
964+
ext != "GL_EXT_shader_framebuffer_fetch_non_coherent") {
965+
slog.e << "ERROR: Feature Level 0 shaders cannot require: " << ext << ". "
966+
<< "spirv-cross attempted to unilaterally inject it." << io::endl;
967+
return false;
968+
}
969+
}
970+
971+
TShader validateShader(internalConfig.shLang);
972+
// The cleaner must be declared after the TShader to manage the glslang memory pool
973+
// teardown order correctly and safely destroy the AST.
974+
GLSLangCleaner const validateCleaner;
975+
976+
const char* shaderCString = str.c_str();
977+
validateShader.setStrings(&shaderCString, 1);
978+
979+
bool const validateOk = validateShader.parse(&DefaultTBuiltInResource, glslOptions.version, false, EShMsgDefault);
980+
if (!validateOk) {
981+
slog.e << "ESSL1 Validation failed:\n" << validateShader.getInfoLog() << io::endl;
982+
return false;
983+
}
984+
}
953985
}
954986
return true;
955987
}

libs/filamat/src/MaterialBuilder.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void MaterialBuilderBase::prepare(bool const vulkanSemantics,
131131
// OpenGL is a special case. If we're doing any optimization, then we need to go to Spir-V.
132132
TargetLanguage glTargetLanguage = mOptimization > Optimization::PREPROCESSOR ?
133133
TargetLanguage::SPIRV : TargetLanguage::GLSL;
134-
if (vulkanSemantics) {
134+
if (vulkanSemantics || featureLevel == backend::FeatureLevel::FEATURE_LEVEL_0) {
135135
// Currently GLSLPostProcessor.cpp is incapable of compiling SPIRV to GLSL without
136136
// running the optimizer. For now we just activate the optimizer in that case.
137137
mOptimization = Optimization::PERFORMANCE;
@@ -167,7 +167,7 @@ void MaterialBuilderBase::prepare(bool const vulkanSemantics,
167167
&& featureLevel == backend::FeatureLevel::FEATURE_LEVEL_0
168168
&& shaderModel == ShaderModel::MOBILE) {
169169
mCodeGenPermutations.push_back({
170-
shaderModel,
170+
ShaderModel::MOBILE,
171171
TargetApi::OPENGL,
172172
glTargetLanguage,
173173
backend::FeatureLevel::FEATURE_LEVEL_0
@@ -938,6 +938,15 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
938938
JobSystem::Job* parent = jobSystem.createJob();
939939

940940
for (const auto& v : variants) {
941+
if (params.featureLevel == FeatureLevel::FEATURE_LEVEL_0) {
942+
assert_invariant(params.shaderModel == ShaderModel::MOBILE);
943+
assert_invariant(params.targetApi == TargetApi::OPENGL);
944+
if (filament::Variant::isStereoVariant(v.variant)) {
945+
// the stereo variant can never be used at feature level 0
946+
continue;
947+
}
948+
}
949+
941950
JobSystem::Job* job = jobs::createJob(jobSystem, parent, [&]() {
942951
if (cancelJobs.load()) {
943952
return;
@@ -1319,8 +1328,7 @@ Package MaterialBuilder::build(JobSystem& jobSystem) {
13191328
CodeGenParams const semanticCodeGenParams = {
13201329
.shaderModel = ShaderModel::MOBILE,
13211330
.targetApi = TargetApi::OPENGL,
1322-
.targetLanguage = (info.featureLevel == FeatureLevel::FEATURE_LEVEL_0) ?
1323-
TargetLanguage::GLSL : TargetLanguage::SPIRV,
1331+
.targetLanguage = TargetLanguage::SPIRV,
13241332
.featureLevel = info.featureLevel,
13251333
};
13261334

libs/filamat/src/shaders/CodeGenerator.cpp

Lines changed: 5 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -202,36 +202,6 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out,
202202
out << "#define FILAMENT_HAS_FEATURE_INSTANCING\n";
203203
}
204204

205-
// During compilation and optimization, __VERSION__ reflects the shader language version of the
206-
// intermediate code, not the version of the final code. spirv-cross automatically adapts
207-
// certain language features (e.g. fragment output) but leaves others untouched (e.g. sampler
208-
// functions, bit shift operations). Client code may have to make decisions based on this
209-
// information, so define a FILAMENT_EFFECTIVE_VERSION constant.
210-
const char *effective_version;
211-
if (mTargetLanguage == TargetLanguage::GLSL) {
212-
effective_version = "__VERSION__";
213-
} else {
214-
switch (mShaderModel) {
215-
case ShaderModel::MOBILE:
216-
if (mFeatureLevel >= FeatureLevel::FEATURE_LEVEL_1) {
217-
effective_version = "300";
218-
} else {
219-
effective_version = "100";
220-
}
221-
break;
222-
case ShaderModel::DESKTOP:
223-
if (mFeatureLevel >= FeatureLevel::FEATURE_LEVEL_2) {
224-
effective_version = "450";
225-
} else {
226-
effective_version = "410";
227-
}
228-
break;
229-
default:
230-
assert(false);
231-
}
232-
}
233-
generateDefine(out, "FILAMENT_EFFECTIVE_VERSION", effective_version);
234-
235205
switch (material.stereoscopicType) {
236206
case StereoscopicType::INSTANCED:
237207
generateDefine(out, "FILAMENT_STEREO_INSTANCED", true);
@@ -253,17 +223,11 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out,
253223
generateDefine(out, "MATERIAL_HAS_CUSTOM_DEPTH", material.userMaterialHasCustomDepth);
254224
}
255225

256-
if (mTargetLanguage == TargetLanguage::SPIRV ||
257-
mFeatureLevel >= FeatureLevel::FEATURE_LEVEL_1) {
258-
if (stage == ShaderStage::VERTEX) {
259-
generateDefine(out, "VARYING", "out");
260-
generateDefine(out, "ATTRIBUTE", "in");
261-
} else if (stage == ShaderStage::FRAGMENT) {
262-
generateDefine(out, "VARYING", "in");
263-
}
264-
} else {
265-
generateDefine(out, "VARYING", "varying");
266-
generateDefine(out, "ATTRIBUTE", "attribute");
226+
if (stage == ShaderStage::VERTEX) {
227+
generateDefine(out, "VARYING", "out");
228+
generateDefine(out, "ATTRIBUTE", "in");
229+
} else if (stage == ShaderStage::FRAGMENT) {
230+
generateDefine(out, "VARYING", "in");
267231
}
268232

269233
auto getShadingDefine = [](Shading shading) -> const char* {
@@ -361,31 +325,6 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out,
361325
out << '\n';
362326
out << SHADERS_COMMON_DEFINES_GLSL_DATA;
363327

364-
if (material.featureLevel == FeatureLevel::FEATURE_LEVEL_0 &&
365-
(mFeatureLevel > FeatureLevel::FEATURE_LEVEL_0
366-
|| mTargetLanguage == TargetLanguage::SPIRV)) {
367-
// Insert compatibility definitions for ESSL 1.0 functions which were removed in ESSL 3.0.
368-
369-
// This is the minimum required value according to the OpenGL ES Shading Language Version
370-
// 1.00 document. glslang forbids defining symbols beginning with gl_ as const, hence the
371-
// #define.
372-
generateDefine(out, "gl_MaxVaryingVectors", "8");
373-
374-
generateDefine(out, "texture2D", "texture");
375-
generateDefine(out, "texture2DProj", "textureProj");
376-
generateDefine(out, "texture3D", "texture");
377-
generateDefine(out, "texture3DProj", "textureProj");
378-
generateDefine(out, "textureCube", "texture");
379-
380-
if (stage == ShaderStage::VERTEX) {
381-
generateDefine(out, "texture2DLod", "textureLod");
382-
generateDefine(out, "texture2DProjLod", "textureProjLod");
383-
generateDefine(out, "texture3DLod", "textureLod");
384-
generateDefine(out, "texture3DProjLod", "textureProjLod");
385-
generateDefine(out, "textureCubeLod", "textureLod");
386-
}
387-
}
388-
389328
// Api level enforcement.
390329
generateDefine(out, "CLIENT_MATERIAL_API_LEVEL", apiLevel);
391330
generateDefine(out, "UNSTABLE_MATERIAL_API_LEVEL", filament::UNSTABLE_MATERIAL_API_LEVEL);

libs/filamat/tests/test_filamat.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ TEST_F(MaterialCompiler, FeatureLevel0Sampler2D) {
923923
std::string shaderCode(R"(
924924
void material(inout MaterialInputs material) {
925925
prepareMaterial(material);
926-
material.baseColor = texture2D(materialParams_sampler, vec2(0.0, 0.0));
926+
material.baseColor = texture(materialParams_sampler, vec2(0.0, 0.0));
927927
}
928928
)");
929929
filamat::MaterialBuilder builder;
@@ -941,7 +941,7 @@ TEST_F(MaterialCompiler, SamplerTransformName) {
941941
void material(inout MaterialInputs material) {
942942
prepareMaterial(material);
943943
vec3 uvw = materialParams.sampler_transform * vec3(0.0, 0.0, 0.0);
944-
material.baseColor = texture2D(materialParams_sampler, uvw.xy);
944+
material.baseColor = texture(materialParams_sampler, uvw.xy);
945945
}
946946
)");
947947
filamat::MaterialBuilder builder;
@@ -960,7 +960,7 @@ TEST_F(MaterialCompiler, SamplerMissingTransformName) {
960960
void material(inout MaterialInputs material) {
961961
prepareMaterial(material);
962962
vec3 uvw = materialParams.sampler_transform * vec3(0.0, 0.0, 0.0);
963-
material.baseColor = texture2D(materialParams_sampler, uvw.xy);
963+
material.baseColor = texture(materialParams_sampler, uvw.xy);
964964
}
965965
)");
966966
filamat::MaterialBuilder builder;

shaders/src/common_getters.glsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ highp mat4 getViewFromClipMatrix() {
4646
return frameUniforms.viewFromClipMatrix;
4747
}
4848

49-
#if FILAMENT_EFFECTIVE_VERSION > 100
49+
#if MATERIAL_FEATURE_LEVEL > 0
5050
/** @public-api */
5151
highp mat4 getEyeFromViewMatrix() {
5252
return frameUniforms.eyeFromViewMatrix[getEyeIndex()];

shaders/src/surface_depth_main.fs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
#if defined(VARIANT_HAS_VSM)
22
layout(location = 0) out highp vec4 fragColor;
33
#elif defined(VARIANT_HAS_PICKING)
4-
# if __VERSION__ == 100
5-
highp vec4 outPicking;
6-
# else
7-
# if MATERIAL_FEATURE_LEVEL == 0
4+
# if MATERIAL_FEATURE_LEVEL == 0
85
layout(location = 0) out highp vec4 outPicking;
9-
# else
6+
# else
107
layout(location = 0) out highp uvec2 outPicking;
11-
# endif
128
# endif
139
#else
1410
// not color output
@@ -55,7 +51,7 @@ void main() {
5551
highp float depth = vertex_worldPosition.w;
5652
fragColor = computeDepthMomentsVSM(depth);
5753
#elif defined(VARIANT_HAS_PICKING)
58-
#if FILAMENT_EFFECTIVE_VERSION == 100
54+
#if MATERIAL_FEATURE_LEVEL == 0
5955
outPicking.a = mod(float(object_uniforms_objectId / 65536), 256.0) / 255.0;
6056
outPicking.b = mod(float(object_uniforms_objectId / 256), 256.0) / 255.0;
6157
outPicking.g = mod(float(object_uniforms_objectId) , 256.0) / 255.0;
@@ -64,9 +60,7 @@ void main() {
6460
outPicking.x = uint(object_uniforms_objectId);
6561
outPicking.y = floatBitsToUint(vertex_position.z / vertex_position.w);
6662
#endif
67-
#if __VERSION__ == 100
68-
gl_FragData[0] = outPicking;
69-
#endif
63+
7064
#else
7165
// that's it
7266
#endif

0 commit comments

Comments
 (0)