[Bf-blender-cvs] [998a867] master: GPU framebuffer API:

Antony Riakiotakis noreply at git.blender.org
Tue Nov 18 11:59:44 CET 2014


Commit: 998a867ba3b30911b1512ac782a23eadd6aa77db
Author: Antony Riakiotakis
Date:   Tue Nov 18 11:56:23 2014 +0100
Branches: master
https://developer.blender.org/rB998a867ba3b30911b1512ac782a23eadd6aa77db

GPU framebuffer API:

Allow binding a texture to a different texture attachment than the
first.

Also fix a number error in seperable gaussian blur shader.

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

M	source/blender/gpu/GPU_extensions.h
M	source/blender/gpu/intern/gpu_extensions.c
M	source/blender/gpu/intern/gpu_material.c
M	source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl

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

diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 3daf858..8ca7958 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -141,8 +141,8 @@ int GPU_texture_opengl_bindcode(GPUTexture *tex);
  *   be called before rendering to the window framebuffer again */
 
 GPUFrameBuffer *GPU_framebuffer_create(void);
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256]);
-void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex);
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256]);
+void GPU_framebuffer_texture_detach(GPUTexture *tex);
 void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex, int w, int h);
 void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex);
 void GPU_framebuffer_free(GPUFrameBuffer *fb);
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 04f8e68..ecab103 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -323,6 +323,7 @@ struct GPUTexture {
 	int fromblender;		/* we got the texture from Blender */
 
 	GPUFrameBuffer *fb;		/* GPUFramebuffer this texture is attached to */
+	int fb_attachment;		/* slot the texture is attached to */
 	int depth;				/* is a depth texture? */
 };
 
@@ -370,6 +371,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
 	tex->refcount = 1;
 	tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D;
 	tex->depth = depth;
+	tex->fb_attachment = -1;
 
 	glGenTextures(1, &tex->bindcode);
 
@@ -791,7 +793,7 @@ void GPU_texture_free(GPUTexture *tex)
 	
 	if (tex->refcount == 0) {
 		if (tex->fb)
-			GPU_framebuffer_texture_detach(tex->fb, tex);
+			GPU_framebuffer_texture_detach(tex);
 		if (tex->bindcode && !tex->fromblender)
 			glDeleteTextures(1, &tex->bindcode);
 
@@ -831,9 +833,12 @@ GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
 
 /* GPUFrameBuffer */
 
+/* Number of maximum output slots. We support 4 outputs for now (usually we wouldn't need more to preserve fill rate) */
+#define GPU_FB_MAX_SLOTS 4
+
 struct GPUFrameBuffer {
 	GLuint object;
-	GPUTexture *colortex;
+	GPUTexture *colortex[GPU_FB_MAX_SLOTS];
 	GPUTexture *depthtex;
 };
 
@@ -857,16 +862,21 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
 	return fb;
 }
 
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256])
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
 {
 	GLenum status;
 	GLenum attachment;
 	GLenum error;
 
+	if (slot >= GPU_FB_MAX_SLOTS) {
+		fprintf(stderr, "Attaching to index %d framebuffer slot unsupported in blender use at most %d\n", slot, GPU_FB_MAX_SLOTS);
+		return 0;
+	}
+
 	if (tex->depth)
 		attachment = GL_DEPTH_ATTACHMENT_EXT;
 	else
-		attachment = GL_COLOR_ATTACHMENT0_EXT;
+		attachment = GL_COLOR_ATTACHMENT0_EXT + slot;
 
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
 	GG.currentfb = fb->object;
@@ -890,8 +900,9 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err
 		glReadBuffer(GL_NONE);
 	}
 	else {
-		glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
-		glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+		/* last bound prevails here, better allow explicit control here too */
+		glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
+		glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
 	}
 
 	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
@@ -905,22 +916,26 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err
 	if (tex->depth)
 		fb->depthtex = tex;
 	else
-		fb->colortex = tex;
+		fb->colortex[slot] = tex;
 
 	tex->fb= fb;
