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:
authormano-wii <germano.costa@ig.com.br>2018-12-06 01:59:22 +0300
committermano-wii <germano.costa@ig.com.br>2018-12-06 02:00:08 +0300
commitc0a71b8369a19cba05765af828ba014e67d05bc5 (patch)
treebe55678abba25183b245e9b6631c050f238fca89 /source/blender/gpu/intern
parent75b739c969ce851495ce28a7f92decc8c24de733 (diff)
Fix problem with unused color slot in framebuffer on some bugged AMD GPUs
Differential Revision: https://developer.blender.org/D4035
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index f92899f91a0..d5762700b0f 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -416,6 +416,64 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb)
glDrawBuffer(GL_NONE);
}
+/**
+ * Hack to solve the problem of some bugged AMD GPUs (see `GPU_unused_fb_slot_workaround`).
+ * If there is an empty color slot between the color slots,
+ * all textures after this slot are apparently skipped/discarded.
+ **/
+static void gpu_framebuffer_update_attachments_and_fill_empty_slots(GPUFrameBuffer *fb)
+{
+ GLenum gl_attachments[GPU_FB_MAX_COLOR_ATTACHMENT];
+ bool fill_empty_slot = false;
+ int dummy_tex = 0;
+
+ BLI_assert(GPU_framebuffer_active_get() == fb);
+
+ /* Update attachments */
+ for (GPUAttachmentType type = GPU_FB_MAX_ATTACHEMENT; type--;) {
+ GPUTexture *tex = fb->attachments[type].tex;
+
+ if (type >= GPU_FB_COLOR_ATTACHMENT0) {
+ int slot = type - GPU_FB_COLOR_ATTACHMENT0;
+ if (tex != NULL || fill_empty_slot) {
+ gl_attachments[slot] = convert_attachment_type_to_gl(type);
+
+ if (!fill_empty_slot) {
+ fill_empty_slot = true;
+ dummy_tex = GPU_texture_opengl_bindcode(tex);
+ }
+ }
+ else {
+ gl_attachments[slot] = GL_NONE;
+ }
+ }
+ else {
+ fill_empty_slot = false;
+ dummy_tex = 0;
+ }
+
+ if ((fill_empty_slot && tex == NULL) || GPU_FB_ATTACHEMENT_IS_DIRTY(fb->dirty_flag, type)) {
+ if (tex != NULL) {
+ gpu_framebuffer_attachment_attach(&fb->attachments[type], type);
+
+ fb->multisample = (GPU_texture_samples(tex) > 0);
+ fb->width = GPU_texture_width(tex);
+ fb->height = GPU_texture_height(tex);
+
+ fill_empty_slot = dummy_tex != 0;
+ }
+ else {
+ glFramebufferTexture(GL_FRAMEBUFFER, convert_attachment_type_to_gl(type), dummy_tex, 0);
+ }
+ }
+ }
+ fb->dirty_flag = 0;
+
+ /* Update draw buffers (color targets)
+ * This state is saved in the FBO */
+ glDrawBuffers(GPU_FB_MAX_COLOR_ATTACHMENT, gl_attachments);
+}
+
#define FRAMEBUFFER_STACK_DEPTH 16
@@ -451,8 +509,15 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb)
gpu_framebuffer_current_set(fb);
- if (fb->dirty_flag != 0)
- gpu_framebuffer_update_attachments(fb);
+ if (fb->dirty_flag != 0) {
+ if (GPU_unused_fb_slot_workaround()) {
+ /* XXX: Please AMD, fix this. */
+ gpu_framebuffer_update_attachments_and_fill_empty_slots(fb);
+ }
+ else {
+ gpu_framebuffer_update_attachments(fb);
+ }
+ }
/* TODO manually check for errors? */
#if 0