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/hydra/display_driver.cpp')
-rw-r--r--intern/cycles/hydra/display_driver.cpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/intern/cycles/hydra/display_driver.cpp b/intern/cycles/hydra/display_driver.cpp
new file mode 100644
index 00000000000..6f6ca35cd31
--- /dev/null
+++ b/intern/cycles/hydra/display_driver.cpp
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2022 NVIDIA Corporation
+ * Copyright 2022 Blender Foundation */
+
+#ifdef _WIN32
+// Include first to avoid "NOGDI" definition set in Cycles headers
+# include <Windows.h>
+#endif
+
+#include "hydra/display_driver.h"
+#include "hydra/render_buffer.h"
+#include "hydra/session.h"
+
+#include <GL/glew.h>
+#include <pxr/imaging/hgiGL/texture.h>
+
+HDCYCLES_NAMESPACE_OPEN_SCOPE
+
+HdCyclesDisplayDriver::HdCyclesDisplayDriver(HdCyclesSession *renderParam, Hgi *hgi)
+ : _renderParam(renderParam), _hgi(hgi)
+{
+#ifdef _WIN32
+ hdc_ = GetDC(CreateWindowA("STATIC",
+ "HdCycles",
+ WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ 0,
+ 0,
+ 64,
+ 64,
+ NULL,
+ NULL,
+ GetModuleHandle(NULL),
+ NULL));
+
+ int pixelFormat = GetPixelFormat(wglGetCurrentDC());
+ PIXELFORMATDESCRIPTOR pfd = {sizeof(pfd)};
+ DescribePixelFormat((HDC)hdc_, pixelFormat, sizeof(pfd), &pfd);
+ SetPixelFormat((HDC)hdc_, pixelFormat, &pfd);
+
+ TF_VERIFY(gl_context_ = wglCreateContext((HDC)hdc_));
+ TF_VERIFY(wglShareLists(wglGetCurrentContext(), (HGLRC)gl_context_));
+#endif
+
+ glewInit();
+
+ glGenBuffers(1, &gl_pbo_id_);
+}
+
+HdCyclesDisplayDriver::~HdCyclesDisplayDriver()
+{
+ if (texture_) {
+ _hgi->DestroyTexture(&texture_);
+ }
+
+ glDeleteBuffers(1, &gl_pbo_id_);
+
+#ifdef _WIN32
+ TF_VERIFY(wglDeleteContext((HGLRC)gl_context_));
+ DestroyWindow(WindowFromDC((HDC)hdc_));
+#endif
+}
+
+void HdCyclesDisplayDriver::next_tile_begin()
+{
+}
+
+bool HdCyclesDisplayDriver::update_begin(const Params &params,
+ int texture_width,
+ int texture_height)
+{
+#ifdef _WIN32
+ if (!hdc_ || !gl_context_) {
+ return false;
+ }
+#endif
+
+ graphics_interop_activate();
+
+ if (gl_render_sync_) {
+ glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
+ }
+
+ if (pbo_size_.x != params.full_size.x || pbo_size_.y != params.full_size.y) {
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_pbo_id_);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER,
+ sizeof(half4) * params.full_size.x * params.full_size.y,
+ 0,
+ GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ pbo_size_ = params.full_size;
+ }
+
+ need_update_ = true;
+
+ return true;
+}
+
+void HdCyclesDisplayDriver::update_end()
+{
+ gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+
+ glFlush();
+
+ graphics_interop_deactivate();
+}
+
+void HdCyclesDisplayDriver::flush()
+{
+ graphics_interop_activate();
+
+ if (gl_upload_sync_) {
+ glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
+ }
+
+ if (gl_render_sync_) {
+ glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
+ }
+
+ graphics_interop_deactivate();
+}
+
+half4 *HdCyclesDisplayDriver::map_texture_buffer()
+{
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_pbo_id_);
+
+ const auto mapped_rgba_pixels = static_cast<half4 *>(
+ glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
+
+ if (need_clear_ && mapped_rgba_pixels) {
+ memset(mapped_rgba_pixels, 0, sizeof(half4) * pbo_size_.x * pbo_size_.y);
+ need_clear_ = false;
+ }
+
+ return mapped_rgba_pixels;
+}
+
+void HdCyclesDisplayDriver::unmap_texture_buffer()
+{
+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+}
+
+DisplayDriver::GraphicsInterop HdCyclesDisplayDriver::graphics_interop_get()
+{
+ GraphicsInterop interop_dst;
+ interop_dst.buffer_width = pbo_size_.x;
+ interop_dst.buffer_height = pbo_size_.y;
+ interop_dst.opengl_pbo_id = gl_pbo_id_;
+
+ interop_dst.need_clear = need_clear_;
+ need_clear_ = false;
+
+ return interop_dst;
+}
+
+void HdCyclesDisplayDriver::graphics_interop_activate()
+{
+ mutex_.lock();
+
+#ifdef _WIN32
+ // Do not change context if this is called in the main thread
+ if (wglGetCurrentContext() == nullptr) {
+ TF_VERIFY(wglMakeCurrent((HDC)hdc_, (HGLRC)gl_context_));
+ }
+#endif
+}
+
+void HdCyclesDisplayDriver::graphics_interop_deactivate()
+{
+#ifdef _WIN32
+ if (wglGetCurrentContext() == gl_context_) {
+ TF_VERIFY(wglMakeCurrent(nullptr, nullptr));
+ }
+#endif
+
+ mutex_.unlock();
+}
+
+void HdCyclesDisplayDriver::clear()
+{
+ need_clear_ = true;
+}
+
+void HdCyclesDisplayDriver::draw(const Params &params)
+{
+ const auto renderBuffer = static_cast<HdCyclesRenderBuffer *>(
+ _renderParam->GetDisplayAovBinding().renderBuffer);
+ if (!renderBuffer || // Ensure this render buffer matches the texture dimensions
+ (renderBuffer->GetWidth() != params.size.x || renderBuffer->GetHeight() != params.size.y)) {
+ return;
+ }
+
+ // Cycles 'DisplayDriver' only supports 'half4' format
+ TF_VERIFY(renderBuffer->GetFormat() == HdFormatFloat16Vec4);
+
+ const thread_scoped_lock lock(mutex_);
+
+ const GfVec3i dimensions(params.size.x, params.size.y, 1);
+ if (!texture_ || texture_->GetDescriptor().dimensions != dimensions) {
+ if (texture_) {
+ _hgi->DestroyTexture(&texture_);
+ }
+
+ HgiTextureDesc texDesc;
+ texDesc.usage = 0;
+ texDesc.format = HgiFormatFloat16Vec4;
+ texDesc.type = HgiTextureType2D;
+ texDesc.dimensions = dimensions;
+ texDesc.sampleCount = HgiSampleCount1;
+
+ texture_ = _hgi->CreateTexture(texDesc);
+
+ renderBuffer->SetResource(VtValue(texture_));
+ }
+
+ HgiGLTexture *const texture = dynamic_cast<HgiGLTexture *>(texture_.Get());
+ if (!texture || !need_update_ || pbo_size_.x != params.size.x || pbo_size_.y != params.size.y) {
+ return;
+ }
+
+ if (gl_upload_sync_) {
+ glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
+ }
+
+ glBindTexture(GL_TEXTURE_2D, texture->GetTextureId());
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_pbo_id_);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pbo_size_.x, pbo_size_.y, GL_RGBA, GL_HALF_FLOAT, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+
+ glFlush();
+
+ need_update_ = false;
+}
+
+HDCYCLES_NAMESPACE_CLOSE_SCOPE