diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-10-16 13:19:44 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-10-30 17:15:55 +0300 |
commit | 4227a35b3271daec0cf886d3887e3de65ba9fabe (patch) | |
tree | cbaaddda2f5839250053b0c892bc95e18680a224 | |
parent | 31873218b27d5cd4c5f24e4f13d211c9b347101b (diff) |
OpenSubdiv: Avoid unnecessary memory copies
Make evaluator itself to write directly to the output buffer.
Brings unmeasurable speedup and makes it possible to simplify
some buffer class logic.
-rw-r--r-- | intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc index 6507d31480b..c584fad7543 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc @@ -117,6 +117,25 @@ template<int element_size, int num_vertices> class StackAllocatedBuffer { float data_[element_size * num_vertices]; }; +// Buffer which implements API required by OpenSubdiv and uses an existing memory as an underlying +// storage. +template<typename T> class RawDataWrapperBuffer { + public: + RawDataWrapperBuffer(T *data) : data_(data) + { + } + + T *BindCpuBuffer() + { + return data_; + } + + // TODO(sergey): Support UpdateData(). + + protected: + T *data_; +}; + template<typename EVAL_VERTEX_BUFFER, typename STENCIL_TABLE, typename PATCH_TABLE, @@ -177,7 +196,7 @@ class FaceVaryingVolatileEval { void evalPatch(const PatchCoord &patch_coord, float face_varying[2]) { - StackAllocatedBuffer<2, 1> face_varying_data; + RawDataWrapperBuffer<float> face_varying_data(face_varying); BufferDescriptor face_varying_desc(0, 2, 2); SinglePatchCoordBuffer patch_coord_buffer(patch_coord); const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( @@ -192,8 +211,6 @@ class FaceVaryingVolatileEval { face_varying_channel_, eval_instance, device_context_); - const float *refined_face_varying = face_varying_data.BindCpuBuffer(); - memcpy(face_varying, refined_face_varying, sizeof(float) * 2); } protected: @@ -357,23 +374,21 @@ class VolatileEvalOutput { void evalPatchCoord(const PatchCoord &patch_coord, float P[3]) { - StackAllocatedBuffer<3, 1> vertex_data; + RawDataWrapperBuffer<float> P_data(P); // TODO(sergey): Support interleaved vertex-varying data. - BufferDescriptor vertex_desc(0, 3, 3); + BufferDescriptor P_desc(0, 3, 3); SinglePatchCoordBuffer patch_coord_buffer(patch_coord); const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( - evaluator_cache_, src_desc_, vertex_desc, device_context_); + evaluator_cache_, src_desc_, P_desc, device_context_); EVALUATOR::EvalPatches(src_data_, src_desc_, - &vertex_data, - vertex_desc, + &P_data, + P_desc, patch_coord_buffer.GetNumVertices(), &patch_coord_buffer, patch_table_, eval_instance, device_context_); - const float *refined_vertices = vertex_data.BindCpuBuffer(); - memcpy(P, refined_vertices, sizeof(float) * 3); } void evalPatchesWithDerivatives(const PatchCoord &patch_coord, @@ -383,42 +398,32 @@ class VolatileEvalOutput { { assert(dPdu); assert(dPdv); - StackAllocatedBuffer<3, 1> vertex_data; - StackAllocatedBuffer<3, 1> dPdu_data, dPdv_data; + RawDataWrapperBuffer<float> P_data(P); + RawDataWrapperBuffer<float> dPdu_data(dPdu), dPdv_data(dPdv); // TODO(sergey): Support interleaved vertex-varying data. - BufferDescriptor vertex_desc(0, 3, 3); - BufferDescriptor du_desc(0, 3, 3), dv_desc(0, 3, 3); + BufferDescriptor P_desc(0, 3, 3); + BufferDescriptor dpDu_desc(0, 3, 3), pPdv_desc(0, 3, 3); SinglePatchCoordBuffer patch_coord_buffer(patch_coord); const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( - evaluator_cache_, src_desc_, vertex_desc, du_desc, dv_desc, device_context_); + evaluator_cache_, src_desc_, P_desc, dpDu_desc, pPdv_desc, device_context_); EVALUATOR::EvalPatches(src_data_, src_desc_, - &vertex_data, - vertex_desc, + &P_data, + P_desc, &dPdu_data, - du_desc, + dpDu_desc, &dPdv_data, - dv_desc, + pPdv_desc, patch_coord_buffer.GetNumVertices(), &patch_coord_buffer, patch_table_, eval_instance, device_context_); - const float *refined_vertices = vertex_data.BindCpuBuffer(); - memcpy(P, refined_vertices, sizeof(float) * 3); - if (dPdu != NULL) { - const float *refined_dPdu = dPdu_data.BindCpuBuffer(); - memcpy(dPdu, refined_dPdu, sizeof(float) * 3); - } - if (dPdv != NULL) { - const float *refined_dPdv = dPdv_data.BindCpuBuffer(); - memcpy(dPdv, refined_dPdv, sizeof(float) * 3); - } } void evalPatchVarying(const PatchCoord &patch_coord, float varying[3]) { - StackAllocatedBuffer<6, 1> varying_data; + RawDataWrapperBuffer<float> varying_data(varying); BufferDescriptor varying_desc(3, 3, 6); SinglePatchCoordBuffer patch_coord_buffer(patch_coord); const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( @@ -432,8 +437,6 @@ class VolatileEvalOutput { patch_table_, eval_instance, device_context_); - const float *refined_varying = varying_data.BindCpuBuffer(); - memcpy(varying, refined_varying, sizeof(float) * 3); } void evalPatchFaceVarying(const int face_varying_channel, |