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:
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c15
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c38
-rw-r--r--source/blender/gpu/intern/gpu_shader.c40
-rw-r--r--source/blender/gpu/intern/gpu_texture.c1
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c105
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c196
6 files changed, 391 insertions, 4 deletions
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index e8fd4b8b8b1..d7ed65e853e 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -69,6 +69,8 @@ static struct GPUGlobal {
GLint maxtexsize;
GLint maxcubemapsize;
GLint maxtextures;
+ GLint maxubosize;
+ GLint maxubobinds;
bool extdisabled;
int colordepth;
int samples_color_texture_max;
@@ -121,6 +123,16 @@ int GPU_max_cube_map_size(void)
return GG.maxcubemapsize;
}
+int GPU_max_ubo_binds(void)
+{
+ return GG.maxubobinds;
+}
+
+int GPU_max_ubo_size(void)
+{
+ return GG.maxubosize;
+}
+
void GPU_get_dfdy_factors(float fac[2])
{
copy_v2_v2(fac, GG.dfdyfactors);
@@ -154,6 +166,9 @@ void gpu_extensions_init(void)
else
GG.max_anisotropy = 1.0f;
+ glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &GG.maxubobinds);
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GG.maxubosize);
+
GLint r, g, b;
glGetIntegerv(GL_RED_BITS, &r);
glGetIntegerv(GL_GREEN_BITS, &g);
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 2ef8018e5e9..1efc451f4a8 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -260,6 +260,43 @@ void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
glPushMatrix();
}
+void GPU_framebuffer_bind(GPUFrameBuffer *fb)
+{
+ int numslots = 0, i;
+ GLenum attachments[4];
+ GLenum readattachement = 0;
+ GPUTexture *tex;
+
+ for (i = 0; i < 4; i++) {
+ if (fb->colortex[i]) {
+ attachments[numslots] = GL_COLOR_ATTACHMENT0 + i;
+ tex = fb->colortex[i];
+
+ if (!readattachement)
+ readattachement = GL_COLOR_ATTACHMENT0 + i;
+
+ numslots++;
+ }
+ }
+
+ /* bind framebuffer */
+ glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
+
+ if (numslots == 0) {
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ tex = fb->depthtex;
+ }
+ else {
+ /* last bound prevails here, better allow explicit control here too */
+ glDrawBuffers(numslots, attachments);
+ glReadBuffer(readattachement);
+ }
+
+ glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex));
+ GG.currentfb = fb->object;
+}
+
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
{
@@ -283,7 +320,6 @@ void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot)
/* push matrices and set default viewport and matrix */
glViewport(0, 0, GPU_texture_width(fb->colortex[slot]), GPU_texture_height(fb->colortex[slot]));
GG.currentfb = fb->object;
- GG.currentfb = fb->object;
}
bool GPU_framebuffer_bound(GPUFrameBuffer *fb)
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index b81c19d5c70..0d6fd5f7b99 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -37,6 +37,7 @@
#include "GPU_debug.h"
#include "GPU_extensions.h"
#include "GPU_shader.h"
+#include "GPU_uniformbuffer.h"
#include "GPU_texture.h"
#include "gpu_shader_private.h"
@@ -64,10 +65,16 @@ extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
extern char datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl[];
extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
+extern char datatoc_gpu_shader_3D_instance_vert_glsl[];
extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
+extern char datatoc_gpu_shader_3D_groundline_vert_glsl[];
+extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
+extern char datatoc_gpu_shader_3D_lamp_vert_glsl[];
+
extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_point_uniform_color_smooth_frag_glsl[];
extern char datatoc_gpu_shader_point_uniform_color_outline_smooth_frag_glsl[];
@@ -511,11 +518,24 @@ int GPU_shader_get_uniform(GPUShader *shader, const char *name)
return glGetUniformLocation(shader->program, name);
}
+int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+
+ return glGetUniformBlockIndex(shader->program, name);
+}
+
void *GPU_shader_get_interface(GPUShader *shader)
{
return shader->uniform_interface;
}
+/* Clement : Temp */
+int GPU_shader_get_program(GPUShader *shader)
+{
+ return (int)shader->program;
+}
+
void GPU_shader_set_interface(GPUShader *shader, void *interface)
{
shader->uniform_interface = interface;
@@ -563,6 +583,17 @@ void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int ou
}
}
+void GPU_shader_uniform_buffer(GPUShader *shader, int location, GPUUniformBuffer *ubo)
+{
+ int bindpoint = GPU_uniformbuffer_bindpoint(ubo);
+
+ if (location == -1) {
+ return;
+ }
+
+ glUniformBlockBinding(shader->program, location, bindpoint);
+}
+
void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
{
int number = GPU_texture_bound_number(tex);
@@ -645,12 +676,21 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_2D_IMAGE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE] = { datatoc_gpu_shader_3D_instance_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
[GPU_SHADER_3D_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_smooth_color_vert_glsl,
datatoc_gpu_shader_3D_smooth_color_frag_glsl },
[GPU_SHADER_3D_DEPTH_ONLY] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_depth_only_frag_glsl },
+ [GPU_SHADER_3D_GROUNDPOINT] = { datatoc_gpu_shader_3D_groundpoint_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_groundline_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ datatoc_gpu_shader_3D_groundline_geom_glsl },
+
+ [GPU_SHADER_3D_LAMP_COMMON] = { datatoc_gpu_shader_3D_lamp_vert_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl},
+
[GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR] =
{ datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl },
[GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR] =
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 6fb658e20eb..3513250993e 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -91,6 +91,7 @@ static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type,
/* Formats texture & renderbuffer */
case GPU_RGBA16F: return GL_RGBA16F;
case GPU_RG32F: return GL_RG32F;
+ case GPU_RG16F: return GL_RG16F;
case GPU_RGBA8: return GL_RGBA8;
case GPU_R8: return GL_R8;
/* Special formats texture & renderbuffer */
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
new file mode 100644
index 00000000000..76aa1a8226f
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -0,0 +1,105 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gpu_uniformbuffer.c
+ * \ingroup gpu
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+
+#include "GPU_extensions.h"
+#include "GPU_glew.h"
+#include "GPU_uniformbuffer.h"
+
+struct GPUUniformBuffer {
+ int size; /* in bytes */
+ GLuint bindcode; /* opengl identifier for UBO */
+ int bindpoint; /* current binding point */
+};
+
+GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256])
+{
+ GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBuffer), "GPUUniformBuffer");
+ ubo->size = size;
+
+ /* Generate Buffer object */
+ glGenBuffers(1, &ubo->bindcode);
+
+ if (!ubo->bindcode) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUUniformBuffer: UBO create failed");
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ if (ubo->size > GPU_max_ubo_size()) {
+ if (err_out)
+ BLI_snprintf(err_out, 256, "GPUUniformBuffer: UBO too big");
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+ return ubo;
+}
+
+void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
+{
+ glDeleteBuffers(1, &ubo->bindcode);
+ MEM_freeN(ubo);
+}
+
+void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
+{
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+}
+
+void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
+{
+ if (number >= GPU_max_ubo_binds()) {
+ fprintf(stderr, "Not enough UBO slots.\n");
+ return;
+ }
+
+ if (ubo->bindcode != 0) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
+ }
+
+ ubo->bindpoint = number;
+}
+
+int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo)
+{
+ return ubo->bindpoint;
+} \ No newline at end of file
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index a4fb3494639..b1964857ab1 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -31,10 +31,19 @@
* System that manages viewport drawing.
*/
+#include <string.h>
+
+#include "BLI_rect.h"
+
+#include "DNA_vec_types.h"
+
+#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_immediate.h"
-#include "GPU_viewport.h"
#include "GPU_texture.h"
+#include "GPU_viewport.h"
+
+#include "DRW_engine.h"
#include "MEM_guardedalloc.h"
@@ -43,19 +52,200 @@ struct GPUViewport {
/* debug */
GPUTexture *debug_depth;
- int debug_width, debug_height;
+ int size[2];
+
+ /* Viewport Buffer Storage */
+ /* TODO indentify to what engine conf are theses buffers */
+ DefaultFramebufferList *fbl;
+ DefaultTextureList *txl;
+ DefaultPassList *psl;
};
+static void GPU_viewport_buffers_free(GPUViewport *viewport);
+static void GPU_viewport_passes_free(GPUViewport *viewport);
+
GPUViewport *GPU_viewport_create(void)
{
GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport");
+ viewport->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList");
+ viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList");
+ viewport->psl = MEM_callocN(sizeof(PassList), "PassList");
+ viewport->size[0] = viewport->size[1] = -1;
+
return viewport;
}
+void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss)
+{
+ *fbs = viewport->fbl;
+ *txs = viewport->txl;
+ *pss = viewport->psl;
+}
+
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
+{
+ /* add one pixel because of scissor test */
+ int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1;
+
+#ifndef WITH_VIEWPORT_CACHE_TEST
+ /* TODO for testing only, we need proper cache invalidation */
+ GPU_viewport_passes_free(viewport);
+#endif
+
+ if (viewport->fbl->default_fb) {
+ if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
+ GPU_viewport_buffers_free(viewport);
+ }
+ }
+
+ if (!viewport->fbl->default_fb) {
+ bool ok = true;
+ viewport->size[0] = rect_w;
+ viewport->size[1] = rect_h;
+
+ viewport->fbl->default_fb = GPU_framebuffer_create();
+ if (!viewport->fbl->default_fb) {
+ ok = false;
+ goto cleanup;
+ }
+
+ /* Color */
+ /* No multi samples for now */
+ viewport->txl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
+ if (!viewport->txl->color) {
+ ok = false;
+ goto cleanup;
+ }
+
+ if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->color, 0)) {
+ ok = false;
+ goto cleanup;
+ }
+
+ /* Depth */
+ viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
+ if (!viewport->txl->depth) {
+ ok = false;
+ goto cleanup;
+ }
+ else if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->depth, 0)) {
+ ok = false;
+ goto cleanup;
+ }
+ else if (!GPU_framebuffer_check_valid(viewport->fbl->default_fb, NULL)) {
+ ok = false;
+ goto cleanup;
+ }
+
+cleanup:
+ if (!ok) {
+ GPU_viewport_free(viewport);
+ MEM_freeN(viewport);
+ return;
+ }
+
+ GPU_framebuffer_restore();
+ }
+
+ GPU_framebuffer_slots_bind(viewport->fbl->default_fb, 0);
+}
+
+static void draw_ofs_to_screen(GPUViewport *viewport)
+{
+ GPUTexture *color = viewport->txl->color;
+
+ const float w = (float)GPU_texture_width(color);
+ const float h = (float)GPU_texture_height(color);
+
+ VertexFormat *format = immVertexFormat();
+ unsigned texcoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT);
+ unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
+
+ GPU_texture_bind(color, 0);
+
+ immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+
+ immBegin(GL_QUADS, 4);
+
+ immAttrib2f(texcoord, 0.0f, 0.0f);
+ immVertex2f(pos, 0.0f, 0.0f);
+
+ immAttrib2f(texcoord, 1.0f, 0.0f);
+ immVertex2f(pos, w, 0.0f);
+
+ immAttrib2f(texcoord, 1.0f, 1.0f);
+ immVertex2f(pos, w, h);
+
+ immAttrib2f(texcoord, 0.0f, 1.0f);
+ immVertex2f(pos, 0.0f, h);
+
+ immEnd();
+
+ GPU_texture_unbind(color);
+
+ immUnbindProgram();
+}
+
+void GPU_viewport_unbind(GPUViewport *viewport)
+{
+ if (viewport->fbl->default_fb) {
+ GPU_framebuffer_texture_unbind(NULL, NULL);
+ GPU_framebuffer_restore();
+
+ glEnable(GL_SCISSOR_TEST);
+
+ /* This might be bandwidth limiting */
+ draw_ofs_to_screen(viewport);
+ }
+}
+
+static void GPU_viewport_buffers_free(GPUViewport *viewport)
+{
+ FramebufferList *fbl = (FramebufferList *)viewport->fbl;
+ TextureList *txl = (TextureList *)viewport->txl;
+ int i;
+ for (i = MAX_BUFFERS - 1; i > -1; --i) {
+ GPUFrameBuffer *fb = fbl->framebuffers[i];
+ if (fb) {
+ GPU_framebuffer_free(fb);
+ fbl->framebuffers[i] = NULL;
+ }
+ }
+ for (i = MAX_TEXTURES - 1; i > -1; --i) {
+ GPUTexture *tex = txl->textures[i];
+ if (tex) {
+ GPU_texture_free(tex);
+ txl->textures[i] = NULL;
+ }
+ }
+}
+
+static void GPU_viewport_passes_free(GPUViewport *viewport)
+{
+ PassList *psl = (PassList *)viewport->psl;
+ int i;
+
+ for (i = MAX_PASSES - 1; i > -1; --i) {
+ struct DRWPass *pass = psl->passes[i];
+ if (pass) {
+ DRW_pass_free(pass);
+ MEM_freeN(pass);
+ psl->passes[i] = NULL;
+ }
+ }
+}
+
void GPU_viewport_free(GPUViewport *viewport)
{
GPU_viewport_debug_depth_free(viewport);
- MEM_freeN(viewport);
+ GPU_viewport_buffers_free(viewport);
+ GPU_viewport_passes_free(viewport);
+
+ MEM_freeN(viewport->fbl);
+ MEM_freeN(viewport->txl);
+ MEM_freeN(viewport->psl);
}
/****************** debug ********************/