Fix T98190: EEVEE: Very slow rendering on Intel HD Graphics 4400

This particular GPU driver does not constant fold all the way in order
to discard the unused branches.

To workaround that, we introduce a series of material flag that generates
defines that only keep used branches.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D15852
This commit is contained in:
Clément Foucault
2022-09-02 13:48:55 +02:00
committed by Clément Foucault
parent f366d197db
commit de818d81c3
5 changed files with 60 additions and 1 deletions

View File

@@ -77,12 +77,20 @@ typedef enum eGPUMaterialFlag {
GPU_MATFLAG_HOLDOUT = (1 << 6),
GPU_MATFLAG_SHADER_TO_RGBA = (1 << 7),
GPU_MATFLAG_AO = (1 << 8),
GPU_MATFLAG_CLEARCOAT = (1 << 9),
GPU_MATFLAG_OBJECT_INFO = (1 << 10),
GPU_MATFLAG_AOV = (1 << 11),
GPU_MATFLAG_BARYCENTRIC = (1 << 20),
/* Optimization to only add the branches of the principled shader that are necessary. */
GPU_MATFLAG_PRINCIPLED_CLEARCOAT = (1 << 21),
GPU_MATFLAG_PRINCIPLED_METALLIC = (1 << 22),
GPU_MATFLAG_PRINCIPLED_DIELECTRIC = (1 << 23),
GPU_MATFLAG_PRINCIPLED_GLASS = (1 << 24),
GPU_MATFLAG_PRINCIPLED_ANY = (1 << 25),
/* Tells the render engine the material was just compiled or updated. */
GPU_MATFLAG_UPDATED = (1 << 29),

View File

@@ -351,6 +351,24 @@ void GPUCodegen::generate_resources()
{
GPUCodegenCreateInfo &info = *create_info;
/* Ref. T98190: Defines are optimizations for old compilers.
* Might become unecessary with EEVEE-Next. */
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_CLEARCOAT)) {
info.define("PRINCIPLED_CLEARCOAT");
}
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_METALLIC)) {
info.define("PRINCIPLED_METALLIC");
}
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_DIELECTRIC)) {
info.define("PRINCIPLED_DIELECTRIC");
}
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_GLASS)) {
info.define("PRINCIPLED_GLASS");
}
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_ANY)) {
info.define("PRINCIPLED_ANY");
}
std::stringstream ss;
/* Textures. */

View File

@@ -149,25 +149,37 @@ void node_bsdf_principled(vec4 base_color,
max(roughness, transmission_roughness);
refraction_data.ior = ior;
/* Ref. T98190: Defines are optimizations for old compilers.
* Might become unecessary with EEVEE-Next. */
if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat != 0.0) {
#ifdef PRINCIPLED_CLEARCOAT
/* Metallic & Clearcoat case. */
result = closure_eval(reflection_data, clearcoat_data);
#endif
}
else if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) {
#ifdef PRINCIPLED_METALLIC
/* Metallic case. */
result = closure_eval(reflection_data);
#endif
}
else if (do_diffuse != 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) {
#ifdef PRINCIPLED_DIELECTRIC
/* Dielectric case. */
result = closure_eval(diffuse_data, reflection_data);
#endif
}
else if (do_diffuse == 0.0 && do_refraction != 0.0 && do_clearcoat == 0.0) {
#ifdef PRINCIPLED_GLASS
/* Glass case. */
result = closure_eval(reflection_data, refraction_data);
#endif
}
else {
#ifdef PRINCIPLED_ANY
/* Un-optimized case. */
result = closure_eval(diffuse_data, reflection_data, clearcoat_data, refraction_data);
#endif
}
Closure emission_cl = closure_eval(emission_data);
Closure transparency_cl = closure_eval(transparency_data);

View File

@@ -167,6 +167,27 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
if (use_transparency) {
flag |= GPU_MATFLAG_TRANSPARENT;
}
if (use_clear) {
flag |= GPU_MATFLAG_CLEARCOAT;
}
/* Ref. T98190: Defines are optimizations for old compilers.
* Might become unecessary with EEVEE-Next. */
if (use_diffuse == false && use_refract == false && use_clear == true) {
flag |= GPU_MATFLAG_PRINCIPLED_CLEARCOAT;
}
else if (use_diffuse == false && use_refract == false && use_clear == false) {
flag |= GPU_MATFLAG_PRINCIPLED_METALLIC;
}
else if (use_diffuse == true && use_refract == false && use_clear == false) {
flag |= GPU_MATFLAG_PRINCIPLED_DIELECTRIC;
}
else if (use_diffuse == false && use_refract == true && use_clear == false) {
flag |= GPU_MATFLAG_PRINCIPLED_GLASS;
}
else {
flag |= GPU_MATFLAG_PRINCIPLED_ANY;
}
if (use_subsurf) {
bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);