|
@@ -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) {
|
|
void RendererSceneRenderRD::_allocate_luminance_textures(RenderBuffers *rb) {
|
|
ERR_FAIL_COND(!rb->luminance.current.is_null());
|
|
ERR_FAIL_COND(!rb->luminance.current.is_null());
|
|
|
|
|
|
@@ -1579,6 +1611,16 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
|
|
rb->depth_texture = RID();
|
|
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 i = 0; i < 2; i++) {
|
|
for (int m = 0; m < rb->blur[i].mipmaps.size(); m++) {
|
|
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?
|
|
// 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);
|
|
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) {
|
|
void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) {
|
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
|
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
|
|
ERR_FAIL_COND(!rb);
|
|
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;
|
|
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) {
|
|
RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) {
|
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
|
ERR_FAIL_COND_V(!rb, RID());
|
|
ERR_FAIL_COND_V(!rb, RID());
|