Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_antialiasing.c14
-rw-r--r--source/blender/gpu/GPU_texture.h2
-rw-r--r--source/blender/gpu/intern/gpu_texture.c67
3 files changed, 78 insertions, 5 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
index 5c960acbd78..a7ddd1c547b 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
@@ -417,8 +417,10 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
{
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_TextureList *txl = vedata->txl;
WORKBENCH_PassList *psl = vedata->psl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
if (wpd->taa_sample_len == 0) {
/* AA disabled. */
@@ -438,12 +440,14 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
const bool taa_finished = wpd->taa_sample >= wpd->taa_sample_len;
if (wpd->taa_sample == 0) {
wpd->valid_history = true;
+ GPU_texture_copy(txl->history_buffer_tx, dtxl->color);
/* In playback mode, we are sure the next redraw will not use the same viewmatrix.
* In this case no need to save the depth buffer. */
- eGPUFrameBufferBits bits = GPU_COLOR_BIT | (!wpd->is_playback ? GPU_DEPTH_BIT : 0);
- GPU_framebuffer_blit(dfbl->default_fb, 0, fbl->antialiasing_fb, 0, bits);
+ if (!wpd->is_playback) {
+ GPU_texture_copy(txl->depth_buffer_tx, dtxl->depth);
+ }
if (workbench_in_front_history_needed(vedata)) {
- GPU_framebuffer_blit(dfbl->in_front_fb, 0, fbl->antialiasing_in_front_fb, 0, GPU_DEPTH_BIT);
+ GPU_texture_copy(txl->depth_buffer_in_front_tx, dtxl->depth_in_front);
}
}
else {
@@ -453,9 +457,9 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
DRW_draw_pass(psl->aa_accum_ps);
}
/* Copy back the saved depth buffer for correct overlays. */
- GPU_framebuffer_blit(fbl->antialiasing_fb, 0, dfbl->default_fb, 0, GPU_DEPTH_BIT);
+ GPU_texture_copy(dtxl->depth, txl->depth_buffer_tx);
if (workbench_in_front_history_needed(vedata)) {
- GPU_framebuffer_blit(fbl->antialiasing_in_front_fb, 0, dfbl->in_front_fb, 0, GPU_DEPTH_BIT);
+ GPU_texture_copy(dtxl->depth_in_front, txl->depth_buffer_in_front_tx);
}
}
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 892452a2738..d6e5866ae28 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -239,6 +239,8 @@ void GPU_texture_bind(GPUTexture *tex, int number);
void GPU_texture_unbind(GPUTexture *tex);
int GPU_texture_bound_number(GPUTexture *tex);
+void GPU_texture_copy(GPUTexture *dst, GPUTexture *src);
+
void GPU_texture_generate_mipmap(GPUTexture *tex);
void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare);
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter);
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 6d2d0f09a42..69ede4a9e13 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -88,6 +88,9 @@ struct GPUTexture {
int fb_attachment[GPU_TEX_MAX_FBO_ATTACHED];
GPUFrameBuffer *fb[GPU_TEX_MAX_FBO_ATTACHED];
+ /* Legacy workaround for texture copy. */
+ GLuint copy_fb;
+ GPUContext *copy_fb_ctx;
};
static uint gpu_get_bytesize(eGPUTextureFormat data_type);
@@ -1719,6 +1722,67 @@ void GPU_texture_generate_mipmap(GPUTexture *tex)
gpu_texture_memory_footprint_add(tex);
}
+/* Copy a texture content to a similar texture. Only Mip 0 is copied. */
+void GPU_texture_copy(GPUTexture *dst, GPUTexture *src)
+{
+ BLI_assert(dst->target == src->target);
+ BLI_assert(dst->w == src->w);
+ BLI_assert(dst->h == src->h);
+ BLI_assert(!GPU_texture_cube(src) && !GPU_texture_cube(dst));
+ /* TODO support array / 3D textures. */
+ BLI_assert(dst->d == 0);
+ BLI_assert(dst->format == src->format);
+
+ if (GLEW_ARB_copy_image) {
+ /* Opengl 4.3 */
+ glCopyImageSubData(src->bindcode,
+ src->target,
+ 0,
+ 0,
+ 0,
+ 0,
+ dst->bindcode,
+ dst->target,
+ 0,
+ 0,
+ 0,
+ 0,
+ src->w,
+ src->h,
+ 1);
+ }
+ else {
+ /* Fallback for older GL. */
+ GLenum attachment = !GPU_texture_depth(src) ?
+ GL_COLOR_ATTACHMENT0 :
+ (GPU_texture_stencil(src) ? GL_DEPTH_STENCIL_ATTACHMENT :
+ GL_DEPTH_ATTACHMENT);
+
+ if (src->copy_fb == 0) {
+ src->copy_fb = GPU_fbo_alloc();
+ src->copy_fb_ctx = GPU_context_active_get();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, src->copy_fb);
+ glFramebufferTexture(GL_READ_FRAMEBUFFER, attachment, src->bindcode, 0);
+
+ BLI_assert(glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+ }
+ /* This means that this function can only be used in one context for each texture. */
+ BLI_assert(src->copy_fb_ctx == GPU_context_active_get());
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, src->copy_fb);
+ glReadBuffer(attachment);
+
+ /* WATCH: glCopyTexSubImage2D might clamp the values to the [0,1] range
+ * where glCopyImageSubData would not. */
+ glBindTexture(dst->target, dst->bindcode);
+ glCopyTexSubImage2D(dst->target, 0, 0, 0, 0, 0, src->w, src->h);
+
+ glBindTexture(dst->target, 0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ }
+}
+
void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare)
{
WARN_NOT_BOUND(tex);
@@ -1838,6 +1902,9 @@ void GPU_texture_free(GPUTexture *tex)
if (tex->bindcode) {
GPU_tex_free(tex->bindcode);
}
+ if (tex->copy_fb) {
+ GPU_fbo_free(tex->copy_fb, tex->copy_fb_ctx);
+ }
gpu_texture_memory_footprint_remove(tex);