Skip to content

Commit

Permalink
Merge pull request #27317 from aqnuep/depth_texture_fix
Browse files Browse the repository at this point in the history
Fixed handling of depth texture so it's resolved and bound when needed
  • Loading branch information
akien-mga committed Apr 1, 2019
2 parents 39c8681 + 849596c commit 658aaa5
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 27 deletions.
85 changes: 63 additions & 22 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Expand Up @@ -2349,6 +2349,10 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
state.used_screen_texture = true;
}

if (p_material->shader->spatial.uses_depth_texture) {
state.used_depth_texture = true;
}

if (p_depth_pass) {

if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test)
Expand Down Expand Up @@ -3165,6 +3169,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
current_material_index = 0;
state.used_sss = false;
state.used_screen_texture = false;
state.used_depth_texture = false;

//fill list

Expand Down Expand Up @@ -3281,22 +3286,37 @@ void RasterizerSceneGLES3::_blur_effect_buffer() {
}
}

void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_cam_projection) {

glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);

if (!state.used_depth_prepass_and_resolved) {
void RasterizerSceneGLES3::_prepare_depth_texture() {
if (!state.prepared_depth_texture) {
//resolve depth buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
state.prepared_depth_texture = true;
}
}

void RasterizerSceneGLES3::_bind_depth_texture() {
if (!state.bound_depth_texture) {
ERR_FAIL_COND(!state.prepared_depth_texture)
//bind depth for read
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 8);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
state.bound_depth_texture = true;
}
}

void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_cam_projection) {

glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);

_prepare_depth_texture();

if (env->ssao_enabled || env->ssr_enabled) {

Expand Down Expand Up @@ -4149,7 +4169,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glDepthFunc(GL_LEQUAL);

state.used_contact_shadows = false;
state.used_depth_prepass_and_resolved = false;
state.prepared_depth_texture = false;
state.bound_depth_texture = false;

for (int i = 0; i < p_light_cull_count; i++) {

Expand All @@ -4161,7 +4182,17 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
}
}

if (!storage->config.no_depth_prepass && storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS]) { //detect with state.used_contact_shadows too
// Do depth prepass if it's explicitly enabled
bool use_depth_prepass = storage->config.use_depth_prepass;

// If contact shadows are used then we need to do depth prepass even if it's otherwise disabled
use_depth_prepass = use_depth_prepass || state.used_contact_shadows;

// Never do depth prepass if effects are disabled or if we render overdraws
use_depth_prepass = use_depth_prepass && storage->frame.current_rt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS];
use_depth_prepass = use_depth_prepass && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW;

if (use_depth_prepass) {
//pre z pass

glDisable(GL_BLEND);
Expand All @@ -4188,16 +4219,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const

if (state.used_contact_shadows) {

glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//bind depth for read
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 8);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
state.used_depth_prepass_and_resolved = true;
_prepare_depth_texture();
_bind_depth_texture();
}

fb_cleared = true;
Expand Down Expand Up @@ -4455,7 +4478,12 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const

_render_mrts(env, p_cam_projection);
} else {
//FIXME: check that this is possible to use
// Here we have to do the blits/resolves that otherwise are done in the MRT rendering, in particular
// - prepare screen texture for any geometry that uses a shader with screen texture
// - prepare depth texture for any geometry that uses a shader with depth texture

bool framebuffer_dirty = false;

if (storage->frame.current_rt && storage->frame.current_rt->buffers.active && state.used_screen_texture) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
Expand All @@ -4464,12 +4492,25 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
_blur_effect_buffer();
//restored framebuffer
framebuffer_dirty = true;
}

if (storage->frame.current_rt && storage->frame.current_rt->buffers.active && state.used_depth_texture) {
_prepare_depth_texture();
framebuffer_dirty = true;
}

if (framebuffer_dirty) {
// Restore framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
}
}

if (storage->frame.current_rt && state.used_depth_texture && storage->frame.current_rt->buffers.active) {
_bind_depth_texture();
}

if (storage->frame.current_rt && state.used_screen_texture && storage->frame.current_rt->buffers.active) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
Expand Down
8 changes: 7 additions & 1 deletion drivers/gles3/rasterizer_scene_gles3.h
Expand Up @@ -206,7 +206,10 @@ class RasterizerSceneGLES3 : public RasterizerScene {
bool used_screen_texture;

bool used_depth_prepass;
bool used_depth_prepass_and_resolved;

bool used_depth_texture;
bool prepared_depth_texture;
bool bound_depth_texture;

VS::ViewportDebugDraw debug_draw;
} state;
Expand Down Expand Up @@ -848,6 +851,9 @@ class RasterizerSceneGLES3 : public RasterizerScene {
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
void _post_process(Environment *env, const CameraMatrix &p_cam_projection);

void _prepare_depth_texture();
void _bind_depth_texture();

virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
virtual bool free(RID p_rid);
Expand Down
6 changes: 3 additions & 3 deletions drivers/gles3/rasterizer_storage_gles3.cpp
Expand Up @@ -8042,8 +8042,8 @@ void RasterizerStorageGLES3::initialize() {

String renderer = (const char *)glGetString(GL_RENDERER);

config.no_depth_prepass = !bool(GLOBAL_GET("rendering/quality/depth_prepass/enable"));
if (!config.no_depth_prepass) {
config.use_depth_prepass = bool(GLOBAL_GET("rendering/quality/depth_prepass/enable"));
if (config.use_depth_prepass) {

String vendors = GLOBAL_GET("rendering/quality/depth_prepass/disable_for_vendors");
Vector<String> vendor_match = vendors.split(",");
Expand All @@ -8053,7 +8053,7 @@ void RasterizerStorageGLES3::initialize() {
continue;

if (renderer.findn(v) != -1) {
config.no_depth_prepass = true;
config.use_depth_prepass = false;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gles3/rasterizer_storage_gles3.h
Expand Up @@ -103,7 +103,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage {

bool keep_original_textures;

bool no_depth_prepass;
bool use_depth_prepass;
bool force_vertex_shading;
} config;

Expand Down

0 comments on commit 658aaa5

Please sign in to comment.