Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geometry shader support #28237

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drivers/gles2/shader_compiler_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener

Error ShaderCompilerGLES2::compile(VS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {

Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types());
Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_ranges(p_mode), ShaderTypes::get_singleton()->get_types());

if (err != OK) {

Expand Down
2 changes: 1 addition & 1 deletion drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2361,7 +2361,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test)
return; //bye

if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_geometry && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//shader does not use discard and does not write a vertex position, use generic material
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material_twosided : default_material_twosided);
Expand Down
11 changes: 10 additions & 1 deletion drivers/gles3/rasterizer_storage_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2107,9 +2107,12 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_depth_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.uses_geometry = false;
p_shader->spatial.writes_modelview_or_projection = false;
p_shader->spatial.uses_world_coordinates = false;

shaders.actions_scene.render_mode_values["geometry_max_vertices"] = Pair<int *, int>(&p_shader->spatial.max_vertices, 0);

shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
shaders.actions_scene.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_SUB);
Expand Down Expand Up @@ -2143,6 +2146,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
shaders.actions_scene.write_flag_pointers["OUT_VERTEX"] = &p_shader->spatial.uses_geometry;

actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
Expand All @@ -2161,7 +2165,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {

ERR_FAIL_COND(err != OK);

p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.defines);
p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.geometry, gen_code.geometry_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.defines);

p_shader->ubo_size = gen_code.uniform_total_size;
p_shader->ubo_offsets = gen_code.uniform_offsets;
Expand All @@ -2170,6 +2174,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->texture_types = gen_code.texture_types;

p_shader->uses_vertex_time = gen_code.uses_vertex_time;
p_shader->uses_geometry_time = gen_code.uses_geometry_time;
p_shader->uses_fragment_time = gen_code.uses_fragment_time;

//all materials using this shader will have to be invalidated, unfortunately
Expand Down Expand Up @@ -2999,6 +3004,10 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
is_animated = true;
}

if (material->shader->spatial.uses_geometry && material->shader->uses_geometry_time) {
is_animated = true;
}

if (material->shader->spatial.uses_vertex && material->shader->uses_vertex_time) {
is_animated = true;
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/gles3/rasterizer_storage_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,12 +479,14 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
};

int cull_mode;
int max_vertices;

bool uses_alpha;
bool uses_alpha_scissor;
bool unshaded;
bool no_depth_test;
bool uses_vertex;
bool uses_geometry;
bool uses_discard;
bool uses_sss;
bool uses_screen_texture;
Expand All @@ -501,6 +503,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
} particles;

bool uses_vertex_time;
bool uses_geometry_time;
bool uses_fragment_time;

Shader() :
Expand Down
88 changes: 84 additions & 4 deletions drivers/gles3/shader_compiler_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,24 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
}

for (Map<StringName, int>::Element *E = pnode->render_ranges.front(); E; E = E->next()) {

if (p_default_actions.render_mode_defines.has(E->key()) && !used_rmode_defines.has(E->key())) {

r_gen_code.defines.push_back((p_default_actions.render_mode_defines[E->key()] + itos(E->get()) + String("\n")).utf8());
used_rmode_defines.insert(E->key());
}

if (p_actions.render_mode_flags.has(E->key())) {
*p_actions.render_mode_flags[E->key()] = true;
}

if (p_actions.render_mode_values.has(E->key())) {
Pair<int *, int> &p = p_actions.render_mode_values[E->key()];
*p.first = p.second;
}
}

int max_texture_uniforms = 0;
int max_uniforms = 0;

Expand Down Expand Up @@ -379,6 +397,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
ucode += ";\n";
if (SL::is_sampler_type(E->get().type)) {
r_gen_code.vertex_global += ucode;
r_gen_code.geometry_global += ucode;
r_gen_code.fragment_global += ucode;
r_gen_code.texture_uniforms.write[E->get().texture_order] = _mkid(E->key());
r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
Expand Down Expand Up @@ -467,8 +486,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
vcode += " " + _mkid(E->key());
varyings.insert(E->key());
String gcode = vcode + "[];";
vcode += ";\n";
r_gen_code.vertex_global += interp_mode + "out " + vcode;
r_gen_code.geometry_global += interp_mode + "in " + gcode;
r_gen_code.fragment_global += interp_mode + "in " + vcode;
}

