[Bf-blender-cvs] [b868f43fd38] blender2.8: Cycles support for preview on viewport with core profile

Dalai Felinto noreply at git.blender.org
Fri Apr 28 19:26:13 CEST 2017


Commit: b868f43fd382c0497b82f29685f6280d9692a0fb
Author: Dalai Felinto
Date:   Fri Apr 28 19:25:57 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBb868f43fd382c0497b82f29685f6280d9692a0fb

Cycles support for preview on viewport with core profile

This upgrade the drawing code to use latest opengl calls.
Also, it adds a fallback shader for opencolorio.

Reviewers: sergey, brecht
Subscribers: merwin, fclem

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

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

M	intern/cycles/device/device.cpp
M	intern/cycles/device/device.h
M	intern/cycles/device/device_cuda.cpp
M	intern/cycles/device/device_multi.cpp
M	intern/cycles/render/buffers.cpp

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

diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index c024021b4b3..4c4e862ed1f 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -23,6 +23,7 @@
 #include "util/util_debug.h"
 #include "util/util_foreach.h"
 #include "util/util_half.h"
+#include "util/util_logging.h"
 #include "util/util_math.h"
 #include "util/util_opengl.h"
 #include "util/util_time.h"
@@ -75,8 +76,13 @@ std::ostream& operator <<(std::ostream &os,
 
 Device::~Device()
 {
-	if(!background && vertex_buffer != 0) {
-		glDeleteBuffers(1, &vertex_buffer);
+	if(!background) {
+		if(vertex_buffer != 0) {
+			glDeleteBuffers(1, &vertex_buffer);
+		}
+		if(fallback_shader_program != 0) {
+			glDeleteProgram(fallback_shader_program);
+		}
 	}
 }
 
@@ -98,125 +104,266 @@ void Device::pixels_free(device_memory& mem)
 	mem_free(mem);
 }
 
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
-	const DeviceDrawParams &draw_params)
+/* TODO move shaders to standalone .glsl file. */
+const char *FALLBACK_VERTEX_SHADER =
+"#version 330\n"
+"uniform vec2 fullscreen;\n"
+"in vec2 texCoord;\n"
+"in vec2 pos;\n"
+"out vec2 texCoord_interp;\n"
+"\n"
+"vec2 normalize_coordinates()\n"
+"{\n"
+"	return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+"	gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
+"	texCoord_interp = texCoord;\n"
+"}\n\0";
+
+const char *FALLBACK_FRAGMENT_SHADER =
+"#version 330\n"
+"uniform sampler2D image_texture;\n"
+"in vec2 texCoord_interp;\n"
+"out vec4 fragColor;\n"
+"\n"
+"void main()\n"
+"{\n"
+"	fragColor = texture(image_texture, texCoord_interp);\n"
+"}\n\0";
+
+static void shader_print_errors(const char *task, const char *log, const char *code)
 {
-	pixels_copy_from(rgba, y, w, h);
+	LOG(ERROR) << "Shader: " << task << " error:";
+	LOG(ERROR) << "===== shader string ====";
 
-	if(transparent) {
-		glEnable(GL_BLEND);
-		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+	stringstream stream(code);
+	string partial;
+
+	int line = 1;
+	while(getline(stream, partial, '\n')) {
+		if(line < 10) {
+			LOG(ERROR) << " " << line << " " << partial;
+		}
+		else {
+			LOG(ERROR) << line << " " << partial;
+		}
+		line++;
 	}
+	LOG(ERROR) << log;
+}
 
-	glColor3f(1.0f, 1.0f, 1.0f);
+static int bind_fallback_shader(void)
+{
+	GLint status;
+	GLchar log[5000];
+	GLsizei length = 0;
+	GLuint program = 0;
 
-	if(rgba.data_type == TYPE_HALF) {
-		/* for multi devices, this assumes the inefficient method that we allocate
-		 * all pixels on the device even though we only render to a subset */
-		GLhalf *data_pointer = (GLhalf*)rgba.data_pointer;
-		float vbuffer[16], *basep;
-		float *vp = NULL;
+	struct Shader {
+		const char *source;
+		GLenum type;
+	} shaders[2] = {
+	    {FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
+	    {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}
+    };
 
-		data_pointer += 4*y*w;
+	program = glCreateProgram();
 
-		/* draw half float texture, GLSL shader for display transform assumed to be bound */
-		GLuint texid;
-		glGenTextures(1, &texid);
-		glBindTexture(GL_TEXTURE_2D, texid);
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	for(int i = 0; i < 2; i++) {
+		GLuint shader = glCreateShader(shaders[i].type);
+
+		string source_str = shaders[i].source;
+		const char *c_str = source_str.c_str();
 
-		glEnable(GL_TEXTURE_2D);
+		glShaderSource(shader, 1, &c_str, NULL);
+		glCompileShader(shader);
 
-		if(draw_params.bind_display_space_shader_cb) {
-			draw_params.bind_display_space_shader_cb();
+		glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+
+		if(!status) {
+			glGetShaderInfoLog(shader, sizeof(log), &length, log);
+			shader_print_errors("compile", log, c_str);
+			return 0;
 		}
 
-		if(GLEW_VERSION_1_5) {
-			if(!vertex_buffer)
-				glGenBuffers(1, &vertex_buffer);
+		glAttachShader(program, shader);
+	}
+
+	/* Link output. */
+	glBindFragDataLocation(program, 0, "fragColor");
 
-			glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
-			/* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
-			glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+	/* Link and error check. */
+	glLinkProgram(program);
 
-			vp = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	glGetProgramiv(program, GL_LINK_STATUS, &status);
+	if(!status) {
+		glGetShaderInfoLog(program, sizeof(log), &length, log);
+		shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
+		shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
+		return 0;
+	}
 
-			basep = NULL;
+	return program;
+}
+
+bool Device::bind_fallback_display_space_shader(const float width, const float height)
+{
+	if(fallback_status == FALLBACK_SHADER_STATUS_ERROR) {
+		return false;
+	}
+
+	if(fallback_status == FALLBACK_SHADER_STATUS_NONE) {
+		fallback_shader_program = bind_fallback_shader();
+		fallback_status = FALLBACK_SHADER_STATUS_ERROR;
+
+		if (fallback_shader_program == 0) {
+			return false;
 		}
-		else {
-			basep = vbuffer;
-			vp = vbuffer;
+
+		glUseProgram(fallback_shader_program);
+		image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture");
+		if(image_texture_location < 0) {
+			LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform.";
+			return false;
 		}
 
-		if(vp) {
-			/* texture coordinate - vertex pair */
-			vp[0] = 0.0f;
-			vp[1] = 0.0f;
-			vp[2] = dx;
-			vp[3] = dy;
-
-			vp[4] = 1.0f;
-			vp[5] = 0.0f;
-			vp[6] = (float)width + dx;
-			vp[7] = dy;
-
-			vp[8] = 1.0f;
-			vp[9] = 1.0f;
-			vp[10] = (float)width + dx;
-			vp[11] = (float)height + dy;
-
-			vp[12] = 0.0f;
-			vp[13] = 1.0f;
-			vp[14] = dx;
-			vp[15] = (float)height + dy;
-
-			if(vertex_buffer)
-				glUnmapBuffer(GL_ARRAY_BUFFER);
+		fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen");
+		if(fullscreen_location < 0) {
+			LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform.";
+			return false;
 		}
 
-		glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), basep);
-		glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), ((char *)basep) + 2 * sizeof(float));
+		fallback_status = FALLBACK_SHADER_STATUS_SUCCESS;
+	}
 
-		glEnableClientState(GL_VERTEX_ARRAY);
-		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+	/* Run this every time. */
+	glUseProgram(fallback_shader_program);
+	glUniform1i(image_texture_location, 0);
+	glUniform2f(fullscreen_location, width, height);
+	return true;
+}
 
-		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+void Device::draw_pixels(
+    device_memory& rgba, int y,
+    int w, int h, int width, int height,
+    int dx, int dy, int dw, int dh,
+    bool transparent, const DeviceDrawParams &draw_params)
+{
+	const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
+	pixels_copy_from(rgba, y, w, h);
 
-		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-		glDisableClientState(GL_VERTEX_ARRAY);
+	GLuint texid;
+	glGenTextures(1, &texid);
+	glBindTexture(GL_TEXTURE_2D, texid);
 
-		if(vertex_buffer) {
-			glBindBuffer(GL_ARRAY_BUFFER, 0);
-		}
+	if(rgba.data_type == TYPE_HALF) {
+		GLhalf *data_pointer = (GLhalf*)rgba.data_pointer;
+		data_pointer += 4 * y * w;
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer);
+	}
+	else {
+		uint8_t *data_pointer = (uint8_t*)rgba.data_pointer;
+		data_pointer += 4 * y * w;
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data_pointer);
+	}
 
-		if(draw_params.unbind_display_space_shader_cb) {
-			draw_params.unbind_display_space_shader_cb();
-		}
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	glEnable(GL_TEXTURE_2D);
+
+	if(transparent) {
+		glEnable(GL_BLEND);
+		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+	}
 
-		glBindTexture(GL_TEXTURE_2D, 0);
-		glDisable(GL_TEXTURE_2D);
-		glDeleteTextures(1, &texid);
+	GLint shader_program;
+	if(use_fallback_shader) {
+		if (!bind_fallback_display_space_shader(dw, dh)) {
+			return;
+		}
+		shader_program = fallback_shader_program;
 	}
 	else {
-		/* fallback for old graphics cards that don't support GLSL, half float,
-		 * and non-power-of-two textures */
-		glPixelZoom((float)width/(float)w, (float)height/(float)h);
-		glRasterPos2f(dx, dy);
+		draw_params.bind_display_space_shader_cb();
+		glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
+	}
+
+	if(!vertex_buffer) {
+		glGenBuffers(1, &vertex_buffer);
+	}
+
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+	/* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
+	glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+	float *vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+	if(vpointer) {
+		/* texture coordinate - vertex pair */
+		vpointer[0] = 0.0f;
+		vpointer[1] = 0.0f;
+		vpointer[2] = dx;
+		vpointer[3] = dy;
 
-		uint8_t *pixels = (uint8_t*)rgba.data_pointer;
+		vpointer[4] = 1.0f;
+		vpointer[5] = 0.0f;
+		vpointer[6] = (float)width + dx;
+		vpointer[7] = dy;
 
-		pixels += 4*y*w;
+		vpointer[8] = 1.0f;
+		vpointer[9] = 1.0f;
+		vpointer[10] = (float)width + dx;
+		vpointer[11] = (float)height + dy;
 
-		glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+		vpointer[12] = 0.0f;
+		vpointer[13] = 1.0f;
+		vpointer[14] = dx;
+		vpointer[15] = (float)height + dy;
 
-		glRasterPos2f(0.0f, 0.0f);
-		glPixelZoom(1.0f, 1.0f);
+		if(vertex_buffer) {
+			glUnmapBuffer(GL_ARRAY_BUFFER);
+		}
 	}
 
-	if(transparent)
+	GLuint vertex_array_object;
+	GLuint position_attribute, texcoord_attribute;
+
+	glGenVertexArrays(1, &vertex_array_object);
+	glBindVertexArray(vertex_array_object);
+
+	texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+	position_attribute = glGetAttribLocation(shader_program, "pos");
+
+	glEnableVertexAttribArray(texcoord_attribute);
+	glEn

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list