Fix read from screen and depth texture

This commit is contained in:
Bastiaan Olij 2021-08-11 21:00:12 +10:00
parent 8781c9536e
commit 4002650cb9
6 changed files with 158 additions and 2 deletions

View file

@ -739,6 +739,26 @@ void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const S
RD::get_singleton()->compute_list_end();
}
void EffectsRD::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size) {
ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of mipmap with the clustered renderer.");
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
BlurRasterMode mode = BLUR_MIPMAP;
blur_raster.push_constant.pixel_size[0] = 1.0 / float(p_size.x);
blur_raster.push_constant.pixel_size[1] = 1.0 / float(p_size.y);
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
RD::get_singleton()->draw_list_end();
}
void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip) {
CopyToDPPushConstant push_constant;
push_constant.screen_rect[0] = p_rect.position.x;
@ -1873,6 +1893,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
// init blur shader (on compute use copy shader)
Vector<String> blur_modes;
blur_modes.push_back("\n#define MODE_MIPMAP\n"); // BLUR_MIPMAP
blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); // BLUR_MODE_GAUSSIAN_BLUR
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); // BLUR_MODE_GAUSSIAN_GLOW
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); // BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE

View file

@ -70,6 +70,8 @@ private:
bool prefer_raster_effects;
enum BlurRasterMode {
BLUR_MIPMAP,
BLUR_MODE_GAUSSIAN_BLUR,
BLUR_MODE_GAUSSIAN_GLOW,
BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE,
@ -767,6 +769,7 @@ public:
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size);
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip);
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);

View file

@ -1533,6 +1533,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
}
if (scene_state.used_screen_texture) {
// Copy screen texture to backbuffer so we can read from it
_render_buffers_copy_screen_texture(p_render_data);
}
if (scene_state.used_depth_texture) {
// Copy depth texture to backbuffer so we can read from it
_render_buffers_copy_depth_texture(p_render_data);
}
RENDER_TIMESTAMP("Render Transparent Pass");
RD::get_singleton()->draw_command_begin_label("Render Transparent Pass");
@ -2219,7 +2229,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 9;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID();
RID texture = (dbt.is_valid()) ? dbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
uniforms.push_back(u);
}

View file

@ -414,7 +414,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
RD::Uniform u;
u.binding = 9;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID();
RID texture = (dbt.is_valid()) ? dbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
uniforms.push_back(u);
}
@ -752,6 +753,16 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass
}
if (scene_state.used_screen_texture) {
// Copy screen texture to backbuffer so we can read from it
_render_buffers_copy_screen_texture(p_render_data);
}
if (scene_state.used_depth_texture) {
// Copy depth texture to backbuffer so we can read from it
_render_buffers_copy_depth_texture(p_render_data);
}
// transparent pass
RD::get_singleton()->draw_command_begin_label("Render Transparent Subpass");

View file

