[Bf-blender-cvs] [c0a71b8369a] blender2.8: Fix problem with unused color slot in framebuffer on some bugged AMD GPUs

mano-wii noreply at git.blender.org
Thu Dec 6 01:04:57 CET 2018


Commit: c0a71b8369a19cba05765af828ba014e67d05bc5
Author: mano-wii
Date:   Wed Dec 5 20:59:22 2018 -0200
Branches: blender2.8
https://developer.blender.org/rBc0a71b8369a19cba05765af828ba014e67d05bc5

Fix problem with unused color slot in framebuffer on some bugged AMD GPUs

Differential Revision: https://developer.blender.org/D4035

===================================================================

M	source/blender/gpu/intern/gpu_framebuffer.c

===================================================================

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



More information about the Bf-blender-cvs mailing list