Merge pull request #38450 from lawnjelly/shaper_modulate
GLES2 batching - prevent color baking with MODULATE or COLOR
This commit is contained in:
commit
41b836cb3d
|
@ -60,6 +60,7 @@ RasterizerCanvasGLES2::BatchData::BatchData() {
|
||||||
settings_colored_vertex_format_threshold = 0.0f;
|
settings_colored_vertex_format_threshold = 0.0f;
|
||||||
settings_batch_buffer_num_verts = 0;
|
settings_batch_buffer_num_verts = 0;
|
||||||
scissor_threshold_area = 0.0f;
|
scissor_threshold_area = 0.0f;
|
||||||
|
prevent_color_baking = false;
|
||||||
diagnose_frame = false;
|
diagnose_frame = false;
|
||||||
next_diagnose_tick = 10000;
|
next_diagnose_tick = 10000;
|
||||||
diagnose_frame_number = 9999999999; // some high number
|
diagnose_frame_number = 9999999999; // some high number
|
||||||
|
@ -1687,7 +1688,9 @@ void RasterizerCanvasGLES2::flush_render_batches(Item *p_first_item, Item *p_cur
|
||||||
bdata.use_colored_vertices = false;
|
bdata.use_colored_vertices = false;
|
||||||
|
|
||||||
// only check whether to convert if there are quads (prevent divide by zero)
|
// only check whether to convert if there are quads (prevent divide by zero)
|
||||||
if (bdata.total_quads) {
|
// and we haven't decided to prevent color baking (due to e.g. MODULATE
|
||||||
|
// being used in a shader)
|
||||||
|
if (bdata.total_quads && !bdata.prevent_color_baking) {
|
||||||
// minus 1 to prevent single primitives (ratio 1.0) always being converted to colored..
|
// minus 1 to prevent single primitives (ratio 1.0) always being converted to colored..
|
||||||
// in that case it is slightly cheaper to just have the color as part of the batch
|
// in that case it is slightly cheaper to just have the color as part of the batch
|
||||||
float ratio = (float)(bdata.total_color_changes - 1) / (float)bdata.total_quads;
|
float ratio = (float)(bdata.total_color_changes - 1) / (float)bdata.total_quads;
|
||||||
|
@ -2252,6 +2255,16 @@ bool RasterizerCanvasGLES2::try_join_item(Item *p_ci, RenderItemState &r_ris, bo
|
||||||
bool unshaded = r_ris.shader_cache && (r_ris.shader_cache->canvas_item.light_mode == RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA));
|
bool unshaded = r_ris.shader_cache && (r_ris.shader_cache->canvas_item.light_mode == RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA));
|
||||||
bool reclip = false;
|
bool reclip = false;
|
||||||
|
|
||||||
|
// does the shader contain BUILTINs which should break the batching?
|
||||||
|
if (r_ris.shader_cache && !unshaded) {
|
||||||
|
if (r_ris.shader_cache->canvas_item.prevent_color_baking) {
|
||||||
|
// we will do this same test on the shader during the rendering pass in order to set a bool not to bake vertex colors
|
||||||
|
// instead of saving this info as it is cheap to calculate
|
||||||
|
join = false;
|
||||||
|
r_batch_break = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we are precalculating the final_modulate ahead of time because we need this for baking of final modulate into vertex colors
|
// we are precalculating the final_modulate ahead of time because we need this for baking of final modulate into vertex colors
|
||||||
// (only in software transform mode)
|
// (only in software transform mode)
|
||||||
// This maybe inefficient storing it...
|
// This maybe inefficient storing it...
|
||||||
|
@ -2974,6 +2987,14 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
|
||||||
bool unshaded = r_ris.shader_cache && (r_ris.shader_cache->canvas_item.light_mode == RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA));
|
bool unshaded = r_ris.shader_cache && (r_ris.shader_cache->canvas_item.light_mode == RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA));
|
||||||
bool reclip = false;
|
bool reclip = false;
|
||||||
|
|
||||||
|
// does the shader contain BUILTINs which break the batching and should prevent color baking?
|
||||||
|
bdata.prevent_color_baking = false;
|
||||||
|
if (r_ris.shader_cache && !unshaded) {
|
||||||
|
if (r_ris.shader_cache->canvas_item.prevent_color_baking) {
|
||||||
|
bdata.prevent_color_baking = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (r_ris.last_blend_mode != blend_mode) {
|
if (r_ris.last_blend_mode != blend_mode) {
|
||||||
|
|
||||||
switch (blend_mode) {
|
switch (blend_mode) {
|
||||||
|
|
|
@ -200,6 +200,10 @@ class RasterizerCanvasGLES2 : public RasterizerCanvasBaseGLES2 {
|
||||||
// to alternate batching method and add color to the vertex format.
|
// to alternate batching method and add color to the vertex format.
|
||||||
int total_color_changes;
|
int total_color_changes;
|
||||||
|
|
||||||
|
// if the shader is using MODULATE, we prevent baking so the final_modulate can
|
||||||
|
// be read in the shader
|
||||||
|
bool prevent_color_baking;
|
||||||
|
|
||||||
// measured in pixels, recalculated each frame
|
// measured in pixels, recalculated each frame
|
||||||
float scissor_threshold_area;
|
float scissor_threshold_area;
|
||||||
|
|
||||||
|
|
|
@ -1424,6 +1424,9 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
|
||||||
p_shader->canvas_item.uses_screen_texture = false;
|
p_shader->canvas_item.uses_screen_texture = false;
|
||||||
p_shader->canvas_item.uses_screen_uv = false;
|
p_shader->canvas_item.uses_screen_uv = false;
|
||||||
p_shader->canvas_item.uses_time = false;
|
p_shader->canvas_item.uses_time = false;
|
||||||
|
p_shader->canvas_item.uses_modulate = false;
|
||||||
|
p_shader->canvas_item.reads_color = false;
|
||||||
|
p_shader->canvas_item.prevent_color_baking = false;
|
||||||
|
|
||||||
shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
|
shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
|
||||||
shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
|
shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
|
||||||
|
@ -1438,6 +1441,9 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
|
||||||
shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
|
shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
|
||||||
shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
|
shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
|
||||||
shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time;
|
shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time;
|
||||||
|
shaders.actions_canvas.usage_flag_pointers["MODULATE"] = &p_shader->canvas_item.uses_modulate;
|
||||||
|
|
||||||
|
shaders.actions_canvas.read_flag_pointers["COLOR"] = &p_shader->canvas_item.reads_color;
|
||||||
|
|
||||||
actions = &shaders.actions_canvas;
|
actions = &shaders.actions_canvas;
|
||||||
actions->uniforms = &p_shader->uniforms;
|
actions->uniforms = &p_shader->uniforms;
|
||||||
|
@ -1525,6 +1531,11 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
|
||||||
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
|
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
|
||||||
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
|
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
|
||||||
|
|
||||||
|
// some logic for batching
|
||||||
|
if (p_shader->mode == VS::SHADER_CANVAS_ITEM) {
|
||||||
|
p_shader->canvas_item.prevent_color_baking = p_shader->canvas_item.uses_modulate | p_shader->canvas_item.reads_color;
|
||||||
|
}
|
||||||
|
|
||||||
p_shader->shader->set_custom_shader(p_shader->custom_code_id);
|
p_shader->shader->set_custom_shader(p_shader->custom_code_id);
|
||||||
p_shader->shader->bind();
|
p_shader->shader->bind();
|
||||||
|
|
||||||
|
|
|
@ -450,6 +450,13 @@ public:
|
||||||
bool uses_screen_texture;
|
bool uses_screen_texture;
|
||||||
bool uses_screen_uv;
|
bool uses_screen_uv;
|
||||||
bool uses_time;
|
bool uses_time;
|
||||||
|
bool uses_modulate;
|
||||||
|
bool reads_color;
|
||||||
|
|
||||||
|
// this flag is specifically for batching
|
||||||
|
// some of the logic is thus in rasterizer_storage.cpp
|
||||||
|
// we could alternatively set some bitflags here and test on the fly
|
||||||
|
bool prevent_color_baking;
|
||||||
|
|
||||||
} canvas_item;
|
} canvas_item;
|
||||||
|
|
||||||
|
|
|
@ -486,6 +486,10 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
*p_actions.write_flag_pointers[var_node->name] = true;
|
*p_actions.write_flag_pointers[var_node->name] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!p_assigning && p_actions.read_flag_pointers.has(var_node->name)) {
|
||||||
|
*p_actions.read_flag_pointers[var_node->name] = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) {
|
if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) {
|
||||||
String define = p_default_actions.usage_defines[var_node->name];
|
String define = p_default_actions.usage_defines[var_node->name];
|
||||||
String node_name = define.substr(1, define.length());
|
String node_name = define.substr(1, define.length());
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
Map<StringName, Pair<int *, int> > render_mode_values;
|
Map<StringName, Pair<int *, int> > render_mode_values;
|
||||||
Map<StringName, bool *> render_mode_flags;
|
Map<StringName, bool *> render_mode_flags;
|
||||||
Map<StringName, bool *> usage_flag_pointers;
|
Map<StringName, bool *> usage_flag_pointers;
|
||||||
|
Map<StringName, bool *> read_flag_pointers;
|
||||||
Map<StringName, bool *> write_flag_pointers;
|
Map<StringName, bool *> write_flag_pointers;
|
||||||
|
|
||||||
Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms;
|
Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms;
|
||||||
|
|
Loading…
Reference in New Issue