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:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-05-22 10:19:55 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-05-22 10:19:55 +0300
commit9d9f2f1a0356d2049ea2ce4820c61fdebbdf50ca (patch)
tree402d7a7e1bda5a9516e43e09f5e9b8ba8a6205ff /intern/opensubdiv
parent45ed325443a3a3afb57da25ad01d636a94bf6cee (diff)
GPU subdiv: smoothly interpolate orco layer
This uses the recently introduced evaluator's vertex data to smoothly interpolate original coordinates instead of using linear interpolation. The orcos are interpolated at the same time as positions and as such, the specific subdivision routine for the orco extractor has been removed. The patch evaluation shader uses a definition to enable code specific to orco evaluation. Since the orco layer may not have been requested on first render, and since orco data is now stored in the OpenSubDiv evaluator, the evaluator needs to be recreated if an orco layer is suddenly available. For this, a callback to check if the evaluator has the data was added. This is added to the evaluator as the `Subdiv` cache stored in the modifier is invalidated less often than the Mesh batch cache and so leads to fewer evaluator recreations. Differential Revision: https://developer.blender.org/D14999
Diffstat (limited to 'intern/opensubdiv')
-rw-r--r--intern/opensubdiv/internal/evaluator/eval_output.h19
-rw-r--r--intern/opensubdiv/internal/evaluator/eval_output_gpu.cc6
-rw-r--r--intern/opensubdiv/internal/evaluator/eval_output_gpu.h2
-rw-r--r--intern/opensubdiv/internal/evaluator/evaluator_capi.cc14
-rw-r--r--intern/opensubdiv/internal/evaluator/evaluator_impl.cc10
-rw-r--r--intern/opensubdiv/internal/evaluator/evaluator_impl.h6
-rw-r--r--intern/opensubdiv/opensubdiv_evaluator_capi.h7
7 files changed, 64 insertions, 0 deletions
diff --git a/intern/opensubdiv/internal/evaluator/eval_output.h b/intern/opensubdiv/internal/evaluator/eval_output.h
index bc5494bfe41..c0da108edca 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output.h
@@ -103,6 +103,10 @@ class EvalOutputAPI::EvalOutput {
{
}
+ virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer * /*src_buffer*/)
+ {
+ }
+
virtual void fillFVarPatchArraysBuffer(const int /*face_varying_channel*/,
OpenSubdiv_Buffer * /*patch_arrays_buffer*/)
{
@@ -122,6 +126,11 @@ class EvalOutputAPI::EvalOutput {
OpenSubdiv_Buffer * /*src_buffer*/)
{
}
+
+ virtual bool hasVertexData() const
+ {
+ return false;
+ }
};
namespace {
@@ -437,6 +446,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
return face_varying_evaluators_.size() != 0;
}
+ bool hasVertexData() const override
+ {
+ return src_vertex_data_ != nullptr;
+ }
+
void refine() override
{
// Evaluate vertex positions.
@@ -599,6 +613,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
return src_data_;
}
+ SRC_VERTEX_BUFFER *getSrcVertexDataBuffer() const
+ {
+ return src_vertex_data_;
+ }
+
PATCH_TABLE *getPatchTable() const
{
return patch_table_;
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
index 566071d581b..274772b2c37 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
+++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
@@ -86,6 +86,12 @@ void GpuEvalOutput::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer)
src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO());
}
+void GpuEvalOutput::wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer)
+{
+ GLVertexBuffer *vertex_buffer = getSrcVertexDataBuffer();
+ src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO());
+}
+
void GpuEvalOutput::fillFVarPatchArraysBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_arrays_buffer)
{
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
index 2306a87b87c..8a4950dd3bc 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
@@ -52,6 +52,8 @@ class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer,
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer) override;
+ void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer) override;
+
void fillFVarPatchArraysBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_arrays_buffer) override;
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
index 8a54ed653dc..5a3a2ff131c 100644
--- a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
+++ b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
@@ -191,6 +191,12 @@ void wrapSrcBuffer(struct OpenSubdiv_Evaluator *evaluator, struct OpenSubdiv_Buf
evaluator->impl->eval_output->wrapSrcBuffer(src_buffer);
}
+void wrapSrcVertexDataBuffer(struct OpenSubdiv_Evaluator *evaluator,
+ struct OpenSubdiv_Buffer *src_buffer)
+{
+ evaluator->impl->eval_output->wrapSrcVertexDataBuffer(src_buffer);
+}
+
void fillFVarPatchArraysBuffer(struct OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
struct OpenSubdiv_Buffer *patch_array_buffer)
@@ -220,6 +226,11 @@ void wrapFVarSrcBuffer(struct OpenSubdiv_Evaluator *evaluator,
evaluator->impl->eval_output->wrapFVarSrcBuffer(face_varying_channel, src_buffer);
}
+bool hasVertexData(struct OpenSubdiv_Evaluator *evaluator)
+{
+ return evaluator->impl->eval_output->hasVertexData();
+}
+
void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
{
evaluator->setCoarsePositions = setCoarsePositions;
@@ -246,11 +257,14 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
evaluator->wrapPatchIndexBuffer = wrapPatchIndexBuffer;
evaluator->wrapPatchParamBuffer = wrapPatchParamBuffer;
evaluator->wrapSrcBuffer = wrapSrcBuffer;
+ evaluator->wrapSrcVertexDataBuffer = wrapSrcVertexDataBuffer;
evaluator->fillFVarPatchArraysBuffer = fillFVarPatchArraysBuffer;
evaluator->wrapFVarPatchIndexBuffer = wrapFVarPatchIndexBuffer;
evaluator->wrapFVarPatchParamBuffer = wrapFVarPatchParamBuffer;
evaluator->wrapFVarSrcBuffer = wrapFVarSrcBuffer;
+
+ evaluator->hasVertexData = hasVertexData;
}
} // namespace
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc
index bb9e6e7bd0d..a5273cad13a 100644
--- a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc
+++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc
@@ -383,6 +383,11 @@ void EvalOutputAPI::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer)
implementation_->wrapSrcBuffer(src_buffer);
}
+void EvalOutputAPI::wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer)
+{
+ implementation_->wrapSrcVertexDataBuffer(src_buffer);
+}
+
void EvalOutputAPI::fillFVarPatchArraysBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_arrays_buffer)
{
@@ -407,6 +412,11 @@ void EvalOutputAPI::wrapFVarSrcBuffer(const int face_varying_channel,
implementation_->wrapFVarSrcBuffer(face_varying_channel, src_buffer);
}
+bool EvalOutputAPI::hasVertexData() const
+{
+ return implementation_->hasVertexData();
+}
+
} // namespace opensubdiv
} // namespace blender
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.h b/intern/opensubdiv/internal/evaluator/evaluator_impl.h
index 8ecfa4477be..df8ef70cc01 100644
--- a/intern/opensubdiv/internal/evaluator/evaluator_impl.h
+++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.h
@@ -163,6 +163,9 @@ class EvalOutputAPI {
// Wrap the buffer used by OpenSubDiv for the source data with the given buffer.
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer);
+ // Wrap the buffer used by OpenSubDiv for the extra source data with the given buffer.
+ void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer);
+
// Copy the patch arrays buffer used by OpenSubDiv for the face varying channel with the given
// buffer.
void fillFVarPatchArraysBuffer(const int face_varying_channel,
@@ -181,6 +184,9 @@ class EvalOutputAPI {
// Wrap thebuffer used by OpenSubDiv for the face varying channel with the given buffer.
void wrapFVarSrcBuffer(const int face_varying_channel, OpenSubdiv_Buffer *src_buffer);
+ // Return true if source vertex data has been set.
+ bool hasVertexData() const;
+
protected:
PatchMap *patch_map_;
EvalOutput *implementation_;
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.h b/intern/opensubdiv/opensubdiv_evaluator_capi.h
index 98e1db6e323..094244c4681 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.h
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.h
@@ -195,6 +195,10 @@ typedef struct OpenSubdiv_Evaluator {
void (*wrapSrcBuffer)(struct OpenSubdiv_Evaluator *evaluator,
struct OpenSubdiv_Buffer *src_buffer);
+ // Fill the given buffer with data from the evaluator's extra source buffer.
+ void (*wrapSrcVertexDataBuffer)(struct OpenSubdiv_Evaluator *evaluator,
+ struct OpenSubdiv_Buffer *src_buffer);
+
// Fill the given buffer with data from the evaluator's face varying patch array buffer.
void (*fillFVarPatchArraysBuffer)(struct OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
@@ -215,6 +219,9 @@ typedef struct OpenSubdiv_Evaluator {
const int face_varying_channel,
struct OpenSubdiv_Buffer *src_buffer);
+ // Return true if the evaluator has source vertex data set.
+ bool (*hasVertexData)(struct OpenSubdiv_Evaluator *evaluator);
+
// Implementation of the evaluator.
struct OpenSubdiv_EvaluatorImpl *impl;