Prevent item joining with custom shaders using selected BUILTINs
Large FVF allows batching of many custom shaders, but should not join items which have shaders that utilize BUILTINs which would change for each item, because these will not be sent individually, and all joined items would wrongly use the values from the first joined item.
This commit is contained in:
parent
3a8e1f324f
commit
1394df3188
7 changed files with 106 additions and 45 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue