work on oslworker
This commit is contained in:
@@ -90,7 +90,7 @@ void Config::SetDefaults()
|
|||||||
|
|
||||||
// Online/offline settings
|
// Online/offline settings
|
||||||
config_map_["OnlinePixelFormat"] = PixelFormat::PIX_FMT_RGBA32F;
|
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_["OnlineSampleFormat"] = SampleFormat::SAMPLE_FMT_FLT;
|
||||||
config_map_["OfflineSampleFormat"] = SampleFormat::SAMPLE_FMT_FLT;
|
config_map_["OfflineSampleFormat"] = SampleFormat::SAMPLE_FMT_FLT;
|
||||||
config_map_["OnlineOCIOMethod"] = ColorManager::kOCIOAccurate;
|
config_map_["OnlineOCIOMethod"] = ColorManager::kOCIOAccurate;
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "project/projectsavemanager.h"
|
#include "project/projectsavemanager.h"
|
||||||
#include "project/item/footage/footage.h"
|
#include "project/item/footage/footage.h"
|
||||||
#include "project/item/sequence/sequence.h"
|
#include "project/item/sequence/sequence.h"
|
||||||
|
#include "render/backend/opengl/opengltexturecache.h"
|
||||||
#include "render/colormanager.h"
|
#include "render/colormanager.h"
|
||||||
#include "render/diskmanager.h"
|
#include "render/diskmanager.h"
|
||||||
#include "render/pixelservice.h"
|
#include "render/pixelservice.h"
|
||||||
|
|||||||
@@ -65,21 +65,24 @@ bool OSLBackend::CompileInternal()
|
|||||||
foreach (Node* n, deps) {
|
foreach (Node* n, deps) {
|
||||||
if (!shader_cache_.Has(n->id())) {
|
if (!shader_cache_.Has(n->id())) {
|
||||||
if (n->IsAccelerated()) {
|
if (n->IsAccelerated()) {
|
||||||
// FIXME: Compile here
|
|
||||||
|
|
||||||
std::string oso_buffer;
|
std::string oso_buffer;
|
||||||
|
|
||||||
|
QString function_name = n->id().replace('.', '_');
|
||||||
|
|
||||||
if (!compiler.compile_buffer(n->AcceleratedCodeFragment().toStdString(),
|
if (!compiler.compile_buffer(n->AcceleratedCodeFragment().toStdString(),
|
||||||
oso_buffer,
|
oso_buffer,
|
||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
"",
|
"",
|
||||||
n->id().toStdString())) {
|
function_name.toStdString())) {
|
||||||
qWarning() << "Failed to compile" << n->id();
|
qWarning() << "Failed to compile" << n->id();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
system->LoadMemoryCompiledShader(function_name.toStdString(), oso_buffer);
|
||||||
|
|
||||||
OSL::ShaderGroupRef ref = system->ShaderGroupBegin(n->id().toStdString());
|
OSL::ShaderGroupRef ref = system->ShaderGroupBegin(n->id().toStdString());
|
||||||
system->Shader("surface", n->id().toStdString(), "layer1");
|
system->Shader("shader", function_name.toStdString(), "layer1");
|
||||||
system->ShaderGroupEnd();
|
system->ShaderGroupEnd();
|
||||||
|
|
||||||
shader_cache_.Add(n->id(), ref);
|
shader_cache_.Add(n->id(), ref);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <QVector4D>
|
#include <QVector4D>
|
||||||
|
|
||||||
#include "common/clamp.h"
|
#include "common/clamp.h"
|
||||||
|
#include "common/define.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "node/block/transition/transition.h"
|
#include "node/block/transition/transition.h"
|
||||||
#include "node/node.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);
|
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 alpha is associated, disassociate for the color transform
|
||||||
if (video_stream->premultiplied_alpha()) {
|
if (video_stream->premultiplied_alpha()) {
|
||||||
ColorManager::DisassociateAlpha(frame);
|
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
|
// Perform color transform
|
||||||
color_processor->ConvertFrame(frame);
|
color_processor->ConvertFrame(frame);
|
||||||
|
|
||||||
@@ -65,17 +66,15 @@ void OSLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable *t
|
|||||||
ColorManager::AssociateAlpha(frame);
|
ColorManager::AssociateAlpha(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
table->Push(NodeParam::kTexture, QVariant::fromValue(frame));
|
OIIOImageBufRef buf = std::make_shared<OIIO::ImageBuf>(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)
|
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()) {
|
if (!node->IsAccelerated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -86,15 +85,10 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the output textures
|
int input_texture_count = 0;
|
||||||
QList<OpenGLTextureCache::ReferencePtr> dst_refs;
|
|
||||||
dst_refs.append(texture_cache_.Get(ctx_, video_params_));
|
|
||||||
GLuint iterative_input = 0;
|
|
||||||
|
|
||||||
// If this node requires multiple iterations, get a texture for it too
|
OIIOImageBufRef iteration_buf = nullptr;
|
||||||
if (node->AcceleratedCodeIterations() > 1 && node->AcceleratedCodeIterativeInput()) {
|
int iteration_id = -1;
|
||||||
dst_refs.append(texture_cache_.Get(ctx_, video_params_));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (NodeParam* param, node->parameters()) {
|
foreach (NodeParam* param, node->parameters()) {
|
||||||
if (param->type() == NodeParam::kInput) {
|
if (param->type() == NodeParam::kInput) {
|
||||||
@@ -160,16 +154,39 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con
|
|||||||
case NodeInput::kTexture:
|
case NodeInput::kTexture:
|
||||||
case NodeInput::kBuffer:
|
case NodeInput::kBuffer:
|
||||||
{
|
{
|
||||||
OpenGLTextureCache::ReferencePtr texture = value.value<OpenGLTextureCache::ReferencePtr>();
|
OIIOImageBufRef buf = value.value<OIIOImageBufRef>();
|
||||||
|
|
||||||
functions_->glActiveTexture(GL_TEXTURE0 + input_texture_count);
|
if (buf) {
|
||||||
|
|
||||||
GLuint tex_id = texture ? texture->texture()->texture() : 0;
|
QString tex_fn = ImageBufToTexture(*buf.get(), input_texture_count);
|
||||||
functions_->glBindTexture(GL_TEXTURE_2D, tex_id);
|
|
||||||
|
|
||||||
// Set value to bound texture
|
if (!tex_fn.isEmpty()) {
|
||||||
shader->setUniformValue(variable_location, input_texture_count);
|
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
|
// Set enable flag if shader wants it
|
||||||
int enable_param_location = shader->uniformLocation(QStringLiteral("%1_enabled").arg(input->id()));
|
int enable_param_location = shader->uniformLocation(QStringLiteral("%1_enabled").arg(input->id()));
|
||||||
if (enable_param_location > -1) {
|
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_);
|
OpenGLRenderFunctions::PrepareToDraw(functions_);
|
||||||
|
*/
|
||||||
|
|
||||||
input_texture_count++;
|
input_texture_count++;
|
||||||
break;
|
break;
|
||||||
@@ -253,14 +268,10 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con
|
|||||||
&p);
|
&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OIIOImageBufRef dest_buf = nullptr;
|
||||||
|
|
||||||
// Some nodes use multiple iterations for optimization
|
// Some nodes use multiple iterations for optimization
|
||||||
OpenGLTextureCache::ReferencePtr output_tex;
|
|
||||||
|
|
||||||
for (int iteration=0;iteration<node->AcceleratedCodeIterations();iteration++) {
|
for (int iteration=0;iteration<node->AcceleratedCodeIterations();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
|
// Set iteration number
|
||||||
shading_system_->ReParameter(*group.get(),
|
shading_system_->ReParameter(*group.get(),
|
||||||
"layer1",
|
"layer1",
|
||||||
@@ -269,13 +280,28 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con
|
|||||||
&iteration);
|
&iteration);
|
||||||
|
|
||||||
if (iteration > 0) {
|
if (iteration > 0) {
|
||||||
functions_->glActiveTexture(GL_TEXTURE0 + iterative_input);
|
// Convert destination buffer into texture
|
||||||
functions_->glBindTexture(GL_TEXTURE_2D, source_tex->texture()->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::ImageBuf>(OIIO::ImageSpec(video_params().width(),
|
||||||
|
video_params().height(),
|
||||||
|
kRGBAChannels,
|
||||||
|
PixelService::GetPixelFormatInfo(video_params().format()).oiio_desc));
|
||||||
|
}
|
||||||
|
|
||||||
static OIIO::array_view<OSL::ustring> outputs = {OSL::ustring("Cout")};
|
static OSL::ustring outputs[] = {OSL::ustring("Cout")};
|
||||||
|
|
||||||
OIIO::ImageBufAlgo::parallel_image_options popt;
|
OIIO::ImageBufAlgo::parallel_image_options popt;
|
||||||
#if OPENIMAGEIO_VERSION > 10902
|
#if OPENIMAGEIO_VERSION > 10902
|
||||||
@@ -284,28 +310,44 @@ void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, con
|
|||||||
popt.recursive = true;
|
popt.recursive = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OIIO::ImageBuf buffer;
|
|
||||||
|
|
||||||
shade_image(*shading_system_,
|
shade_image(*shading_system_,
|
||||||
*group.get(),
|
*group.get(),
|
||||||
nullptr,
|
nullptr,
|
||||||
buffer,
|
*dest_buf.get(),
|
||||||
outputs,
|
outputs,
|
||||||
OSL::ShadePixelCenters,
|
OSL::ShadePixelCenters,
|
||||||
OIIO::ROI(),
|
OIIO::ROI(),
|
||||||
popt);
|
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)
|
void OSLWorker::TextureToBuffer(const QVariant &tex_in, QByteArray &buffer)
|
||||||
{
|
{
|
||||||
FramePtr frame = tex_in.value<FramePtr>();
|
OIIOImageBufRef frame = tex_in.value<OIIOImageBufRef>();
|
||||||
|
|
||||||
memcpy(buffer.data(), frame->data(), static_cast<size_t>(buffer.size()));
|
memcpy(buffer.data(), frame->localpixels(), static_cast<size_t>(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<quintptr>(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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ protected:
|
|||||||
virtual void TextureToBuffer(const QVariant& texture, QByteArray& buffer) override;
|
virtual void TextureToBuffer(const QVariant& texture, QByteArray& buffer) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString ImageBufToTexture(const OIIO::ImageBuf& buffer, int tex_no);
|
||||||
|
|
||||||
OSL::ShadingSystem* shading_system_;
|
OSL::ShadingSystem* shading_system_;
|
||||||
|
|
||||||
OSLShaderCache* shader_cache_;
|
OSLShaderCache* shader_cache_;
|
||||||
@@ -33,4 +35,7 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using OIIOImageBufRef = std::shared_ptr<OIIO::ImageBuf>;
|
||||||
|
Q_DECLARE_METATYPE(OIIOImageBufRef)
|
||||||
|
|
||||||
#endif // OSLWORKER_H
|
#endif // OSLWORKER_H
|
||||||
|
|||||||
@@ -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;
|
varying vec2 ove_texcoord;
|
||||||
uniform sampler2D footage_in;
|
uniform sampler2D footage_in;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_FragColor = texture2D(footage_in, ove_texcoord);
|
gl_FragColor = texture2D(footage_in, ove_texcoord);
|
||||||
}
|
}*/
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
|||||||
SetScale(48.0);
|
SetScale(48.0);
|
||||||
|
|
||||||
// Start background renderers
|
// 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::CachedFrameReady, this, &ViewerWidget::RendererCachedFrame);
|
||||||
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, this, &ViewerWidget::RendererCachedTime);
|
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, this, &ViewerWidget::RendererCachedTime);
|
||||||
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, ruler(), &TimeRuler::CacheTimeReady);
|
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, ruler(), &TimeRuler::CacheTimeReady);
|
||||||
@@ -225,7 +225,7 @@ void ViewerWidget::UpdateTextureFromNode(const rational& time)
|
|||||||
if (!GetConnectedNode()) {
|
if (!GetConnectedNode()) {
|
||||||
SetTexture(nullptr);
|
SetTexture(nullptr);
|
||||||
} else {
|
} else {
|
||||||
SetTexture(video_renderer_->GetCachedFrameAsTexture(time));
|
//SetTexture(video_renderer_->GetCachedFrameAsTexture(time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "common/rational.h"
|
#include "common/rational.h"
|
||||||
#include "node/output/viewer/viewer.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/opengl/opengltexture.h"
|
||||||
#include "render/backend/audio/audiobackend.h"
|
#include "render/backend/audio/audiobackend.h"
|
||||||
#include "viewerglwidget.h"
|
#include "viewerglwidget.h"
|
||||||
@@ -124,7 +124,7 @@ protected:
|
|||||||
|
|
||||||
virtual void resizeEvent(QResizeEvent *event) override;
|
virtual void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
OpenGLBackend* video_renderer_;
|
OSLBackend* video_renderer_;
|
||||||
AudioBackend* audio_renderer_;
|
AudioBackend* audio_renderer_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user