+	tex->fb_attachment = slot;
 
 	return 1;
 }
 
-void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
+void GPU_framebuffer_texture_detach(GPUTexture *tex)
 {
 	GLenum attachment;
+	GPUFrameBuffer *fb;
 
-	if (!tex->fb)
+	if (!tex->fb || tex->fb_attachment == -1)
 		return;
 
-	if (GG.currentfb != tex->fb->object) {
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
+	fb = tex->fb;
+
+	if (GG.currentfb != fb->object) {
+		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
 		GG.currentfb = tex->fb->object;
 	}
 
@@ -929,14 +944,16 @@ void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
 		attachment = GL_DEPTH_ATTACHMENT_EXT;
 	}
 	else {
-		fb->colortex = NULL;
-		attachment = GL_COLOR_ATTACHMENT0_EXT;
+		BLI_assert(fb->colortex[tex->fb_attachment] == tex);
+		fb->colortex[tex->fb_attachment] = NULL;
+		attachment = GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment;
 	}
 
 	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
 		tex->target, 0, 0);
 
 	tex->fb = NULL;
+	tex->fb_attachment = -1;
 }
 
 void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, int w, int h)
@@ -973,10 +990,15 @@ void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUS
 
 void GPU_framebuffer_free(GPUFrameBuffer *fb)
 {
+	int i;
 	if (fb->depthtex)
-		GPU_framebuffer_texture_detach(fb, fb->depthtex);
-	if (fb->colortex)
-		GPU_framebuffer_texture_detach(fb, fb->colortex);
+		GPU_framebuffer_texture_detach(fb->depthtex);
+
+	for (i = 0; i < GPU_FB_MAX_SLOTS; i++) {
+		if (fb->colortex[i]) {
+			GPU_framebuffer_texture_detach(fb->colortex[i]);
+		}
+	}
 
 	if (fb->object) {
 		glDeleteFramebuffersEXT(1, &fb->object);
@@ -1093,7 +1115,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
 		return NULL;
 	}
 
-	if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) {
+	if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) {
 		GPU_offscreen_free(ofs);
 		return NULL;
 	}
@@ -1104,7 +1126,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
 		return NULL;
 	}
 
-	if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) {
+	if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) {
 		GPU_offscreen_free(ofs);
 		return NULL;
 	}
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index fa22783..e4fa8a7 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1851,7 +1851,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 				return lamp;
 			}
 		
-			if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, NULL)) {
+			if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, NULL)) {
 				gpu_lamp_shadow_free(lamp);
 				return lamp;
 			}
@@ -1863,7 +1863,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 				return lamp;
 			}
 
-			if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
+			if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
 				gpu_lamp_shadow_free(lamp);
 				return lamp;
 			}
@@ -1881,7 +1881,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 				return lamp;
 			}
 		
-			if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, NULL)) {
+			if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, NULL)) {
 				gpu_lamp_shadow_free(lamp);
 				return lamp;
 			}
@@ -1893,7 +1893,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 				return lamp;
 			}
 
-			if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
+			if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
 				gpu_lamp_shadow_free(lamp);
 				return lamp;
 			}
diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
index 978b6db..5f406c9 100644
--- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
@@ -10,7 +10,7 @@ void main()
 	color += texture2D( textureSource, gl_TexCoord[0].st + vec2(0.0, 0.0)) * 0.3125;
 	color += texture2D( textureSource, gl_TexCoord[0].st + vec2(1.0 * ScaleU.x,  1.0 * ScaleU.y ) ) * 0.234375;
 	color += texture2D( textureSource, gl_TexCoord[0].st + vec2(2.0 * ScaleU.x,  2.0 * ScaleU.y ) ) * 0.09375;
-	color += texture2D( textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, -3.0 * ScaleU.y ) ) * 0.015625;
+	color += texture2D( textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x,  3.0 * ScaleU.y ) ) * 0.015625;
 
 	gl_FragColor = color;
 }




More information about the Bf-blender-cvs mailing list