Skip to content

Commit

Permalink
Unbind texture slots when changing framebuffer
Browse files Browse the repository at this point in the history
Prevent bugs whereby texture still in use.
  • Loading branch information
lawnjelly committed Aug 12, 2023
1 parent 9435c38 commit 5e197fd
Show file tree
Hide file tree
Showing 12 changed files with 322 additions and 240 deletions.
26 changes: 13 additions & 13 deletions drivers/gles2/rasterizer_canvas_base_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void RasterizerCanvasBaseGLES2::canvas_begin() {

reset_canvas();

glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);

glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
Expand Down Expand Up @@ -191,7 +191,7 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasBaseGLES2::_bind_canvas_texture
state.current_tex = RID();
state.current_tex_ptr = nullptr;

glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);

} else {
Expand All @@ -205,7 +205,7 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasBaseGLES2::_bind_canvas_texture
texture->render_target->used_in_frame = true;
}

glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, texture->tex_id);

state.current_tex = p_texture;
Expand All @@ -217,7 +217,7 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasBaseGLES2::_bind_canvas_texture
state.current_tex = RID();
state.current_tex_ptr = nullptr;

glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
}

Expand All @@ -230,7 +230,7 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasBaseGLES2::_bind_canvas_texture

if (!normal_map) {
state.current_normal = RID();
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, false);

Expand All @@ -241,15 +241,15 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasBaseGLES2::_bind_canvas_texture

normal_map = normal_map->get_ptr();

glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
state.current_normal = p_normal_map;
state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, true);
}

} else {
state.current_normal = RID();
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, false);
}
Expand All @@ -272,7 +272,7 @@ void RasterizerCanvasBaseGLES2::draw_window_margins(int *black_margin, RID *blac
draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h),
Rect2(0, 0, (float)black_margin[MARGIN_LEFT] / sz.x, (float)(window_h) / sz.y));
} else if (black_margin[MARGIN_LEFT]) {
glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);

draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h), Rect2(0, 0, 1, 1));
Expand All @@ -284,7 +284,7 @@ void RasterizerCanvasBaseGLES2::draw_window_margins(int *black_margin, RID *blac
draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h),
Rect2(0, 0, (float)black_margin[MARGIN_RIGHT] / sz.x, (float)window_h / sz.y));
} else if (black_margin[MARGIN_RIGHT]) {
glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);

draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h), Rect2(0, 0, 1, 1));
Expand All @@ -298,7 +298,7 @@ void RasterizerCanvasBaseGLES2::draw_window_margins(int *black_margin, RID *blac
Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[MARGIN_TOP] / sz.y));

} else if (black_margin[MARGIN_TOP]) {
glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);

draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[MARGIN_TOP]), Rect2(0, 0, 1, 1));
Expand All @@ -312,7 +312,7 @@ void RasterizerCanvasBaseGLES2::draw_window_margins(int *black_margin, RID *blac
Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[MARGIN_BOTTOM] / sz.y));

} else if (black_margin[MARGIN_BOTTOM]) {
glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);

draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, 1, 1));
Expand Down Expand Up @@ -364,7 +364,7 @@ void RasterizerCanvasBaseGLES2::_set_uniforms() {

if (state.using_shadow) {
RasterizerStorageGLES2::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(light->shadow_buffer);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
glBindTexture(GL_TEXTURE_2D, cls->distance);
state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX, light->shadow_matrix_cache);
state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR, light->shadow_color);
Expand Down Expand Up @@ -723,7 +723,7 @@ void RasterizerCanvasBaseGLES2::_copy_screen(const Rect2 &p_rect) {
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, !state.using_transparent_rt);

glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->copy_screen_effect.fbo);
glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);

storage->shaders.copy.bind();
Expand Down
25 changes: 12 additions & 13 deletions drivers/gles2/rasterizer_canvas_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ void RasterizerCanvasGLES2::canvas_render_items_implementation(Item *p_item_list
state.current_normal = RID();
state.canvas_texscreen_used = false;

glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);

if (bdata.settings_use_batching) {
Expand Down Expand Up @@ -1621,7 +1621,7 @@ void RasterizerCanvasGLES2::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
}

if (skeleton) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
state.using_skeleton = true;
} else {
Expand Down Expand Up @@ -1656,7 +1656,7 @@ void RasterizerCanvasGLES2::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
}

if (storage->frame.current_rt->copy_screen_effect.color) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
}
}
Expand All @@ -1676,7 +1676,7 @@ void RasterizerCanvasGLES2::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw();

for (int i = 0; i < tc; i++) {
glActiveTexture(GL_TEXTURE0 + i);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + i);

RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i].second);

Expand Down Expand Up @@ -1856,7 +1856,7 @@ void RasterizerCanvasGLES2::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
_set_uniforms();
state.canvas_shader.use_material((void *)material_ptr);

glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(light->texture);
if (!t) {
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
Expand All @@ -1866,9 +1866,8 @@ void RasterizerCanvasGLES2::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
glBindTexture(t->target, t->tex_id);
}

glActiveTexture(GL_TEXTURE0);
_legacy_canvas_item_render_commands(p_ci, nullptr, reclip, material_ptr); //redraw using light

WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
_legacy_canvas_item_render_commands(p_ci, nullptr, reclip, material_ptr); //redraw using lights
state.using_light = nullptr;
}

Expand Down Expand Up @@ -1985,7 +1984,7 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
}

if (skeleton) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
state.using_skeleton = true;
} else {
Expand Down Expand Up @@ -2021,7 +2020,7 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
}

if (storage->frame.current_rt->copy_screen_effect.color) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
}
}
Expand All @@ -2041,7 +2040,7 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw();

for (int i = 0; i < tc; i++) {
glActiveTexture(GL_TEXTURE0 + i);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + i);

RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i].second);

Expand Down Expand Up @@ -2239,7 +2238,7 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
_set_uniforms();
state.canvas_shader.use_material((void *)material_ptr);

glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(light->texture);
if (!t) {
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
Expand All @@ -2249,7 +2248,7 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
glBindTexture(t->target, t->tex_id);
}

glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);

// redraw using light.
// if there is no clip item, we can consider scissoring to the intersection area between the light and the item
Expand Down
9 changes: 6 additions & 3 deletions drivers/gles2/rasterizer_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ void RasterizerGLES2::set_current_render_target(RID p_render_target) {
glViewport(0, 0, OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
}

// Unbind texture slots.
storage->gl_wrapper.reset();
}

void RasterizerGLES2::restore_render_target(bool p_3d_was_drawn) {
Expand Down Expand Up @@ -379,7 +382,7 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c
}

RasterizerStorageGLES2::Texture *t = storage->texture_owner.get(texture);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, t->tex_id);
canvas->draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1));
glBindTexture(GL_TEXTURE_2D, 0);
Expand Down Expand Up @@ -409,7 +412,7 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re
canvas->canvas_begin();
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
if (rt->external.fbo != 0) {
glBindTexture(GL_TEXTURE_2D, rt->external.color);
} else {
Expand Down Expand Up @@ -438,7 +441,7 @@ void RasterizerGLES2::output_lens_distorted_to_screen(RID p_render_target, const
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);

// output our texture
glActiveTexture(GL_TEXTURE0);
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, rt->color);

canvas->draw_lens_distortion_rect(p_screen_rect, p_k1, p_k2, p_eye_center, p_oversample);
Expand Down
Loading

0 comments on commit 5e197fd

Please sign in to comment.