GLES2 Batching - Prevent VERTEX baking within items in custom shaders
In addition to prevent item joins when VERTEX reads are present in a custom shader, it is also necessary to prevent baking extra matrices (extra transforms) WITHIN items, because these can also report incorrect results.
This commit is contained in:
parent
d096ce1644
commit
57c70d8e9c
|
@ -60,7 +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;
|
joined_item_batch_flags = 0;
|
||||||
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
|
||||||
|
@ -1629,6 +1629,12 @@ void RasterizerCanvasGLES2::render_joined_item_commands(const BItemJoined &p_bij
|
||||||
fill_state.use_hardware_transform = p_bij.use_hardware_transform();
|
fill_state.use_hardware_transform = p_bij.use_hardware_transform();
|
||||||
fill_state.extra_matrix_sent = false;
|
fill_state.extra_matrix_sent = false;
|
||||||
|
|
||||||
|
// in the special case of custom shaders that read from VERTEX (i.e. vertex position)
|
||||||
|
// we want to disable software transform of extra matrix
|
||||||
|
if (bdata.joined_item_batch_flags & RasterizerStorageGLES2::Shader::CanvasItem::PREVENT_VERTEX_BAKING) {
|
||||||
|
fill_state.extra_matrix_sent = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < p_bij.num_item_refs; i++) {
|
for (unsigned int i = 0; i < p_bij.num_item_refs; i++) {
|
||||||
const BItemRef &ref = bdata.item_refs[p_bij.first_item_ref + i];
|
const BItemRef &ref = bdata.item_refs[p_bij.first_item_ref + i];
|
||||||
item = ref.item;
|
item = ref.item;
|
||||||
|
@ -1688,7 +1694,7 @@ void RasterizerCanvasGLES2::flush_render_batches(Item *p_first_item, Item *p_cur
|
||||||
// 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)
|
||||||
// and we haven't decided to prevent color baking (due to e.g. MODULATE
|
// and we haven't decided to prevent color baking (due to e.g. MODULATE
|
||||||
// being used in a shader)
|
// being used in a shader)
|
||||||
if (bdata.total_quads && !bdata.prevent_color_baking) {
|
if (bdata.total_quads && !(bdata.joined_item_batch_flags & RasterizerStorageGLES2::Shader::CanvasItem::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;
|
||||||
|
@ -2998,12 +3004,10 @@ 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?
|
// does the shader contain BUILTINs which break the batching and should prevent color baking or vertex baking?
|
||||||
bdata.prevent_color_baking = false;
|
bdata.joined_item_batch_flags = 0;
|
||||||
if (r_ris.shader_cache && !unshaded) {
|
if (r_ris.shader_cache && !unshaded) {
|
||||||
if (r_ris.shader_cache->canvas_item.batch_flags & RasterizerStorageGLES2::Shader::CanvasItem::PREVENT_COLOR_BAKING) {
|
bdata.joined_item_batch_flags = r_ris.shader_cache->canvas_item.batch_flags;
|
||||||
bdata.prevent_color_baking = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_ris.last_blend_mode != blend_mode) {
|
if (r_ris.last_blend_mode != blend_mode) {
|
||||||
|
|
|
@ -200,9 +200,12 @@ 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
|
// if the shader is using MODULATE, we prevent baking color so the final_modulate can
|
||||||
// be read in the shader
|
// be read in the shader.
|
||||||
bool prevent_color_baking;
|
// if the shader is reading VERTEX, we prevent baking vertex positions with extra matrices etc
|
||||||
|
// to prevent the read position being incorrect.
|
||||||
|
// These flags are defined in RasterizerStorageGLES2::Shader::CanvasItem::BatchFlags
|
||||||
|
unsigned int joined_item_batch_flags;
|
||||||
|
|
||||||
// measured in pixels, recalculated each frame
|
// measured in pixels, recalculated each frame
|
||||||
float scissor_threshold_area;
|
float scissor_threshold_area;
|
||||||
|
|
Loading…
Reference in New Issue