@ -1513,6 +1513,38 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) {
}
}
void RendererSceneRenderRD::_allocate_depth_backbuffer_textures(RenderBuffers *rb) {
ERR_FAIL_COND(!rb->depth_back_texture.is_null());
{
RD::TextureFormat tf;
if (rb->view_count > 1) {
tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
}
// We're not using this as a depth stencil, just copying our data into this. May need to look into using a different format on mobile, maybe R16?
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
tf.width = rb->width;
tf.height = rb->height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
tf.array_layers = rb->view_count; // create a layer for every view
tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; // set this as color attachment because we're copying data into it, it's not actually used as a depth buffer
rb->depth_back_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
}
if (!_render_buffers_can_be_storage()) {
// create framebuffer so we can write into this...
Vector<RID> fb;
fb.push_back(rb->depth_back_texture);
rb->depth_back_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, rb->view_count);
}
}
void RendererSceneRenderRD::_allocate_luminance_textures(RenderBuffers *rb) {
ERR_FAIL_COND(!rb->luminance.current.is_null());
@ -1579,6 +1611,16 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->depth_texture = RID();
}
if (rb->depth_back_fb.is_valid()) {
RD::get_singleton()->free(rb->depth_back_fb);
rb->depth_back_fb = RID();
}
if (rb->depth_back_texture.is_valid()) {
RD::get_singleton()->free(rb->depth_back_texture);
rb->depth_back_texture = RID();
}
for (int i = 0; i < 2; i++) {
for (int m = 0; m < rb->blur[i].mipmaps.size(); m++) {
// do we free the texture slice here? or is it enough to free the main texture?
@ -1879,6 +1921,58 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ssao.downsample_uniform_set, rb->ssao.gather_uniform_set, rb->ssao.importance_map_uniform_set);
}
void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
ERR_FAIL_COND(!rb);
RD::get_singleton()->draw_command_begin_label("Copy screen texture");
if (rb->blur[0].texture.is_null()) {
_allocate_blur_textures(rb);
}
// @TODO IMPLEMENT MULTIVIEW, all effects need to support stereo buffers or effects are only applied to the left eye
bool can_use_storage = _render_buffers_can_be_storage();
if (can_use_storage) {
storage->get_effects()->copy_to_rect(rb->texture, rb->blur[0].mipmaps[0].texture, Rect2i(0, 0, rb->width, rb->height));
for (int i = 1; i < rb->blur[0].mipmaps.size(); i++) {
storage->get_effects()->make_mipmap(rb->blur[0].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i].texture, Size2i(rb->blur[0].mipmaps[i].width, rb->blur[0].mipmaps[i].height));
}
} else {
storage->get_effects()->copy_to_fb_rect(rb->texture, rb->blur[0].mipmaps[0].fb, Rect2i(0, 0, rb->width, rb->height));
for (int i = 1; i < rb->blur[0].mipmaps.size(); i++) {
storage->get_effects()->make_mipmap_raster(rb->blur[0].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i].fb, Size2i(rb->blur[0].mipmaps[i].width, rb->blur[0].mipmaps[i].height));
}
}
RD::get_singleton()->draw_command_end_label();
}
void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
ERR_FAIL_COND(!rb);
RD::get_singleton()->draw_command_begin_label("Copy depth texture");
if (rb->depth_back_texture.is_null()) {
_allocate_depth_backbuffer_textures(rb);
}
// @TODO IMPLEMENT MULTIVIEW, all effects need to support stereo buffers or effects are only applied to the left eye
bool can_use_storage = _render_buffers_can_be_storage();
if (can_use_storage) {
storage->get_effects()->copy_to_rect(rb->depth_texture, rb->depth_back_texture, Rect2i(0, 0, rb->width, rb->height));
} else {
storage->get_effects()->copy_to_fb_rect(rb->depth_texture, rb->depth_back_fb, Rect2i(0, 0, rb->width, rb->height));
}
RD::get_singleton()->draw_command_end_label();
}
void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
ERR_FAIL_COND(!rb);
@ -2227,6 +2321,15 @@ RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_b
return rb->blur[0].texture;
}
RID RendererSceneRenderRD::render_buffers_get_back_depth_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
if (!rb->depth_back_texture.is_valid()) {
return RID(); //not valid at the moment
}
return rb->depth_back_texture;
}
RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());

View file

@ -134,6 +134,8 @@ protected:
void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer);
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
void _post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data);
void _disable_clear_request(const RenderDataRD *p_render_data);
@ -492,6 +494,9 @@ private:
WeightBuffers weight_buffers[4]; // Only used in raster
RID base_weight_fb; // base buffer for weight
RID depth_back_texture;
RID depth_back_fb; // only used on mobile
struct Luminance {
Vector<RID> reduce;
RID current;
@ -535,6 +540,7 @@ private:
void _free_render_buffer_data(RenderBuffers *rb);
void _allocate_blur_textures(RenderBuffers *rb);
void _allocate_depth_backbuffer_textures(RenderBuffers *rb);
void _allocate_luminance_textures(RenderBuffers *rb);
void _render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer);
@ -1183,6 +1189,7 @@ public:
RID render_buffers_get_ao_texture(RID p_render_buffers);
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
RID render_buffers_get_back_depth_texture(RID p_render_buffers);
RID render_buffers_get_voxel_gi_buffer(RID p_render_buffers);
RID render_buffers_get_default_voxel_gi_buffer();
RID render_buffers_get_gi_ambient_texture(RID p_render_buffers);