Merge pull request #43690 from lawnjelly/ewok_builtin_prevent_item

Prevent item joining with custom shaders using selected BUILTINs
This commit is contained in:
Rémi Verschelde 2020-11-19 17:02:27 +01:00 committed by GitHub
commit 09f3a21ccc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 106 additions and 45 deletions

View file

@ -1372,33 +1372,42 @@ bool RasterizerCanvasGLES2::try_join_item(Item *p_ci, RenderItemState &r_ris, bo
bdata.joined_item_batch_flags = 0;
if (r_ris.shader_cache) {
unsigned int and_flags = r_ris.shader_cache->canvas_item.batch_flags & (RasterizerStorageCommon::PREVENT_COLOR_BAKING | RasterizerStorageCommon::PREVENT_VERTEX_BAKING);
unsigned int and_flags = r_ris.shader_cache->canvas_item.batch_flags & (RasterizerStorageCommon::PREVENT_COLOR_BAKING | RasterizerStorageCommon::PREVENT_VERTEX_BAKING | RasterizerStorageCommon::PREVENT_ITEM_JOINING);
if (and_flags) {
bool use_larger_fvfs = true;
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
// in some circumstances, if the modulate is identity, we still allow baking because reading modulate / color
// will still be okay to do in the shader with no ill effects
if (r_ris.final_modulate == Color(1, 1, 1, 1)) {
use_larger_fvfs = false;
}
}
// new .. always use large FVF
if (use_larger_fvfs) {
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_MODULATE_FVF;
} else {
// we need to save on the joined item that it should use large fvf.
// This info will then be used in filling and rendering
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_LARGE_FVF;
}
// special case for preventing item joining altogether
if (and_flags & RasterizerStorageCommon::PREVENT_ITEM_JOINING) {
join = false;
//r_batch_break = true; // don't think we need a batch break
// save the flags so that they don't need to be recalculated in the 2nd pass
bdata.joined_item_batch_flags |= r_ris.shader_cache->canvas_item.batch_flags;
}
} else {
/*
bool use_larger_fvfs = true;
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
// in some circumstances, if the modulate is identity, we still allow baking because reading modulate / color
// will still be okay to do in the shader with no ill effects
if (r_ris.final_modulate == Color(1, 1, 1, 1)) {
use_larger_fvfs = false;
}
}
// new .. always use large FVF
if (use_larger_fvfs) {
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_MODULATE_FVF;
} else {
// we need to save on the joined item that it should use large fvf.
// This info will then be used in filling and rendering
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_LARGE_FVF;
}
bdata.joined_item_batch_flags |= r_ris.shader_cache->canvas_item.batch_flags;
}
/*
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
// in some circumstances, if the modulate is identity, we still allow baking because reading modulate / color
// will still be okay to do in the shader with no ill effects
@ -1424,6 +1433,7 @@ bool RasterizerCanvasGLES2::try_join_item(Item *p_ci, RenderItemState &r_ris, bo
bdata.joined_item_batch_flags |= r_ris.shader_cache->canvas_item.batch_flags;
}
*/
} // if not prevent item joining
}
}

View file

@ -1437,6 +1437,11 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
p_shader->canvas_item.uses_vertex = false;
p_shader->canvas_item.batch_flags = 0;
p_shader->canvas_item.uses_world_matrix = false;
p_shader->canvas_item.uses_extra_matrix = false;
p_shader->canvas_item.uses_projection_matrix = false;
p_shader->canvas_item.uses_instance_custom = 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_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB);
@ -1455,6 +1460,11 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex;
shaders.actions_canvas.usage_flag_pointers["WORLD_MATRIX"] = &p_shader->canvas_item.uses_world_matrix;
shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix;
shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix;
shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom;
actions = &shaders.actions_canvas;
actions->uniforms = &p_shader->uniforms;
} break;
@ -1558,6 +1568,9 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
if (p_shader->canvas_item.uses_vertex) {
p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_VERTEX_BAKING;
}
if (p_shader->canvas_item.uses_world_matrix | p_shader->canvas_item.uses_extra_matrix | p_shader->canvas_item.uses_projection_matrix | p_shader->canvas_item.uses_instance_custom) {
p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_ITEM_JOINING;
}
}
p_shader->shader->set_custom_shader(p_shader->custom_code_id);

View file

@ -458,6 +458,12 @@ public:
bool uses_color;
bool uses_vertex;
// all these should disable item joining if used in a custom shader
bool uses_world_matrix;
bool uses_extra_matrix;
bool uses_projection_matrix;
bool uses_instance_custom;
} canvas_item;
struct Spatial {

View file

@ -1770,31 +1770,41 @@ bool RasterizerCanvasGLES3::try_join_item(Item *p_ci, RenderItemState &r_ris, bo
bdata.joined_item_batch_flags = 0;
if (r_ris.shader_cache) {
unsigned int and_flags = r_ris.shader_cache->canvas_item.batch_flags & (RasterizerStorageCommon::PREVENT_COLOR_BAKING | RasterizerStorageCommon::PREVENT_VERTEX_BAKING);
unsigned int and_flags = r_ris.shader_cache->canvas_item.batch_flags & (RasterizerStorageCommon::PREVENT_COLOR_BAKING | RasterizerStorageCommon::PREVENT_VERTEX_BAKING | RasterizerStorageCommon::PREVENT_ITEM_JOINING);
if (and_flags) {
bool use_larger_fvfs = true;
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
// in some circumstances, if the modulate is identity, we still allow baking because reading modulate / color
// will still be okay to do in the shader with no ill effects
if (r_ris.final_modulate == Color(1, 1, 1, 1)) {
use_larger_fvfs = false;
}
}
// new .. always use large FVF
if (use_larger_fvfs) {
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_MODULATE_FVF;
} else {
// we need to save on the joined item that it should use large fvf.
// This info will then be used in filling and rendering
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_LARGE_FVF;
}
// special case for preventing item joining altogether
if (and_flags & RasterizerStorageCommon::PREVENT_ITEM_JOINING) {
join = false;
//r_batch_break = true; // don't think we need a batch break
// save the flags so that they don't need to be recalculated in the 2nd pass
bdata.joined_item_batch_flags |= r_ris.shader_cache->canvas_item.batch_flags;
}
} else {
bool use_larger_fvfs = true;
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
// in some circumstances, if the modulate is identity, we still allow baking because reading modulate / color
// will still be okay to do in the shader with no ill effects
if (r_ris.final_modulate == Color(1, 1, 1, 1)) {
use_larger_fvfs = false;
}
}
// new .. always use large FVF
if (use_larger_fvfs) {
if (and_flags == RasterizerStorageCommon::PREVENT_COLOR_BAKING) {
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_MODULATE_FVF;
} else {
// we need to save on the joined item that it should use large fvf.
// This info will then be used in filling and rendering
bdata.joined_item_batch_flags |= RasterizerStorageCommon::USE_LARGE_FVF;
}
bdata.joined_item_batch_flags |= r_ris.shader_cache->canvas_item.batch_flags;
}
} // if not prevent item joining
}
}

View file

@ -2313,6 +2313,11 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->canvas_item.uses_vertex = false;
p_shader->canvas_item.batch_flags = 0;
p_shader->canvas_item.uses_world_matrix = false;
p_shader->canvas_item.uses_extra_matrix = false;
p_shader->canvas_item.uses_projection_matrix = false;
p_shader->canvas_item.uses_instance_custom = 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_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB);
@ -2332,6 +2337,11 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_canvas.usage_flag_pointers["COLOR"] = &p_shader->canvas_item.uses_color;
shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex;
shaders.actions_canvas.usage_flag_pointers["WORLD_MATRIX"] = &p_shader->canvas_item.uses_world_matrix;
shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix;
shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix;
shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom;
actions = &shaders.actions_canvas;
actions->uniforms = &p_shader->uniforms;
@ -2436,6 +2446,9 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
if (p_shader->canvas_item.uses_vertex) {
p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_VERTEX_BAKING;
}
if (p_shader->canvas_item.uses_world_matrix | p_shader->canvas_item.uses_extra_matrix | p_shader->canvas_item.uses_projection_matrix | p_shader->canvas_item.uses_instance_custom) {
p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_ITEM_JOINING;
}
}
//all materials using this shader will have to be invalidated, unfortunately

View file

@ -473,6 +473,12 @@ public:
bool uses_color;
bool uses_vertex;
// all these should disable item joining if used in a custom shader
bool uses_world_matrix;
bool uses_extra_matrix;
bool uses_projection_matrix;
bool uses_instance_custom;
} canvas_item;
struct Spatial {

View file

@ -48,8 +48,11 @@ public:
PREVENT_COLOR_BAKING = 1 << 0,
PREVENT_VERTEX_BAKING = 1 << 1,
USE_MODULATE_FVF = 1 << 2,
USE_LARGE_FVF = 1 << 3,
// custom vertex shaders using BUILTINS that vary per item
PREVENT_ITEM_JOINING = 1 << 2,
USE_MODULATE_FVF = 1 << 3,
USE_LARGE_FVF = 1 << 4,
};
enum BatchType : uint16_t {