Skip to content

Commit

Permalink
Geometry shader support
Browse files Browse the repository at this point in the history
  • Loading branch information
Chaosus committed Apr 23, 2019
1 parent 8e652a1 commit 1b628eb
Show file tree
Hide file tree
Showing 17 changed files with 814 additions and 84 deletions.
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

0 comments on commit 1b628eb

Please sign in to comment.