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:
authorBrecht Van Lommel <brecht@blender.org>2021-09-14 16:37:47 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-09-30 21:48:08 +0300
commita754e35198d852ea34e2b82cd2b126538e6f5a3b (patch)
tree9118b3fa19ab70aa1b50440ce62e5d028d940cfd /intern/cycles/blender
parentac582056e2e70f3b0d91ff69d0307dd357e2e2ed (diff)
Cycles: refactor API for GPU display
* Split GPUDisplay into two classes. PathTraceDisplay to implement the Cycles side, and DisplayDriver to implement the host application side. The DisplayDriver is now a fully abstract base class, embedded in the PathTraceDisplay. * Move copy_pixels_to_texture implementation out of the host side into the Cycles side, since it can be implemented in terms of the texture buffer mapping. * Move definition of DeviceGraphicsInteropDestination into display driver header, so that we do not need to expose private device headers in the public API. * Add more detailed comments about how the DisplayDriver should be implemented. The "driver" terminology might not be obvious, but is also used in other renderers. Differential Revision: https://developer.blender.org/D12626
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/CMakeLists.txt4
-rw-r--r--intern/cycles/blender/blender_display_driver.cpp (renamed from intern/cycles/blender/blender_gpu_display.cpp)107
-rw-r--r--intern/cycles/blender/blender_display_driver.h (renamed from intern/cycles/blender/blender_gpu_display.h)37
-rw-r--r--intern/cycles/blender/blender_session.cpp15
-rw-r--r--intern/cycles/blender/blender_session.h6
5 files changed, 64 insertions, 105 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 64d226cb9ec..2660eee017b 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -31,9 +31,9 @@ set(INC_SYS
set(SRC
blender_camera.cpp
blender_device.cpp
+ blender_display_driver.cpp
blender_image.cpp
blender_geometry.cpp
- blender_gpu_display.cpp
blender_light.cpp
blender_mesh.cpp
blender_object.cpp
@@ -51,7 +51,7 @@ set(SRC
CCL_api.h
blender_device.h
- blender_gpu_display.h
+ blender_display_driver.h
blender_id_map.h
blender_image.h
blender_object_cull.h
diff --git a/intern/cycles/blender/blender_gpu_display.cpp b/intern/cycles/blender/blender_display_driver.cpp
index 5a4567deac3..5267f41eef7 100644
--- a/intern/cycles/blender/blender_gpu_display.cpp
+++ b/intern/cycles/blender/blender_display_driver.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "blender/blender_gpu_display.h"
+#include "blender/blender_display_driver.h"
#include "device/device.h"
#include "util/util_logging.h"
@@ -273,17 +273,17 @@ uint BlenderDisplaySpaceShader::get_shader_program()
}
/* --------------------------------------------------------------------
- * BlenderGPUDisplay.
+ * BlenderDisplayDriver.
*/
-BlenderGPUDisplay::BlenderGPUDisplay(BL::RenderEngine &b_engine, BL::Scene &b_scene)
+BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
: b_engine_(b_engine), display_shader_(BlenderDisplayShader::create(b_engine, b_scene))
{
/* Create context while on the main thread. */
gl_context_create();
}
-BlenderGPUDisplay::~BlenderGPUDisplay()
+BlenderDisplayDriver::~BlenderDisplayDriver()
{
gl_resources_destroy();
}
@@ -292,19 +292,18 @@ BlenderGPUDisplay::~BlenderGPUDisplay()
* Update procedure.
*/
-bool BlenderGPUDisplay::do_update_begin(const GPUDisplayParams &params,
+bool BlenderDisplayDriver::update_begin(const Params &params,
int texture_width,
int texture_height)
{
- /* Note that it's the responsibility of BlenderGPUDisplay to ensure updating and drawing
+ /* Note that it's the responsibility of BlenderDisplayDriver to ensure updating and drawing
* the texture does not happen at the same time. This is achieved indirectly.
*
* When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
* This same lock is also held when do_draw() is called, which together ensure mutual
* exclusion.
*
- * This locking is not performed at the GPU display level, because that would cause lock
- * inversion. */
+ * This locking is not performed on the Cycles side, because that would cause lock inversion. */
if (!gl_context_enable()) {
return false;
}
@@ -361,7 +360,7 @@ bool BlenderGPUDisplay::do_update_begin(const GPUDisplayParams &params,
return true;
}
-void BlenderGPUDisplay::do_update_end()
+void BlenderDisplayDriver::update_end()
{
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
@@ -370,53 +369,17 @@ void BlenderGPUDisplay::do_update_end()
}
/* --------------------------------------------------------------------
- * Texture update from CPU buffer.
- */
-
-void BlenderGPUDisplay::do_copy_pixels_to_texture(
- const half4 *rgba_pixels, int texture_x, int texture_y, int pixels_width, int pixels_height)
-{
- /* This call copies pixels to a Pixel Buffer Object (PBO) which is much cheaper from CPU time
- * point of view than to copy data directly to the OpenGL texture.
- *
- * The possible downside of this approach is that it might require a higher peak memory when
- * doing partial updates of the texture (although, in practice even partial updates might peak
- * with a full-frame buffer stored on the CPU if the GPU is currently occupied). */
-
- half4 *mapped_rgba_pixels = map_texture_buffer();
- if (!mapped_rgba_pixels) {
- return;
- }
-
- if (texture_x == 0 && texture_y == 0 && pixels_width == texture_.width &&
- pixels_height == texture_.height) {
- const size_t size_in_bytes = sizeof(half4) * texture_.width * texture_.height;
- memcpy(mapped_rgba_pixels, rgba_pixels, size_in_bytes);
- }
- else {
- const half4 *rgba_row = rgba_pixels;
- half4 *mapped_rgba_row = mapped_rgba_pixels + texture_y * texture_.width + texture_x;
- for (int y = 0; y < pixels_height;
- ++y, rgba_row += pixels_width, mapped_rgba_row += texture_.width) {
- memcpy(mapped_rgba_row, rgba_row, sizeof(half4) * pixels_width);
- }
- }
-
- unmap_texture_buffer();
-}
-
-/* --------------------------------------------------------------------
* Texture buffer mapping.
*/
-half4 *BlenderGPUDisplay::do_map_texture_buffer()
+half4 *BlenderDisplayDriver::map_texture_buffer()
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>(
glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
if (!mapped_rgba_pixels) {
- LOG(ERROR) << "Error mapping BlenderGPUDisplay pixel buffer object.";
+ LOG(ERROR) << "Error mapping BlenderDisplayDriver pixel buffer object.";
}
if (texture_.need_clear) {
@@ -431,7 +394,7 @@ half4 *BlenderGPUDisplay::do_map_texture_buffer()
return mapped_rgba_pixels;
}
-void BlenderGPUDisplay::do_unmap_texture_buffer()
+void BlenderDisplayDriver::unmap_texture_buffer()
{
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -442,9 +405,9 @@ void BlenderGPUDisplay::do_unmap_texture_buffer()
* Graphics interoperability.
*/
-DeviceGraphicsInteropDestination BlenderGPUDisplay::do_graphics_interop_get()
+BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get()
{
- DeviceGraphicsInteropDestination interop_dst;
+ GraphicsInterop interop_dst;
interop_dst.buffer_width = texture_.buffer_width;
interop_dst.buffer_height = texture_.buffer_height;
@@ -456,12 +419,12 @@ DeviceGraphicsInteropDestination BlenderGPUDisplay::do_graphics_interop_get()
return interop_dst;
}
-void BlenderGPUDisplay::graphics_interop_activate()
+void BlenderDisplayDriver::graphics_interop_activate()
{
gl_context_enable();
}
-void BlenderGPUDisplay::graphics_interop_deactivate()
+void BlenderDisplayDriver::graphics_interop_deactivate()
{
gl_context_disable();
}
@@ -470,17 +433,17 @@ void BlenderGPUDisplay::graphics_interop_deactivate()
* Drawing.
*/
-void BlenderGPUDisplay::clear()
+void BlenderDisplayDriver::clear()
{
texture_.need_clear = true;
}
-void BlenderGPUDisplay::set_zoom(float zoom_x, float zoom_y)
+void BlenderDisplayDriver::set_zoom(float zoom_x, float zoom_y)
{
zoom_ = make_float2(zoom_x, zoom_y);
}
-void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
+void BlenderDisplayDriver::draw(const Params &params)
{
/* See do_update_begin() for why no locking is required here. */
const bool transparent = true; // TODO(sergey): Derive this from Film.
@@ -584,7 +547,7 @@ void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
}
}
-void BlenderGPUDisplay::gl_context_create()
+void BlenderDisplayDriver::gl_context_create()
{
/* When rendering in viewport there is no render context available via engine.
* Check whether own context is to be created here.
@@ -613,7 +576,7 @@ void BlenderGPUDisplay::gl_context_create()
}
}
-bool BlenderGPUDisplay::gl_context_enable()
+bool BlenderDisplayDriver::gl_context_enable()
{
if (use_gl_context_) {
if (!gl_context_) {
@@ -628,7 +591,7 @@ bool BlenderGPUDisplay::gl_context_enable()
return true;
}
-void BlenderGPUDisplay::gl_context_disable()
+void BlenderDisplayDriver::gl_context_disable()
{
if (use_gl_context_) {
if (gl_context_) {
@@ -641,7 +604,7 @@ void BlenderGPUDisplay::gl_context_disable()
RE_engine_render_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
}
-void BlenderGPUDisplay::gl_context_dispose()
+void BlenderDisplayDriver::gl_context_dispose()
{
if (gl_context_) {
const bool drw_state = DRW_opengl_context_release();
@@ -653,7 +616,7 @@ void BlenderGPUDisplay::gl_context_dispose()
}
}
-bool BlenderGPUDisplay::gl_draw_resources_ensure()
+bool BlenderDisplayDriver::gl_draw_resources_ensure()
{
if (!texture_.gl_id) {
/* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can
@@ -680,7 +643,7 @@ bool BlenderGPUDisplay::gl_draw_resources_ensure()
return true;
}
-void BlenderGPUDisplay::gl_resources_destroy()
+void BlenderDisplayDriver::gl_resources_destroy()
{
gl_context_enable();
@@ -703,7 +666,7 @@ void BlenderGPUDisplay::gl_resources_destroy()
gl_context_dispose();
}
-bool BlenderGPUDisplay::gl_texture_resources_ensure()
+bool BlenderDisplayDriver::gl_texture_resources_ensure()
{
if (texture_.creation_attempted) {
return texture_.is_created;
@@ -740,7 +703,7 @@ bool BlenderGPUDisplay::gl_texture_resources_ensure()
return true;
}
-void BlenderGPUDisplay::texture_update_if_needed()
+void BlenderDisplayDriver::texture_update_if_needed()
{
if (!texture_.need_update) {
return;
@@ -754,7 +717,7 @@ void BlenderGPUDisplay::texture_update_if_needed()
texture_.need_update = false;
}
-void BlenderGPUDisplay::vertex_buffer_update(const GPUDisplayParams &params)
+void BlenderDisplayDriver::vertex_buffer_update(const Params &params)
{
/* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
* rendered. */
@@ -767,23 +730,23 @@ void BlenderGPUDisplay::vertex_buffer_update(const GPUDisplayParams &params)
vpointer[0] = 0.0f;
vpointer[1] = 0.0f;
- vpointer[2] = params.offset.x;
- vpointer[3] = params.offset.y;
+ vpointer[2] = params.full_offset.x;
+ vpointer[3] = params.full_offset.y;
vpointer[4] = 1.0f;
vpointer[5] = 0.0f;
- vpointer[6] = (float)params.size.x + params.offset.x;
- vpointer[7] = params.offset.y;
+ vpointer[6] = (float)params.size.x + params.full_offset.x;
+ vpointer[7] = params.full_offset.y;
vpointer[8] = 1.0f;
vpointer[9] = 1.0f;
- vpointer[10] = (float)params.size.x + params.offset.x;
- vpointer[11] = (float)params.size.y + params.offset.y;
+ vpointer[10] = (float)params.size.x + params.full_offset.x;
+ vpointer[11] = (float)params.size.y + params.full_offset.y;
vpointer[12] = 0.0f;
vpointer[13] = 1.0f;
- vpointer[14] = params.offset.x;
- vpointer[15] = (float)params.size.y + params.offset.y;
+ vpointer[14] = params.full_offset.x;
+ vpointer[15] = (float)params.size.y + params.full_offset.y;
glUnmapBuffer(GL_ARRAY_BUFFER);
}
diff --git a/intern/cycles/blender/blender_gpu_display.h b/intern/cycles/blender/blender_display_driver.h
index 89420567037..558997c6b4f 100644
--- a/intern/cycles/blender/blender_gpu_display.h
+++ b/intern/cycles/blender/blender_display_driver.h
@@ -22,12 +22,14 @@
#include "RNA_blender_cpp.h"
-#include "render/gpu_display.h"
+#include "render/display_driver.h"
+
+#include "util/util_thread.h"
#include "util/util_unique_ptr.h"
CCL_NAMESPACE_BEGIN
-/* Base class of shader used for GPU display rendering. */
+/* Base class of shader used for display driver rendering. */
class BlenderDisplayShader {
public:
static constexpr const char *position_attribute_name = "pos";
@@ -96,11 +98,11 @@ class BlenderDisplaySpaceShader : public BlenderDisplayShader {
uint shader_program_ = 0;
};
-/* GPU display implementation which is specific for Blender viewport integration. */
-class BlenderGPUDisplay : public GPUDisplay {
+/* Display driver implementation which is specific for Blender viewport integration. */
+class BlenderDisplayDriver : public DisplayDriver {
public:
- BlenderGPUDisplay(BL::RenderEngine &b_engine, BL::Scene &b_scene);
- ~BlenderGPUDisplay();
+ BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene);
+ ~BlenderDisplayDriver();
virtual void graphics_interop_activate() override;
virtual void graphics_interop_deactivate() override;
@@ -110,22 +112,15 @@ class BlenderGPUDisplay : public GPUDisplay {
void set_zoom(float zoom_x, float zoom_y);
protected:
- virtual bool do_update_begin(const GPUDisplayParams &params,
- int texture_width,
- int texture_height) override;
- virtual void do_update_end() override;
+ virtual bool update_begin(const Params &params, int texture_width, int texture_height) override;
+ virtual void update_end() override;
- virtual void do_copy_pixels_to_texture(const half4 *rgba_pixels,
- int texture_x,
- int texture_y,
- int pixels_width,
- int pixels_height) override;
- virtual void do_draw(const GPUDisplayParams &params) override;
+ virtual half4 *map_texture_buffer() override;
+ virtual void unmap_texture_buffer() override;
- virtual half4 *do_map_texture_buffer() override;
- virtual void do_unmap_texture_buffer() override;
+ virtual GraphicsInterop graphics_interop_get() override;
- virtual DeviceGraphicsInteropDestination do_graphics_interop_get() override;
+ virtual void draw(const Params &params) override;
/* Helper function which allocates new GPU context. */
void gl_context_create();
@@ -152,13 +147,13 @@ class BlenderGPUDisplay : public GPUDisplay {
* This buffer is used to render texture in the viewport.
*
* NOTE: The buffer needs to be bound. */
- void vertex_buffer_update(const GPUDisplayParams &params);
+ void vertex_buffer_update(const Params &params);
BL::RenderEngine b_engine_;
/* OpenGL context which is used the render engine doesn't have its own. */
void *gl_context_ = nullptr;
- /* The when Blender RenderEngine side context is not available and the GPUDisplay is to create
+ /* The when Blender RenderEngine side context is not available and the DisplayDriver is to create
* its own context. */
bool use_gl_context_ = false;
/* Mutex used to guard the `gl_context_`. */
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 88edc7eafe7..1a42456eda0 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -42,7 +42,7 @@
#include "util/util_progress.h"
#include "util/util_time.h"
-#include "blender/blender_gpu_display.h"
+#include "blender/blender_display_driver.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_util.h"
@@ -159,9 +159,10 @@ void BlenderSession::create_session()
/* Create GPU display. */
if (!b_engine.is_preview() && !headless) {
- unique_ptr<BlenderGPUDisplay> gpu_display = make_unique<BlenderGPUDisplay>(b_engine, b_scene);
- gpu_display_ = gpu_display.get();
- session->set_gpu_display(move(gpu_display));
+ unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(b_engine,
+ b_scene);
+ display_driver_ = display_driver.get();
+ session->set_display_driver(move(display_driver));
}
/* Viewport and preview (as in, material preview) does not do tiled rendering, so can inform
@@ -446,7 +447,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
/* Use final write for preview renders, otherwise render result wouldn't be be updated on Blender
* side. */
- /* TODO(sergey): Investigate whether GPUDisplay can be used for the preview as well. */
+ /* TODO(sergey): Investigate whether DisplayDriver can be used for the preview as well. */
if (b_engine.is_preview()) {
session->update_render_tile_cb = [&]() { write_render_tile(); };
}
@@ -708,7 +709,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
session->read_render_tile_cb = [&]() { read_render_tile(); };
session->write_render_tile_cb = [&]() { write_render_tile(); };
- session->set_gpu_display(nullptr);
+ session->set_display_driver(nullptr);
if (!session->progress.get_cancel()) {
/* Sync scene. */
@@ -895,7 +896,7 @@ void BlenderSession::draw(BL::SpaceImageEditor &space_image)
}
BL::Array<float, 2> zoom = space_image.zoom();
- gpu_display_->set_zoom(zoom[0], zoom[1]);
+ display_driver_->set_zoom(zoom[0], zoom[1]);
session->draw();
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 58683ee07a1..1ca8fdf87d0 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -29,7 +29,7 @@
CCL_NAMESPACE_BEGIN
-class BlenderGPUDisplay;
+class BlenderDisplayDriver;
class BlenderSync;
class ImageMetaData;
class Scene;
@@ -164,8 +164,8 @@ class BlenderSession {
int last_pass_index = -1;
} draw_state_;
- /* NOTE: The BlenderSession references the GPU display. */
- BlenderGPUDisplay *gpu_display_ = nullptr;
+ /* NOTE: The BlenderSession references the display driver. */
+ BlenderDisplayDriver *display_driver_ = nullptr;
vector<string> full_buffer_files_;
};