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 'intern/cycles')
-rw-r--r--intern/cycles/blender/addon/__init__.py18
-rw-r--r--intern/cycles/blender/addon/engine.py13
-rw-r--r--intern/cycles/blender/addon/ui.py6
-rw-r--r--intern/cycles/blender/blender_object.cpp134
-rw-r--r--intern/cycles/blender/blender_python.cpp16
-rw-r--r--intern/cycles/blender/blender_session.cpp8
-rw-r--r--intern/cycles/blender/blender_session.h3
-rw-r--r--intern/cycles/blender/blender_sync.cpp18
-rw-r--r--intern/cycles/blender/blender_sync.h5
-rw-r--r--intern/cycles/device/device.cpp321
-rw-r--r--intern/cycles/device/device.h22
-rw-r--r--intern/cycles/device/device_cuda.cpp57
-rw-r--r--intern/cycles/device/device_multi.cpp9
-rw-r--r--intern/cycles/render/buffers.cpp6
-rw-r--r--intern/cycles/util/util_opengl.h8
-rw-r--r--intern/cycles/util/util_view.cpp2
16 files changed, 383 insertions, 263 deletions
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index eb792af7264..7c58df68011 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -19,7 +19,7 @@
bl_info = {
"name": "Cycles Render Engine",
"author": "",
- "blender": (2, 76, 0),
+ "blender": (2, 80, 0),
"location": "Info header, render engine menu",
"description": "Cycles Render Engine integration",
"warning": "",
@@ -66,21 +66,21 @@ class CyclesRender(bpy.types.RenderEngine):
engine.free(self)
# final render
- def update(self, data, scene):
+ def update(self, data, depsgraph, scene):
if not self.session:
if self.is_preview:
cscene = bpy.context.scene.cycles
use_osl = cscene.shading_system and cscene.device == 'CPU'
- engine.create(self, data, scene,
+ engine.create(self, data, depsgraph, scene,
None, None, None, use_osl)
else:
- engine.create(self, data, scene)
+ engine.create(self, data, depsgraph, scene)
else:
engine.reset(self, data, scene)
- def render(self, scene):
- engine.render(self)
+ def render_to_image(self, depsgraph):
+ engine.render(self, depsgraph)
def bake(self, scene, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
engine.bake(self, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
@@ -88,12 +88,12 @@ class CyclesRender(bpy.types.RenderEngine):
# viewport render
def view_update(self, context):
if not self.session:
- engine.create(self, context.blend_data, context.scene,
+ engine.create(self, context.blend_data, context.depsgraph, context.scene,
context.region, context.space_data, context.region_data)
engine.update(self, context.blend_data, context.scene)
- def view_draw(self, context):
- engine.draw(self, context.region, context.space_data, context.region_data)
+ def render_to_view(self, context):
+ engine.draw(self, context.depsgraph, context.region, context.space_data, context.region_data)
def update_script_node(self, node):
if engine.with_osl():
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index ab57dd44bdb..a418cdd6821 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -123,12 +123,13 @@ def exit():
_cycles.exit()
-def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
+def create(engine, data, depsgraph, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
import bpy
import _cycles
data = data.as_pointer()
userpref = bpy.context.user_preferences.as_pointer()
+ depsgraph = depsgraph.as_pointer()
scene = scene.as_pointer()
if region:
region = region.as_pointer()
@@ -142,7 +143,8 @@ def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=Fa
else:
_cycles.debug_flags_reset()
- engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d, preview_osl)
+ engine.session = _cycles.create(
+ engine.as_pointer(), userpref, data, depsgraph, scene, region, v3d, rv3d, preview_osl)
def free(engine):
@@ -153,7 +155,7 @@ def free(engine):
del engine.session
-def render(engine):
+def render(engine, depsgraph):
import _cycles
if hasattr(engine, "session"):
_cycles.render(engine.session)
@@ -178,13 +180,14 @@ def update(engine, data, scene):
_cycles.sync(engine.session)
-def draw(engine, region, v3d, rv3d):
+def draw(engine, depsgraph, region, v3d, rv3d):
import _cycles
+ depsgraph = depsgraph.as_pointer()
v3d = v3d.as_pointer()
rv3d = rv3d.as_pointer()
# draw render image
- _cycles.draw(engine.session, v3d, rv3d)
+ _cycles.draw(engine.session, depsgraph, v3d, rv3d)
def available_devices():
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 19ab9053e9a..4423f3c266b 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1588,6 +1588,7 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
row.prop(rd, "simplify_subdivision", text="Viewport")
row.prop(rd, "simplify_subdivision_render", text="Render")
+
col = layout.column(align=True)
col.label(text="Child Particles")
row = col.row(align=True)
@@ -1650,10 +1651,11 @@ def draw_pause(self, context):
if scene.render.engine == "CYCLES":
view = context.space_data
+ cscene = scene.cycles
+ layout.prop(cscene, "preview_pause", icon="PAUSE", text="")
+
if view.viewport_shade == 'RENDERED':
- cscene = scene.cycles
layername = scene.render.layers.active.name
- layout.prop(cscene, "preview_pause", icon="PAUSE", text="")
layout.prop(cscene, "preview_active_layer", icon="RENDERLAYERS", text=layername)
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 2810ad15b9a..4ed9f00e51f 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -469,19 +469,11 @@ static bool object_render_hide(BL::Object& b_ob,
}
}
-static bool object_render_hide_duplis(BL::Object& b_ob)
-{
- BL::Object parent = b_ob.parent();
-
- return (parent && object_render_hide_original(b_ob.type(), parent.dupli_type()));
-}
-
/* Object Loop */
-void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
+void BlenderSync::sync_objects(float motion_time)
{
/* layer data */
- uint scene_layer = render_layer.scene_layer;
bool motion = motion_time != 0.0f;
if(!motion) {
@@ -500,100 +492,37 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
BlenderObjectCulling culling(scene, b_scene);
/* object loop */
- BL::Scene::object_bases_iterator b_base;
- BL::Scene b_sce = b_scene;
- /* modifier result type (not exposed as enum in C++ API)
- * 1 : DAG_EVAL_PREVIEW
- * 2 : DAG_EVAL_RENDER
- */
- int dupli_settings = preview ? 1 : 2;
-
bool cancel = false;
bool use_portal = false;
- uint layer_override = get_layer(b_engine.layer_override());
- for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
- /* Render layer's scene_layer is affected by local view already,
- * which is not a desired behavior here.
- */
- uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers());
- for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
- BL::Object b_ob = b_base->object();
- bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render();
- uint ob_layer = get_layer(b_base->layers(),
- b_base->layers_local_view(),
- object_is_light(b_ob),
- scene_layers);
- hide = hide || !(ob_layer & scene_layer);
-
- if(!hide) {
- progress.set_sync_status("Synchronizing object", b_ob.name());
-
- /* load per-object culling data */
- culling.init_object(scene, b_ob);
-
- if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
- /* dupli objects */
- b_ob.dupli_list_create(b_scene, dupli_settings);
-
- BL::Object::dupli_list_iterator b_dup;
-
- for(b_ob.dupli_list.begin(b_dup); b_dup != b_ob.dupli_list.end(); ++b_dup) {
- Transform tfm = get_transform(b_dup->matrix());
- BL::Object b_dup_ob = b_dup->object();
- bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
- bool in_dupli_group = (b_dup->type() == BL::DupliObject::type_GROUP);
- bool hide_tris;
-
- if(!(b_dup->hide() || dup_hide || object_render_hide(b_dup_ob, false, in_dupli_group, hide_tris))) {
- /* the persistent_id allows us to match dupli objects
- * between frames and updates */
- BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
-
- /* sync object and mesh or light data */
- Object *object = sync_object(b_ob,
- persistent_id.data,
- *b_dup,
- tfm,
- ob_layer,
- motion_time,
- hide_tris,
- culling,
- &use_portal);
-
- /* sync possible particle data, note particle_id
- * starts counting at 1, first is dummy particle */
- if(!motion && object) {
- sync_dupli_particle(b_ob, *b_dup, object);
- }
-
- }
- }
-
- b_ob.dupli_list_clear();
- }
-
- /* test if object needs to be hidden */
- bool hide_tris;
-
- if(!object_render_hide(b_ob, true, true, hide_tris)) {
- /* object itself */
- Transform tfm = get_transform(b_ob.matrix_world());
- BL::DupliObject b_empty_dupli_ob(PointerRNA_NULL);
- sync_object(b_ob,
- NULL,
- b_empty_dupli_ob,
- tfm,
- ob_layer,
- motion_time,
- hide_tris,
- culling,
- &use_portal);
- }
- }
-
- cancel = progress.get_cancel();
- }
+ BL::Depsgraph::objects_iterator b_ob_iter;
+
+ for(b_depsgraph.objects.begin(b_ob_iter); b_ob_iter != b_depsgraph.objects.end() && !cancel; ++b_ob_iter) {
+ BL::Object b_ob = *b_ob_iter;
+ progress.set_sync_status("Synchronizing object", b_ob.name());
+
+ /* load per-object culling data */
+ culling.init_object(scene, b_ob);
+
+ /* test if object needs to be hidden */
+ bool hide_tris;
+
+ if(!object_render_hide(b_ob, true, true, hide_tris)) {
+ /* object itself */
+ Transform tfm = get_transform(b_ob.matrix_world());
+ BL::DupliObject b_empty_dupli_ob(PointerRNA_NULL);
+ sync_object(b_ob,
+ NULL,
+ b_empty_dupli_ob,
+ tfm,
+ ~(0), /* until we get rid of layers */
+ motion_time,
+ hide_tris,
+ culling,
+ &use_portal);
+ }
+
+ cancel = progress.get_cancel();
}
progress.set_sync_status("");
@@ -617,7 +546,6 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
}
void BlenderSync::sync_motion(BL::RenderSettings& b_render,
- BL::SpaceView3D& b_v3d,
BL::Object& b_override,
int width, int height,
void **python_thread_state)
@@ -654,7 +582,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
b_engine.frame_set(frame, subframe);
python_thread_state_save(python_thread_state);
sync_camera_motion(b_render, b_cam, width, height, 0.0f);
- sync_objects(b_v3d, 0.0f);
+ sync_objects(0.0f);
}
/* always sample these times for camera motion */
@@ -688,7 +616,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
}
/* sync object */
- sync_objects(b_v3d, relative_time);
+ sync_objects(relative_time);
}
/* we need to set the python thread state again because this
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index d509e9de981..92393c10893 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -199,10 +199,10 @@ static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/)
static PyObject *create_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
+ PyObject *pyengine, *pyuserpref, *pydata, *pygraph, *pyscene, *pyregion, *pyv3d, *pyrv3d;
int preview_osl;
- if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene,
+ if(!PyArg_ParseTuple(args, "OOOOOOOOi", &pyengine, &pyuserpref, &pydata, &pygraph, &pyscene,
&pyregion, &pyv3d, &pyrv3d, &preview_osl))
{
return NULL;
@@ -221,6 +221,10 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData data(dataptr);
+ PointerRNA graphptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pygraph), &graphptr);
+ BL::Depsgraph graph(graphptr);
+
PointerRNA sceneptr;
RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
BL::Scene scene(sceneptr);
@@ -245,7 +249,7 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
int width = region.width();
int height = region.height();
- session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
+ session = new BlenderSession(engine, userpref, data, graph, scene, v3d, rv3d, width, height);
}
else {
/* override some settings for preview */
@@ -257,7 +261,7 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
}
/* offline session or preview render */
- session = new BlenderSession(engine, userpref, data, scene);
+ session = new BlenderSession(engine, userpref, data, graph, scene);
}
python_thread_state_save(&session->python_thread_state);
@@ -323,9 +327,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pyv3d, *pyrv3d;
+ PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
- if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
+ if(!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
return NULL;
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 26f9bccd95d..3e851adbf54 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -52,11 +52,13 @@ int BlenderSession::end_resumable_chunk = 0;
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene)
: b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
b_render(b_engine.render()),
+ b_depsgraph(b_depsgraph),
b_scene(b_scene),
b_v3d(PointerRNA_NULL),
b_rv3d(PointerRNA_NULL),
@@ -76,6 +78,7 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
@@ -84,6 +87,7 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
b_userpref(b_userpref),
b_data(b_data),
b_render(b_scene.render()),
+ b_depsgraph(b_depsgraph),
b_scene(b_scene),
b_v3d(b_v3d),
b_rv3d(b_rv3d),
@@ -141,7 +145,7 @@ void BlenderSession::create_session()
session->set_pause(session_pause);
/* create sync */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, is_cpu);
+ sync = new BlenderSync(b_engine, b_data, b_depsgraph, b_scene, scene, !background, session->progress, is_cpu);
BL::Object b_camera_override(b_engine.camera_override());
if(b_v3d) {
if(session_pause == false) {
@@ -211,7 +215,7 @@ void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
session->stats.mem_peak = session->stats.mem_used;
/* sync object should be re-created */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, is_cpu);
+ sync = new BlenderSync(b_engine, b_data, b_depsgraph, b_scene, scene, !background, session->progress, is_cpu);
/* for final render we will do full data sync per render layer, only
* do some basic syncing here, no objects or materials for speed */
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 22b21a18f2e..2daf66fa373 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -36,11 +36,13 @@ public:
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene);
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
@@ -104,6 +106,7 @@ public:
BL::UserPreferences b_userpref;
BL::BlendData b_data;
BL::RenderSettings b_render;
+ BL::Depsgraph b_depsgraph;
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 3b071bf0e7d..abec9616cff 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -44,6 +44,7 @@ CCL_NAMESPACE_BEGIN
BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
Scene *scene,
bool preview,
@@ -51,6 +52,7 @@ BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
bool is_cpu)
: b_engine(b_engine),
b_data(b_data),
+ b_depsgraph(b_depsgraph),
b_scene(b_scene),
shader_map(&scene->shaders),
object_map(&scene->objects),
@@ -210,10 +212,9 @@ void BlenderSync::sync_data(BL::RenderSettings& b_render,
scene->need_motion() == Scene::MOTION_NONE ||
scene->camera->motion_position == Camera::MOTION_POSITION_CENTER)
{
- sync_objects(b_v3d);
+ sync_objects();
}
sync_motion(b_render,
- b_v3d,
b_override,
width, height,
python_thread_state);
@@ -710,17 +711,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
params.shadingsystem = SHADINGSYSTEM_OSL;
/* color managagement */
-#ifdef GLEW_MX
- /* When using GLEW MX we need to check whether we've got an OpenGL
- * context for current window. This is because command line rendering
- * doesn't have OpenGL context actually.
- */
- if(glewGetContext() != NULL)
-#endif
- {
- params.display_buffer_linear = GLEW_ARB_half_float_pixel &&
- b_engine.support_display_space_shader(b_scene);
- }
+ params.display_buffer_linear = GLEW_ARB_half_float_pixel &&
+ b_engine.support_display_space_shader(b_scene);
if(b_engine.is_preview()) {
/* For preview rendering we're using same timeout as
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 36bedc505af..1388e59f36d 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -51,6 +51,7 @@ class BlenderSync {
public:
BlenderSync(BL::RenderEngine& b_engine,
BL::BlendData& b_data,
+ BL::Depsgraph& b_graph,
BL::Scene& b_scene,
Scene *scene,
bool preview,
@@ -97,9 +98,8 @@ private:
/* sync */
void sync_lamps(bool update_all);
void sync_materials(bool update_all);
- void sync_objects(BL::SpaceView3D& b_v3d, float motion_time = 0.0f);
+ void sync_objects(float motion_time = 0.0f);
void sync_motion(BL::RenderSettings& b_render,
- BL::SpaceView3D& b_v3d,
BL::Object& b_override,
int width, int height,
void **python_thread_state);
@@ -156,6 +156,7 @@ private:
/* variables */
BL::RenderEngine b_engine;
BL::BlendData b_data;
+ BL::Depsgraph b_depsgraph;
BL::Scene b_scene;
id_map<void*, Shader> shader_map;
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);
+ glEnableVertexAttribArray(position_attribute);
+
+ glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if(vertex_buffer) {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+
+ if(use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+ glDeleteTextures(1, &texid);
+
+ if(transparent) {
glDisable(GL_BLEND);
+ }
}
Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 6051dd8b3eb..21d29a801ae 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -229,13 +229,26 @@ struct DeviceDrawParams {
class Device {
protected:
- Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), vertex_buffer(0), info(info_), stats(stats_) {}
+ enum {
+ FALLBACK_SHADER_STATUS_NONE = 0,
+ FALLBACK_SHADER_STATUS_ERROR,
+ FALLBACK_SHADER_STATUS_SUCCESS,
+ };
+
+ Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background),
+ vertex_buffer(0),
+ fallback_status(FALLBACK_SHADER_STATUS_NONE), fallback_shader_program(0),
+ info(info_), stats(stats_) {}
bool background;
string error_msg;
/* used for real time display */
unsigned int vertex_buffer;
+ int fallback_status, fallback_shader_program;
+ int image_texture_location, fullscreen_location;
+
+ bool bind_fallback_display_space_shader(const float width, const float height);
public:
virtual ~Device();
@@ -300,9 +313,10 @@ public:
virtual void task_cancel() = 0;
/* opengl drawing */
- virtual void draw_pixels(device_memory& mem, int y, int w, int h,
- int dx, int dy, int width, int height, bool transparent,
- const DeviceDrawParams &draw_params);
+ virtual void draw_pixels(device_memory& mem, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh,
+ bool transparent, const DeviceDrawParams &draw_params);
#ifdef WITH_NETWORK
/* networking */
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index a971170318e..e497ec6b0e1 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -1199,10 +1199,14 @@ public:
}
}
- void draw_pixels(device_memory& mem, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
+ void draw_pixels(
+ device_memory& mem, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh, bool transparent,
const DeviceDrawParams &draw_params)
{
if(!background) {
+ const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
PixelMem pmem = pixel_mem_map[mem.device_pointer];
float *vpointer;
@@ -1219,10 +1223,12 @@ public:
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
- if(mem.data_type == TYPE_HALF)
+ if(mem.data_type == TYPE_HALF) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_HALF_FLOAT, (void*)offset);
- else
+ }
+ else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)offset);
+ }
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glEnable(GL_TEXTURE_2D);
@@ -1232,14 +1238,21 @@ public:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
- glColor3f(1.0f, 1.0f, 1.0f);
-
- if(draw_params.bind_display_space_shader_cb) {
+ GLint shader_program;
+ if(use_fallback_shader) {
+ if(!bind_fallback_display_space_shader(dw, dh)) {
+ return;
+ }
+ shader_program = fallback_shader_program;
+ }
+ else {
draw_params.bind_display_space_shader_cb();
+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
}
- if(!vertex_buffer)
+ 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 */
@@ -1272,25 +1285,33 @@ public:
glUnmapBuffer(GL_ARRAY_BUFFER);
}
- glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
- glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)NULL + 2 * sizeof(float));
+ GLuint vertex_array_object;
+ GLuint position_attribute, texcoord_attribute;
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+ position_attribute = glGetAttribLocation(shader_program, "pos");
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- if(draw_params.unbind_display_space_shader_cb) {
+ if(use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
draw_params.unbind_display_space_shader_cb();
}
- if(transparent)
+ if(transparent) {
glDisable(GL_BLEND);
+ }
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
@@ -1300,7 +1321,7 @@ public:
return;
}
- Device::draw_pixels(mem, y, w, h, dx, dy, width, height, transparent, draw_params);
+ Device::draw_pixels(mem, y, w, h, width, height, dx, dy, dw, dh, transparent, draw_params);
}
void thread_run(DeviceTask *task)
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 624260a81c8..8616e31d3b9 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -254,8 +254,11 @@ public:
mem.device_pointer = tmp;
}
- void 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)
+ void 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)
{
device_ptr tmp = rgba.device_pointer;
int i = 0, sub_h = h/devices.size();
@@ -269,7 +272,7 @@ public:
/* adjust math for w/width */
rgba.device_pointer = sub.ptr_map[tmp];
- sub.device->draw_pixels(rgba, sy, w, sh, dx, sdy, width, sheight, transparent, draw_params);
+ sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, dx, sdy, dw, dh, transparent, draw_params);
i++;
}
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index fe2c2e78926..49934143ee9 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -371,7 +371,11 @@ void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
if(draw_width != 0 && draw_height != 0) {
device_memory& rgba = rgba_data();
- device->draw_pixels(rgba, 0, draw_width, draw_height, params.full_x, params.full_y, params.width, params.height, transparent, draw_params);
+ device->draw_pixels(
+ rgba, 0,
+ draw_width, draw_height, params.width, params.height,
+ params.full_x, params.full_y, params.full_width, params.full_height,
+ transparent, draw_params);
}
}
diff --git a/intern/cycles/util/util_opengl.h b/intern/cycles/util/util_opengl.h
index 0b5462e0a09..7a8d5eec1f9 100644
--- a/intern/cycles/util/util_opengl.h
+++ b/intern/cycles/util/util_opengl.h
@@ -20,12 +20,6 @@
/* OpenGL header includes, used everywhere we use OpenGL, to deal with
* platform differences in one central place. */
-#ifdef WITH_GLEW_MX
-# include "glew-mx.h"
-#else
-# include <GL/glew.h>
-# define mxCreateContext() glewInit()
-# define mxMakeCurrentContext(x) (x)
-#endif
+#include <GL/glew.h>
#endif /* __UTIL_OPENGL_H__ */
diff --git a/intern/cycles/util/util_view.cpp b/intern/cycles/util/util_view.cpp
index 10d86167921..7b453d123b8 100644
--- a/intern/cycles/util/util_view.cpp
+++ b/intern/cycles/util/util_view.cpp
@@ -252,7 +252,7 @@ void view_main_loop(const char *title, int width, int height,
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow(title);
- mxMakeCurrentContext(mxCreateContext());
+ glewInit();
view_reshape(width, height);