Expand All @@ -484,6 +506,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
//place functions in actual code

Set<StringName> added_vtx;
Set<StringName> added_geometry;
Set<StringName> added_fragment; //share for light

for (int i = 0; i < pnode->functions.size(); i++) {
Expand All @@ -498,6 +521,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
r_gen_code.vertex = function_code[vertex_name];
}

if (fnode->name == geometry_name) {
_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.geometry_global, added_geometry);
r_gen_code.geometry = function_code[geometry_name];
}

if (fnode->name == fragment_name) {

_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment);
Expand Down Expand Up @@ -581,13 +609,19 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener

if (p_default_actions.renames.has(vnode->name))
code = p_default_actions.renames[vnode->name];
else
code = _mkid(vnode->name);

else {
if (current_func_name == geometry_name && varyings.has(vnode->name))
code = _mkid(vnode->name) + "[index]";
else
code = _mkid(vnode->name);
}
if (vnode->name == time_name) {
if (current_func_name == vertex_name) {
r_gen_code.uses_vertex_time = true;
}
if (current_func_name == geometry_name) {
r_gen_code.uses_geometry_time = true;
}
if (current_func_name == fragment_name || current_func_name == light_name) {
r_gen_code.uses_fragment_time = true;
}
Expand Down Expand Up @@ -742,7 +776,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener

Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {

Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types());
Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_ranges(p_mode), ShaderTypes::get_singleton()->get_types());

if (err != OK) {

Expand All @@ -758,15 +792,19 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code,
r_gen_code.defines.clear();
r_gen_code.vertex = String();
r_gen_code.vertex_global = String();
r_gen_code.geometry = String();
r_gen_code.geometry_global = String();
r_gen_code.fragment = String();
r_gen_code.fragment_global = String();
r_gen_code.light = String();
r_gen_code.uses_fragment_time = false;
r_gen_code.uses_geometry_time = false;
r_gen_code.uses_vertex_time = false;

used_name_defines.clear();
used_rmode_defines.clear();
used_flag_pointers.clear();
varyings.clear();

_dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode], false);

Expand Down Expand Up @@ -796,6 +834,13 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass";
actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom";

actions[VS::SHADER_CANVAS_ITEM].renames["LENGTH"] = "gl_in.length()";
actions[VS::SHADER_CANVAS_ITEM].renames["INDEX"] = "index";
actions[VS::SHADER_CANVAS_ITEM].renames["IN_VERTEX"] = "gl_in[index].gl_Position";
actions[VS::SHADER_CANVAS_ITEM].renames["OUT_VERTEX"] = "gl_Position";
actions[VS::SHADER_CANVAS_ITEM].renames["OUT_COLOR"] = "color_interp";
actions[VS::SHADER_CANVAS_ITEM].renames["OUT_UV"] = "uv_interp";

actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal";
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map";
Expand Down Expand Up @@ -825,6 +870,15 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";

actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_max_vertices"] = "#define GEOMETRY_MAX_VERTICES ";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_in_points"] = "#define GEOMETRY_IN_MODE 0\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_in_lines"] = "#define GEOMETRY_IN_MODE 1\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_in_triangles"] = "#define GEOMETRY_IN_MODE 2\n";

actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_out_points"] = "#define GEOMETRY_OUT_MODE 0\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_out_lines"] = "#define GEOMETRY_OUT_MODE 1\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_out_triangles"] = "#define GEOMETRY_OUT_MODE 2\n";

/** SPATIAL SHADER **/

actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform";
Expand All @@ -845,6 +899,17 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize";
actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "gl_InstanceID";

actions[VS::SHADER_SPATIAL].renames["LENGTH"] = "gl_in.length()";
actions[VS::SHADER_SPATIAL].renames["INDEX"] = "index";
actions[VS::SHADER_SPATIAL].renames["IN_VERTEX"] = "gl_in[index].gl_Position";
actions[VS::SHADER_SPATIAL].renames["OUT_VERTEX"] = "gl_Position";
actions[VS::SHADER_SPATIAL].renames["OUT_NORMAL"] = "normal_interp";
actions[VS::SHADER_SPATIAL].renames["OUT_COLOR"] = "color_interp";
actions[VS::SHADER_SPATIAL].renames["OUT_UV"] = "uv_interp";
actions[VS::SHADER_SPATIAL].renames["OUT_UV2"] = "uv2_interp";
actions[VS::SHADER_SPATIAL].renames["OUT_TANGENT"] = "tangent_interp";
actions[VS::SHADER_SPATIAL].renames["OUT_BINORMAL"] = "binormal_interp";

//builtins

actions[VS::SHADER_SPATIAL].renames["TIME"] = "time";
Expand Down Expand Up @@ -888,7 +953,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light";

actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["OUT_TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT";
actions[VS::SHADER_SPATIAL].usage_defines["OUT_BINORMAL"] = "@TANGENT";
actions[VS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n";
actions[VS::SHADER_SPATIAL].usage_defines["RIM_TINT"] = "@RIM";
actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n";
Expand All @@ -898,10 +965,13 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n";
actions[VS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n";
actions[VS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["OUT_UV"] = "#define ENABLE_UV_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["OUT_UV2"] = "#define ENABLE_UV2_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n";
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["OUT_COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n";
actions[VS::SHADER_SPATIAL].usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
Expand All @@ -920,6 +990,15 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";

actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_max_vertices"] = "#define GEOMETRY_MAX_VERTICES ";
actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_in_points"] = "#define GEOMETRY_IN_MODE 0\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_in_lines"] = "#define GEOMETRY_IN_MODE 1\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_in_triangles"] = "#define GEOMETRY_IN_MODE 2\n";

actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_out_points"] = "#define GEOMETRY_OUT_MODE 0\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_out_lines"] = "#define GEOMETRY_OUT_MODE 1\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_out_triangles"] = "#define GEOMETRY_OUT_MODE 2\n";

bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley");

if (!force_lambert) {
Expand Down Expand Up @@ -969,6 +1048,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {

vertex_name = "vertex";
fragment_name = "fragment";
geometry_name = "geometry";
light_name = "light";
time_name = "TIME";

Expand Down
6 changes: 6 additions & 0 deletions drivers/gles3/shader_compiler_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ShaderCompilerGLES3 {
struct IdentifierActions {

Map<StringName, Pair<int *, int> > render_mode_values;
Map<StringName, int *> render_mode_ranges;
Map<StringName, bool *> render_mode_flags;
Map<StringName, bool *> usage_flag_pointers;
Map<StringName, bool *> write_flag_pointers;
Expand All @@ -60,11 +61,14 @@ class ShaderCompilerGLES3 {
String uniforms;
String vertex_global;
String vertex;
String geometry_global;
String geometry;
String fragment_global;
String fragment;
String light;

bool uses_fragment_time;
bool uses_geometry_time;
bool uses_vertex_time;
};

Expand All @@ -84,13 +88,15 @@ class ShaderCompilerGLES3 {
StringName current_func_name;
StringName vertex_name;
StringName fragment_name;
StringName geometry_name;
StringName light_name;
StringName time_name;

Set<StringName> used_name_defines;
Set<StringName> used_flag_pointers;
Set<StringName> used_rmode_defines;
Set<StringName> internal_functions;
Set<StringName> varyings;

DefaultIdentifierActions actions[VS::SHADER_MAX];

Expand Down
Loading