From 6a47b05ab8f63d52c261afcb96bc96b889e04453 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 14 Feb 2020 02:13:38 +1100 Subject: [PATCH] work on oslworker --- app/config/config.cpp | 2 +- app/core.cpp | 1 + app/render/backend/osl/oslbackend.cpp | 9 +- app/render/backend/osl/oslworker.cpp | 142 +++++++++++++++++--------- app/render/backend/osl/oslworker.h | 5 + app/shaders/videoinput.frag | 12 ++- app/widget/viewer/viewer.cpp | 4 +- app/widget/viewer/viewer.h | 4 +- 8 files changed, 119 insertions(+), 60 deletions(-) diff --git a/app/config/config.cpp b/app/config/config.cpp index a0b0abc8b..cf866dcfd 100644 --- a/app/config/config.cpp +++ b/app/config/config.cpp @@ -90,7 +90,7 @@ void Config::SetDefaults() // Online/offline settings config_map_["OnlinePixelFormat"] = PixelFormat::PIX_FMT_RGBA32F; - config_map_["OfflinePixelFormat"] = PixelFormat::PIX_FMT_RGBA16F; + config_map_["OfflinePixelFormat"] = PixelFormat::PIX_FMT_RGBA32F; config_map_["OnlineSampleFormat"] = SampleFormat::SAMPLE_FMT_FLT; config_map_["OfflineSampleFormat"] = SampleFormat::SAMPLE_FMT_FLT; config_map_["OnlineOCIOMethod"] = ColorManager::kOCIOAccurate; diff --git a/app/core.cpp b/app/core.cpp index d15741d82..f948c9f6d 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -46,6 +46,7 @@ #include "project/projectsavemanager.h" #include "project/item/footage/footage.h" #include "project/item/sequence/sequence.h" +#include "render/backend/opengl/opengltexturecache.h" #include "render/colormanager.h" #include "render/diskmanager.h" #include "render/pixelservice.h" diff --git a/app/render/backend/osl/oslbackend.cpp b/app/render/backend/osl/oslbackend.cpp index 58a8afa7d..0771ad699 100644 --- a/app/render/backend/osl/oslbackend.cpp +++ b/app/render/backend/osl/oslbackend.cpp @@ -65,21 +65,24 @@ bool OSLBackend::CompileInternal() foreach (Node* n, deps) { if (!shader_cache_.Has(n->id())) { if (n->IsAccelerated()) { - // FIXME: Compile here std::string oso_buffer; + QString function_name = n->id().replace('.', '_'); + if (!compiler.compile_buffer(n->AcceleratedCodeFragment().toStdString(), oso_buffer, std::vector(), "", - n->id().toStdString())) { + function_name.toStdString())) { qWarning() << "Failed to compile" << n->id(); return false; } + system->LoadMemoryCompiledShader(function_name.toStdString(), oso_buffer); + OSL::ShaderGroupRef ref = system->ShaderGroupBegin(n->id().toStdString()); - system->Shader("surface", n->id().toStdString(), "layer1"); + system->Shader("shader", function_name.toStdString(), "layer1"); system->ShaderGroupEnd(); shader_cache_.Add(n->id(), ref); diff --git a/app/render/backend/osl/oslworker.cpp b/app/render/backend/osl/oslworker.cpp index e76446153..99b402592 100644 --- a/app/render/backend/osl/oslworker.cpp +++ b/app/render/backend/osl/oslworker.cpp @@ -7,6 +7,7 @@ #include #include "common/clamp.h" +#include "common/define.h" #include "core.h" #include "node/block/transition/transition.h" #include "node/node.h" @@ -45,16 +46,16 @@ void OSLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable *t color_cache_->Add(video_stream->colorspace(), color_processor); } + // Convert frame to float for OCIO + if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) { + frame = PixelService::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F); + } + // If alpha is associated, disassociate for the color transform if (video_stream->premultiplied_alpha()) { ColorManager::DisassociateAlpha(frame); } - // Convert frame to float for OCIO - if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) { - frame = PixelService::ConvertPixelFormat(frame, frame->format()); - } - // Perform color transform color_processor->ConvertFrame(frame); @@ -65,17 +66,15 @@ void OSLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable *t ColorManager::AssociateAlpha(frame); } - table->Push(NodeParam::kTexture, QVariant::fromValue(frame)); + OIIOImageBufRef buf = std::make_shared(OIIO::ImageSpec(frame->width(), frame->height(), kRGBAChannels, OIIO::TypeDesc::FLOAT)); + + memcpy(buf->localpixels(), frame->data(), frame->allocated_size()); + + table->Push(NodeParam::kTexture, QVariant::fromValue(buf)); } void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable *output_params) { - Q_UNUSED(node) - Q_UNUSED(range) - Q_UNUSED(input_params) - Q_UNUSED(output_params) - - /* if (!node->IsAccelerated()) { return; } @@ -86,15 +85,10 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con return; } - // Create the output textures - QList dst_refs; - dst_refs.append(texture_cache_.Get(ctx_, video_params_)); - GLuint iterative_input = 0; + int input_texture_count = 0; - // If this node requires multiple iterations, get a texture for it too - if (node->AcceleratedCodeIterations() > 1 && node->AcceleratedCodeIterativeInput()) { - dst_refs.append(texture_cache_.Get(ctx_, video_params_)); - } + OIIOImageBufRef iteration_buf = nullptr; + int iteration_id = -1; foreach (NodeParam* param, node->parameters()) { if (param->type() == NodeParam::kInput) { @@ -160,16 +154,39 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con case NodeInput::kTexture: case NodeInput::kBuffer: { - OpenGLTextureCache::ReferencePtr texture = value.value(); + OIIOImageBufRef buf = value.value(); - functions_->glActiveTexture(GL_TEXTURE0 + input_texture_count); + if (buf) { - GLuint tex_id = texture ? texture->texture()->texture() : 0; - functions_->glBindTexture(GL_TEXTURE_2D, tex_id); + QString tex_fn = ImageBufToTexture(*buf.get(), input_texture_count); - // Set value to bound texture - shader->setUniformValue(variable_location, input_texture_count); + if (!tex_fn.isEmpty()) { + QByteArray tex_fn_bytes = tex_fn.toUtf8(); + const char* tex_fn_c_str = tex_fn_bytes.constData(); + if (!shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc::STRING, &tex_fn_c_str)) { + qDebug() << "Failed to set string parameter"; + } + } + + } else { + + shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc::STRING, nullptr); + + } + + if (node->AcceleratedCodeIterativeInput() == input) { + iteration_buf = buf; + + iteration_id = input_texture_count; + } + + + + + + + /* // Set enable flag if shader wants it int enable_param_location = shader->uniformLocation(QStringLiteral("%1_enabled").arg(input->id())); if (enable_param_location > -1) { @@ -187,12 +204,10 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con } } - // If this texture binding is the iterative input, set it here - if (input == node->AcceleratedCodeIterativeInput()) { - iterative_input = input_texture_count; - } + OpenGLRenderFunctions::PrepareToDraw(functions_); + */ input_texture_count++; break; @@ -253,14 +268,10 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con &p); } + OIIOImageBufRef dest_buf = nullptr; + // Some nodes use multiple iterations for optimization - OpenGLTextureCache::ReferencePtr output_tex; - for (int iteration=0;iterationAcceleratedCodeIterations();iteration++) { - // If this is not the first iteration, set the parameter that will receive the last iteration's texture - OpenGLTextureCache::ReferencePtr source_tex = dst_refs.at((iteration+1)%dst_refs.size()); - OpenGLTextureCache::ReferencePtr destination_tex = dst_refs.at(iteration%dst_refs.size()); - // Set iteration number shading_system_->ReParameter(*group.get(), "layer1", @@ -269,13 +280,28 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con &iteration); if (iteration > 0) { - functions_->glActiveTexture(GL_TEXTURE0 + iterative_input); - functions_->glBindTexture(GL_TEXTURE_2D, source_tex->texture()->texture()); + // Convert destination buffer into texture + QString s = ImageBufToTexture(*dest_buf.get(), iteration_id); + + QByteArray s_bytes = s.toUtf8(); + const char* s_c_str = s_bytes.constData(); + + // Set texture as iterative input + shading_system_->ReParameter(*group.get(), "layer1", node->AcceleratedCodeIterativeInput()->id().toStdString(), OIIO::TypeDesc::STRING, &s_c_str); + + // Swap destination buffer and iteration buffer + std::swap(iteration_buf, dest_buf); } - destination_tex->texture(); // DESTINATION TEXTURE + // Ensure dest_buf exists + if (!dest_buf) { + dest_buf = std::make_shared(OIIO::ImageSpec(video_params().width(), + video_params().height(), + kRGBAChannels, + PixelService::GetPixelFormatInfo(video_params().format()).oiio_desc)); + } - static OIIO::array_view outputs = {OSL::ustring("Cout")}; + static OSL::ustring outputs[] = {OSL::ustring("Cout")}; OIIO::ImageBufAlgo::parallel_image_options popt; #if OPENIMAGEIO_VERSION > 10902 @@ -284,28 +310,44 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con popt.recursive = true; #endif - OIIO::ImageBuf buffer; - shade_image(*shading_system_, *group.get(), nullptr, - buffer, + *dest_buf.get(), outputs, OSL::ShadePixelCenters, OIIO::ROI(), popt); - - // Update output reference to the last texture we wrote to - output_tex = destination_tex; } - output_params->Push(NodeParam::kTexture, QVariant::fromValue(output_tex)); - */ + output_params->Push(NodeParam::kTexture, QVariant::fromValue(dest_buf)); } void OSLWorker::TextureToBuffer(const QVariant &tex_in, QByteArray &buffer) { - FramePtr frame = tex_in.value(); + OIIOImageBufRef frame = tex_in.value(); - memcpy(buffer.data(), frame->data(), static_cast(buffer.size())); + memcpy(buffer.data(), frame->localpixels(), static_cast(buffer.size())); +} + +QString OSLWorker::ImageBufToTexture(const OpenImageIO_v2_1::ImageBuf &buf, int tex_no) +{ + OIIO::ImageSpec config; + config.attribute("maketx:filtername", "lanczos3"); + + QString tex_fn = QStringLiteral("C:/Users/Matt/Desktop/temp-%1-%2.tx").arg(QString::number(reinterpret_cast(this)), QString::number(tex_no)); + + stringstream s; + + if (!OIIO::ImageBufAlgo::make_texture(OIIO::ImageBufAlgo::MakeTextureMode::MakeTxTexture, + buf, + tex_fn.toStdString(), + config, + &s)) { + qCritical() << "Failed to make_texture:" << s.str().c_str(); + + return QString(); + } + + return tex_fn; } diff --git a/app/render/backend/osl/oslworker.h b/app/render/backend/osl/oslworker.h index 2edd33be6..3407b7a6d 100644 --- a/app/render/backend/osl/oslworker.h +++ b/app/render/backend/osl/oslworker.h @@ -25,6 +25,8 @@ protected: virtual void TextureToBuffer(const QVariant& texture, QByteArray& buffer) override; private: + QString ImageBufToTexture(const OIIO::ImageBuf& buffer, int tex_no); + OSL::ShadingSystem* shading_system_; OSLShaderCache* shader_cache_; @@ -33,4 +35,7 @@ private: }; +using OIIOImageBufRef = std::shared_ptr; +Q_DECLARE_METATYPE(OIIOImageBufRef) + #endif // OSLWORKER_H diff --git a/app/shaders/videoinput.frag b/app/shaders/videoinput.frag index 7e7f15b4f..b63e5ef67 100644 --- a/app/shaders/videoinput.frag +++ b/app/shaders/videoinput.frag @@ -1,8 +1,16 @@ -#version 110 +shader videoinput(string footage_in = "" [[ int lockgeom=0 ]], + float s = u [[ int lockgeom=0 ]], + float t = v [[ int lockgeom=0 ]], + output color Cout = 0) +{ + Cout = texture (footage_in, s, t); +} + +/*#version 110 varying vec2 ove_texcoord; uniform sampler2D footage_in; void main(void) { gl_FragColor = texture2D(footage_in, ove_texcoord); -} +}*/ diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 51ba928bb..55cd5338d 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -82,7 +82,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) : SetScale(48.0); // Start background renderers - video_renderer_ = new OpenGLBackend(this); + video_renderer_ = new OSLBackend(this); connect(video_renderer_, &VideoRenderBackend::CachedFrameReady, this, &ViewerWidget::RendererCachedFrame); connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, this, &ViewerWidget::RendererCachedTime); connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, ruler(), &TimeRuler::CacheTimeReady); @@ -225,7 +225,7 @@ void ViewerWidget::UpdateTextureFromNode(const rational& time) if (!GetConnectedNode()) { SetTexture(nullptr); } else { - SetTexture(video_renderer_->GetCachedFrameAsTexture(time)); + //SetTexture(video_renderer_->GetCachedFrameAsTexture(time)); } } diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index 17cd5c620..e9b88cec5 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -30,7 +30,7 @@ #include "common/rational.h" #include "node/output/viewer/viewer.h" -#include "render/backend/opengl/openglbackend.h" +#include "render/backend/osl/oslbackend.h" #include "render/backend/opengl/opengltexture.h" #include "render/backend/audio/audiobackend.h" #include "viewerglwidget.h" @@ -124,7 +124,7 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; - OpenGLBackend* video_renderer_; + OSLBackend* video_renderer_; AudioBackend* audio_renderer_; private: