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>2022-05-30 14:28:38 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-05-30 15:06:03 +0300
commit24e74f8bef813820076cce08635e7c4cb3f2da13 (patch)
tree0648fcbee74ed8cb0aeac591b2647da5e9cf8c56
parentf1c29b9bd3c8241b212d7d50b2d538b980a7d62e (diff)
Fix T98449: Cycles crash changing frame after recent changes
Subdivision did not properly update when evaluating first without and then with orco coordinates. Now update the subdivision evaluator settings every time, and reallocate the vertex data buffer when needed. there is an additional issue in this file where orco coordinates are not available immediately on the first frame when they should be, and only appear on the second frame. However that is an old limitation related to the depsgraph not getting re-evaluated on viewport display mode changes, here we just fix the crash.
-rw-r--r--intern/opensubdiv/internal/evaluator/eval_output.h36
-rw-r--r--intern/opensubdiv/internal/evaluator/eval_output_cpu.h2
-rw-r--r--intern/opensubdiv/internal/evaluator/eval_output_gpu.cc2
-rw-r--r--intern/opensubdiv/internal/evaluator/eval_output_gpu.h1
-rw-r--r--intern/opensubdiv/internal/evaluator/evaluator_capi.cc18
-rw-r--r--intern/opensubdiv/internal/evaluator/evaluator_impl.cc18
-rw-r--r--intern/opensubdiv/internal/evaluator/evaluator_impl.h6
-rw-r--r--intern/opensubdiv/opensubdiv_evaluator_capi.h17
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c3
9 files changed, 59 insertions, 44 deletions
diff --git a/intern/opensubdiv/internal/evaluator/eval_output.h b/intern/opensubdiv/internal/evaluator/eval_output.h
index cff7c8d18c9..57a9fab490f 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output.h
@@ -27,6 +27,8 @@
#include "internal/base/type.h"
#include "internal/evaluator/evaluator_impl.h"
+#include "opensubdiv_evaluator_capi.h"
+
using OpenSubdiv::Far::PatchTable;
using OpenSubdiv::Far::StencilTable;
using OpenSubdiv::Osd::BufferDescriptor;
@@ -42,6 +44,8 @@ class EvalOutputAPI::EvalOutput {
public:
virtual ~EvalOutput() = default;
+ virtual void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) = 0;
+
virtual void updateData(const float *src, int start_vertex, int num_vertices) = 0;
virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices) = 0;
@@ -338,13 +342,13 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
- const int vertex_data_width,
const PatchTable *patch_table,
EvaluatorCache *evaluator_cache = NULL,
DEVICE_CONTEXT *device_context = NULL)
- : src_desc_(0, 3, 3),
+ : src_vertex_data_(NULL),
+ src_desc_(0, 3, 3),
src_varying_desc_(0, 3, 3),
- src_vertex_data_desc_(0, vertex_data_width, vertex_data_width),
+ src_vertex_data_desc_(0, 0, 0),
face_varying_width_(face_varying_width),
evaluator_cache_(evaluator_cache),
device_context_(device_context)
@@ -362,15 +366,6 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
device_context_);
- // Optionally allocate additional data to be subdivided like vertex coordinates.
- if (vertex_data_width > 0) {
- src_vertex_data_ = SRC_VERTEX_BUFFER::Create(
- vertex_data_width, num_total_vertices, device_context_);
- }
- else {
- src_vertex_data_ = NULL;
- }
-
// Create evaluators for every face varying channel.
face_varying_evaluators.reserve(all_face_varying_stencils.size());
int face_varying_channel = 0;
@@ -398,6 +393,23 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
}
}
+ void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) override
+ {
+ // Optionally allocate additional data to be subdivided like vertex coordinates.
+ if (settings->num_vertex_data != src_vertex_data_desc_.length) {
+ delete src_vertex_data_;
+ if (settings->num_vertex_data > 0) {
+ src_vertex_data_ = SRC_VERTEX_BUFFER::Create(
+ settings->num_vertex_data, src_data_->GetNumVertices(), device_context_);
+ }
+ else {
+ src_vertex_data_ = NULL;
+ }
+ src_vertex_data_desc_ = BufferDescriptor(
+ 0, settings->num_vertex_data, settings->num_vertex_data);
+ }
+ }
+
// TODO(sergey): Implement binding API.
void updateData(const float *src, int start_vertex, int num_vertices) override
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_cpu.h b/intern/opensubdiv/internal/evaluator/eval_output_cpu.h
index 2b3c738d6ab..58bae7a322e 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_cpu.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output_cpu.h
@@ -44,7 +44,6 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
- const int vertex_data_width,
const PatchTable *patch_table,
EvaluatorCache *evaluator_cache = NULL)
: VolatileEvalOutput<CpuVertexBuffer,
@@ -55,7 +54,6 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
varying_stencils,
all_face_varying_stencils,
face_varying_width,
- vertex_data_width,
patch_table,
evaluator_cache)
{
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
index 566071d581b..b352ed2c014 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
+++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
@@ -45,7 +45,6 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils,
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
- const int vertex_data_width,
const PatchTable *patch_table,
VolatileEvalOutput::EvaluatorCache *evaluator_cache)
: VolatileEvalOutput<GLVertexBuffer,
@@ -56,7 +55,6 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils,
varying_stencils,
all_face_varying_stencils,
face_varying_width,
- vertex_data_width,
patch_table,
evaluator_cache)
{
diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
index 2306a87b87c..dc137e4322e 100644
--- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
+++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h
@@ -40,7 +40,6 @@ class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer,
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
- const int vertex_data_width,
const PatchTable *patch_table,
EvaluatorCache *evaluator_cache = NULL);
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
index 8a54ed653dc..b8d603ec380 100644
--- a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
+++ b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc
@@ -28,6 +28,12 @@
namespace {
+void setSettings(struct OpenSubdiv_Evaluator *evaluator,
+ const OpenSubdiv_EvaluatorSettings *settings)
+{
+ evaluator->impl->eval_output->setSettings(settings);
+}
+
void setCoarsePositions(OpenSubdiv_Evaluator *evaluator,
const float *positions,
const int start_vertex_index,
@@ -222,6 +228,8 @@ void wrapFVarSrcBuffer(struct OpenSubdiv_Evaluator *evaluator,
void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
{
+ evaluator->setSettings = setSettings;
+
evaluator->setCoarsePositions = setCoarsePositions;
evaluator->setVertexData = setVertexData;
evaluator->setVaryingData = setVaryingData;
@@ -258,16 +266,12 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
- OpenSubdiv_EvaluatorCache *evaluator_cache,
- const OpenSubdiv_EvaluatorSettings *settings)
+ OpenSubdiv_EvaluatorCache *evaluator_cache)
{
OpenSubdiv_Evaluator *evaluator = MEM_new<OpenSubdiv_Evaluator>(__func__);
assignFunctionPointers(evaluator);
- evaluator->impl = openSubdiv_createEvaluatorInternal(topology_refiner,
- evaluator_type,
- evaluator_cache ? evaluator_cache->impl :
- nullptr,
- settings);
+ evaluator->impl = openSubdiv_createEvaluatorInternal(
+ topology_refiner, evaluator_type, evaluator_cache ? evaluator_cache->impl : nullptr);
evaluator->type = evaluator->impl ? evaluator_type : static_cast<eOpenSubdivEvaluator>(0);
return evaluator;
}
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc
index bb9e6e7bd0d..0b8baa754d4 100644
--- a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc
+++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc
@@ -166,6 +166,11 @@ EvalOutputAPI::~EvalOutputAPI()
delete implementation_;
}
+void EvalOutputAPI::setSettings(const OpenSubdiv_EvaluatorSettings *settings)
+{
+ implementation_->updateSettings(settings);
+}
+
void EvalOutputAPI::setCoarsePositions(const float *positions,
const int start_vertex_index,
const int num_vertices)
@@ -425,8 +430,7 @@ OpenSubdiv_EvaluatorImpl::~OpenSubdiv_EvaluatorImpl()
OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
- OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr,
- const OpenSubdiv_EvaluatorSettings *settings)
+ OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr)
{
// Only CPU and GLCompute are implemented at the moment.
if (evaluator_type != OPENSUBDIV_EVALUATOR_CPU &&
@@ -445,7 +449,6 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
const bool has_face_varying_data = (num_face_varying_channels != 0);
const int level = topology_refiner->getSubdivisionLevel(topology_refiner);
const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner);
- const int vertex_data_width = settings->num_vertex_data;
// Common settings for stencils and patches.
const bool stencil_generate_intermediate_levels = is_adaptive;
const bool stencil_generate_offsets = true;
@@ -550,17 +553,12 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
varying_stencils,
all_face_varying_stencils,
2,
- vertex_data_width,
patch_table,
evaluator_cache);
}
else {
- eval_output = new blender::opensubdiv::CpuEvalOutput(vertex_stencils,
- varying_stencils,
- all_face_varying_stencils,
- 2,
- vertex_data_width,
- patch_table);
+ eval_output = new blender::opensubdiv::CpuEvalOutput(
+ vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
}
blender::opensubdiv::PatchMap *patch_map = new blender::opensubdiv::PatchMap(*patch_table);
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.h b/intern/opensubdiv/internal/evaluator/evaluator_impl.h
index 8ecfa4477be..dbd786c8524 100644
--- a/intern/opensubdiv/internal/evaluator/evaluator_impl.h
+++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.h
@@ -57,6 +57,9 @@ class EvalOutputAPI {
~EvalOutputAPI();
+ // Set settings for data buffers.
+ void setSettings(const OpenSubdiv_EvaluatorSettings *settings);
+
// Set coarse positions from a continuous array of coordinates.
void setCoarsePositions(const float *positions,
const int start_vertex_index,
@@ -204,8 +207,7 @@ struct OpenSubdiv_EvaluatorImpl {
OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
struct OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
- OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr,
- const OpenSubdiv_EvaluatorSettings *settings);
+ OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr);
void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator);
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.h b/intern/opensubdiv/opensubdiv_evaluator_capi.h
index 98e1db6e323..7dcf85cca8d 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.h
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.h
@@ -31,6 +31,11 @@ struct OpenSubdiv_EvaluatorInternal;
struct OpenSubdiv_PatchCoord;
struct OpenSubdiv_TopologyRefiner;
+typedef struct OpenSubdiv_EvaluatorSettings {
+ // Number of smoothly interpolated vertex data channels.
+ int num_vertex_data;
+} OpenSubdiv_EvaluatorSettings;
+
// Callback type for doing input/output operations on buffers.
// Useful to abstract GPU buffers.
typedef struct OpenSubdiv_Buffer {
@@ -64,6 +69,10 @@ typedef struct OpenSubdiv_Buffer {
} OpenSubdiv_Buffer;
typedef struct OpenSubdiv_Evaluator {
+ // Set settings for data buffers used.
+ void (*setSettings)(struct OpenSubdiv_Evaluator *evaluator,
+ const OpenSubdiv_EvaluatorSettings *settings);
+
// Set coarse positions from a continuous array of coordinates.
void (*setCoarsePositions)(struct OpenSubdiv_Evaluator *evaluator,
const float *positions,
@@ -227,16 +236,10 @@ typedef struct OpenSubdiv_EvaluatorCache {
struct OpenSubdiv_EvaluatorCacheImpl *impl;
} OpenSubdiv_EvaluatorCache;
-typedef struct OpenSubdiv_EvaluatorSettings {
- // Number of smoothly interpolated vertex data channels.
- int num_vertex_data;
-} OpenSubdiv_EvaluatorSettings;
-
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
struct OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
- OpenSubdiv_EvaluatorCache *evaluator_cache,
- const OpenSubdiv_EvaluatorSettings *settings);
+ OpenSubdiv_EvaluatorCache *evaluator_cache);
void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator *evaluator);
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index d03c0f89948..b8f6dc322c5 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -58,7 +58,7 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv,
opensubdiv_evalutor_from_subdiv_evaluator_type(evaluator_type);
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(
- subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache, settings);
+ subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache);
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
if (subdiv->evaluator == NULL) {
return false;
@@ -67,6 +67,7 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv,
else {
/* TODO(sergey): Check for topology change. */
}
+ subdiv->evaluator->setSettings(subdiv->evaluator, settings);
BKE_subdiv_eval_init_displacement(subdiv);
return true;
}