From 827efd14e3cd2dffccf8fc4c657e1c81db0996c0 Mon Sep 17 00:00:00 2001 From: Manuel Kraemer Date: Sat, 10 May 2014 17:55:50 -0700 Subject: [PATCH] Reorganize EvalLimitContext and EvalLimitController Moved transient states (current vertex buffer etc) to controller. ComputeContext becomes constant so that it's well suited for coarse-grain parallelism on cpu. Client-facing API has changed slightly - limitEval example has been adjusted --- examples/limitEval/main.cpp | 26 +-- opensubdiv/osd/cpuEvalLimitContext.cpp | 31 ---- opensubdiv/osd/cpuEvalLimitContext.h | 217 ---------------------- opensubdiv/osd/cpuEvalLimitController.cpp | 59 +++--- opensubdiv/osd/cpuEvalLimitController.h | 195 +++++++++++++++++-- opensubdiv/osdutil/adaptiveEvaluator.cpp | 13 +- 6 files changed, 219 insertions(+), 322 deletions(-) diff --git a/examples/limitEval/main.cpp b/examples/limitEval/main.cpp index cd00946a..ab4aa773 100644 --- a/examples/limitEval/main.cpp +++ b/examples/limitEval/main.cpp @@ -411,30 +411,30 @@ updateGeom() { g_nsamplesFound=0; - // Bind/Unbind of the vertex buffers to the context needs to happen - // outside of the parallel loop - g_evalCtx->GetVertexData().Bind( g_idesc, g_vertexData, g_odesc, g_Q, g_dQu, g_dQv ); - // The varying data ends-up interleaved in the same g_Q output buffer because // g_Q has a stride of 6 and g_vdesc sets the offset to 3, while g_odesc sets // the offset to 0 switch (g_drawMode) { - case kVARYING : g_evalCtx->GetVaryingData().Bind( g_idesc, g_varyingData, g_vdesc, g_Q ); break; + case kVARYING : g_evalCtrl.BindVaryingBuffers( g_idesc, g_varyingData, g_vdesc, g_Q ); break; - case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Bind( g_fvidesc, g_fvodesc, g_Q ); + case kFACEVARYING : g_evalCtrl.BindFacevaryingBuffers( g_fvidesc, g_fvodesc, g_Q ); break; case kUV : - default : g_evalCtx->GetVaryingData().Unbind(); break; + default : g_evalCtrl.Unbind(); break; } + // Bind/Unbind of the vertex buffers to the context needs to happen + // outside of the parallel loop + g_evalCtrl.BindVertexBuffers( g_idesc, g_vertexData, g_odesc, g_Q, g_dQu, g_dQv ); + #define USE_OPENMP #if defined(OPENSUBDIV_HAS_OPENMP) and defined(USE_OPENMP) #pragma omp parallel for #endif for (int i=0; i<(int)g_coords.size(); ++i) { - int n = g_evalCtrl.EvalLimitSample( g_coords[i], g_evalCtx, i ); + int n = g_evalCtrl.EvalLimitSample( g_coords[i], g_evalCtx, i ); if (n) { // point colors @@ -461,16 +461,8 @@ updateGeom() { } } - g_evalCtx->GetVertexData().Unbind(); + g_evalCtrl.Unbind(); - switch (g_drawMode) { - case kVARYING : g_evalCtx->GetVaryingData().Unbind(); break; - - case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Unbind(); break; - - default : break; - } - g_Q->BindVBO(); s.Stop(); diff --git a/opensubdiv/osd/cpuEvalLimitContext.cpp b/opensubdiv/osd/cpuEvalLimitContext.cpp index 31fb1ebd..c6d5d7fa 100644 --- a/opensubdiv/osd/cpuEvalLimitContext.cpp +++ b/opensubdiv/osd/cpuEvalLimitContext.cpp @@ -98,36 +98,5 @@ OsdCpuEvalLimitContext::~OsdCpuEvalLimitContext() { delete _patchMap; } -void -OsdCpuEvalLimitContext::VertexData::Unbind() { - - inDesc.Reset(); - in.Unbind(); - - outDesc.Reset(); - out.Unbind(); - outDu.Unbind(); - outDv.Unbind(); -} - -void -OsdCpuEvalLimitContext::VaryingData::Unbind() { - - inDesc.Reset(); - in.Unbind(); - - outDesc.Reset(); - out.Unbind(); -} - -void -OsdCpuEvalLimitContext::FaceVaryingData::Unbind() { - - inDesc.Reset(); - - outDesc.Reset(); - out.Unbind(); -} - } // end namespace OPENSUBDIV_VERSION } // end namespace OpenSubdiv diff --git a/opensubdiv/osd/cpuEvalLimitContext.h b/opensubdiv/osd/cpuEvalLimitContext.h index 4a5e7ce0..a87db548 100644 --- a/opensubdiv/osd/cpuEvalLimitContext.h +++ b/opensubdiv/osd/cpuEvalLimitContext.h @@ -56,219 +56,6 @@ public: virtual ~OsdCpuEvalLimitContext(); - - /// A container able to bind vertex buffer data as input or output streams. - class DataStream { - public: - /// Constructor - DataStream() : _data(0) { } - - /// Binds the stream to the context (and moves the data to the appropriate - /// compute device) - /// - /// @param data a valid OsdVertexBuffer - /// - template void Bind( BUFFER * data ) { - _data = data ? data->BindCpuBuffer() : 0; - } - - /// True if the stream has been bound - bool IsBound() const { - return (_data!=NULL); - } - - /// Unbinds the stream - void Unbind() { - _data=0; - } - - protected: - float * _data; - }; - - /// \brief Input (const) data stream - class InputDataStream : public DataStream { - public: - /// Const accessor - float const * GetData() const { - return _data; - } - }; - - /// \brief Output (const) data stream - class OutputDataStream : public DataStream { - public: - /// Non-cont accessor - float * GetData() { - return _data; - } - }; - - /// Vertex-interpolated streams - struct VertexData { - - /// input vertex-interpolated data descriptor - OsdVertexBufferDescriptor inDesc; - - /// input vertex-interpolated data stream - InputDataStream in; - - /// output vertex-interpolated data descriptor - OsdVertexBufferDescriptor outDesc; - - /// output vertex-interpolated data stream and parametric derivative streams - OutputDataStream out, - outDu, - outDv; - - /// Binds the vertex-interpolated data streams - /// - /// @param iDesc data descriptor shared by all input data buffers - /// - /// @param inQ input vertex data - /// - /// @param oDesc data descriptor shared by all output data buffers - /// - /// @param outQ output vertex data - /// - /// @param outdQu output derivative along "u" of the vertex data (optional) - /// - /// @param outdQv output derivative along "v" of the vertex data (optional) - /// - template - void Bind( OsdVertexBufferDescriptor const & iDesc, VERTEX_BUFFER *inQ, - OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ, - OUTPUT_BUFFER *outdQu=0, - OUTPUT_BUFFER *outdQv=0) { - inDesc = iDesc; - in.Bind( inQ ); - - outDesc = oDesc; - out.Bind( outQ ); - outDu.Bind( outdQu ); - outDv.Bind( outdQv ); - } - - /// True if both the mandatory input and output streams have been bound - bool IsBound() const { - return in.IsBound() and out.IsBound(); - } - - /// Unbind the vertex data streams - void Unbind(); - }; - - /// Returns an Eval data descriptor of the vertex-interpolated data currently - /// bound to this EvalLimitContext. - VertexData & GetVertexData() { - return _vertexData; - } - - - - - /// Varying-interpolated streams - struct VaryingData { - - /// input varying-interpolated data descriptor - OsdVertexBufferDescriptor inDesc; - - /// input varying-interpolated data stream - InputDataStream in; - - /// output varying-interpolated data descriptor - OsdVertexBufferDescriptor outDesc; - - /// output varying-interpolated data stream - OutputDataStream out; - - /// Binds the varying-interpolated data streams - /// - /// @param iDesc data descriptor shared by all input data buffers - /// - /// @param inQ input varying data - /// - /// @param oDesc data descriptor shared by all output data buffers - /// - /// @param outQ output varying data - /// - template - void Bind( OsdVertexBufferDescriptor const & iDesc, VARYING_BUFFER *inQ, - OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) { - inDesc = iDesc; - in.Bind( inQ ); - - outDesc = oDesc; - out.Bind( outQ ); - } - - /// True if both the mandatory input and output streams have been bound - bool IsBound() const { - return in.IsBound() and out.IsBound(); - } - - /// Unbind the vertex data streams - void Unbind(); - }; - - /// Returns an Eval data descriptor of the varying-interpolated data currently - /// bound to this EvalLimitContext. - VaryingData & GetVaryingData() { - return _varyingData; - } - - - - /// Face-Varying-interpolated streams - struct FaceVaryingData { - - /// input face-varying-interpolated data descriptor - OsdVertexBufferDescriptor inDesc; - - /// output face-varying-interpolated data descriptor - OsdVertexBufferDescriptor outDesc; - - /// output face-varying-interpolated data stream and parametric derivative streams - OutputDataStream out; - - /// Binds the face-varying-interpolated data streams - /// - /// Note : currently we only support bilinear boundary interpolation rules - /// for face-varying data. Although Hbr supports 3 addition smooth rule sets, - /// the feature-adaptive patch interpolation code currently does not support - /// them, and neither does this EvalContext - /// - /// @param iDesc data descriptor shared by all input data buffers - /// - /// @param oDesc data descriptor shared by all output data buffers - /// - /// @param outQ output face-varying data - /// - template - void Bind( OsdVertexBufferDescriptor const & iDesc, - OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) { - inDesc = iDesc; - - outDesc = oDesc; - out.Bind( outQ ); - } - - /// True if the output stream has been bound - bool IsBound() const { - return out.IsBound(); - } - - /// Unbind the vertex data streams - void Unbind(); - }; - - /// Returns an Eval data descriptor of the face-varying-interpolated data - /// currently bound to this EvalLimitContext. - FaceVaryingData & GetFaceVaryingData() { - return _faceVaryingData; - } - - /// Returns the vector of patch arrays const FarPatchTables::PatchArrayVector & GetPatchArrayVector() const { return _patchArrays; @@ -331,10 +118,6 @@ private: FarPatchMap * _patchMap; // map of the sub-patches given a face index - VertexData _vertexData; // vertex-interpolated data descriptor - VaryingData _varyingData; // varying-interpolated data descriptor - FaceVaryingData _faceVaryingData; // face-varying-interpolated data descriptor - int _maxValence, _fvarwidth; }; diff --git a/opensubdiv/osd/cpuEvalLimitController.cpp b/opensubdiv/osd/cpuEvalLimitController.cpp index 96a49c82..04b98fa5 100644 --- a/opensubdiv/osd/cpuEvalLimitController.cpp +++ b/opensubdiv/osd/cpuEvalLimitController.cpp @@ -72,9 +72,9 @@ OsdCpuEvalLimitController::EvalLimitSample( OpenSubdiv::OsdEvalCoords const & co unsigned int const * cvs = &context->GetControlVertices()[ parray.GetVertIndex() + handle->vertexOffset ]; - OsdCpuEvalLimitContext::VertexData & vertexData = context->GetVertexData(); + VertexData const & vertexData = _currentBindState.vertexData; - if (vertexData.in.IsBound()) { + if (vertexData.in) { float * out = outQ ? outQ + outDesc.offset : 0, * outDu = outDQU ? outDQU + outDesc.offset : 0, @@ -84,21 +84,21 @@ OsdCpuEvalLimitController::EvalLimitSample( OpenSubdiv::OsdEvalCoords const & co case FarPatchTables::REGULAR : evalBSpline( v, u, cvs, vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, outDesc, out, outDu, outDv ); break; case FarPatchTables::BOUNDARY : evalBoundary( v, u, cvs, vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, outDesc, out, outDu, outDv ); break; case FarPatchTables::CORNER : evalCorner( v, u, cvs, vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, outDesc, out, outDu, outDv ); break; @@ -109,7 +109,7 @@ OsdCpuEvalLimitController::EvalLimitSample( OpenSubdiv::OsdEvalCoords const & co &context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ], context->GetMaxValence(), vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, outDesc, out, outDu, outDv ); break; @@ -120,7 +120,7 @@ OsdCpuEvalLimitController::EvalLimitSample( OpenSubdiv::OsdEvalCoords const & co &context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ], context->GetMaxValence(), vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, outDesc, out, outDu, outDv ); break; @@ -154,39 +154,38 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c unsigned int const * cvs = &context->GetControlVertices()[ parray.GetVertIndex() + handle->vertexOffset ]; - OsdCpuEvalLimitContext::VertexData & vertexData = context->GetVertexData(); + VertexData const & vertexData = _currentBindState.vertexData; - if (vertexData.IsBound()) { + if (vertexData.in) { int offset = vertexData.outDesc.stride * index; + if (vertexData.out) { - if (vertexData.IsBound()) { - - float * out = vertexData.out.GetData()+offset, - * outDu = vertexData.outDu.IsBound() ? vertexData.outDu.GetData()+offset : 0, - * outDv = vertexData.outDv.IsBound() ? vertexData.outDv.GetData()+offset : 0; + float * out = vertexData.out+offset, + * outDu = vertexData.outDu ? vertexData.outDu+offset : 0, + * outDv = vertexData.outDv ? vertexData.outDv+offset : 0; // Based on patch type - go execute interpolation switch( parray.GetDescriptor().GetType() ) { case FarPatchTables::REGULAR : evalBSpline( v, u, cvs, vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, vertexData.outDesc, out, outDu, outDv ); break; case FarPatchTables::BOUNDARY : evalBoundary( v, u, cvs, vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, vertexData.outDesc, out, outDu, outDv ); break; case FarPatchTables::CORNER : evalCorner( v, u, cvs, vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, vertexData.outDesc, out, outDu, outDv ); break; @@ -197,7 +196,7 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c &context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ], context->GetMaxValence(), vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, vertexData.outDesc, out, outDu, outDv ); break; @@ -208,7 +207,7 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c &context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ], context->GetMaxValence(), vertexData.inDesc, - vertexData.in.GetData(), + vertexData.in, vertexData.outDesc, out, outDu, outDv ); break; @@ -219,9 +218,9 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c } } - OsdCpuEvalLimitContext::VaryingData & varyingData = context->GetVaryingData(); + VaryingData const & varyingData = _currentBindState.varyingData; - if (varyingData.IsBound()) { + if (varyingData.in and varyingData.out) { static int indices[5][4] = { {5, 6,10, 9}, // regular {1, 2, 6, 5}, // boundary @@ -240,9 +239,9 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c evalBilinear( v, u, zeroRing, varyingData.inDesc, - varyingData.in.GetData(), + varyingData.in, varyingData.outDesc, - varyingData.out.GetData()+offset); + varyingData.out+offset); } @@ -250,22 +249,24 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c // for face-varying data. Although Hbr supports 3 additional smooth rule // sets, the feature-adaptive patch interpolation code currently does not // support them, and neither does this EvalContext. - OsdCpuEvalLimitContext::FaceVaryingData & faceVaryingData = context->GetFaceVaryingData(); - if (faceVaryingData.IsBound()) { + + FacevaryingData const & facevaryingData = _currentBindState.facevaryingData; + + if (facevaryingData.out) { std::vector const & fvarData = context->GetFVarData(); if (not fvarData.empty()) { - int offset = faceVaryingData.outDesc.stride * index; + int offset = facevaryingData.outDesc.stride * index; static unsigned int zeroRing[4] = {0,1,2,3}; evalBilinear( v, u, zeroRing, - faceVaryingData.inDesc, + facevaryingData.inDesc, &fvarData[ handle->patchIdx * 4 * context->GetFVarWidth() ], - faceVaryingData.outDesc, - faceVaryingData.out.GetData()+offset); + facevaryingData.outDesc, + facevaryingData.out+offset); } } diff --git a/opensubdiv/osd/cpuEvalLimitController.h b/opensubdiv/osd/cpuEvalLimitController.h index e9c91f6e..31ba15ae 100644 --- a/opensubdiv/osd/cpuEvalLimitController.h +++ b/opensubdiv/osd/cpuEvalLimitController.h @@ -39,6 +39,23 @@ namespace OPENSUBDIV_VERSION { /// A CPU-driven controller that can be called to evaluate samples on the limit /// surface for a given EvalContext. /// +/// Warning : this eval controller is re-entrant but it breaks the Osd API pattern +/// by requiring client code to bind and unbind the data buffers to the +/// Controller before calling evaluation methods. +/// +/// Ex : +/// \code +/// evalCtroller->BindVertexBuffers( ... ); +/// evalCtroller->BindVaryingBuffers( ... ); +/// evalCtroller->BindFacevaryingBuffers( ... ); +/// +/// parallel_for( int index=0; iEvalLimitSample( coord, evalCtxt, index ); +/// } +/// +/// evalCtroller->Unbind(); +/// \endcode +/// class OsdCpuEvalLimitController { public: @@ -54,13 +71,83 @@ public: float u,v; // local u,v }; + /// \brief Binds control vertex data buffer + /// + /// @param iDesc data descriptor shared by all input data buffers + /// + /// @param inQ input vertex data + /// + /// @param oDesc data descriptor shared by all output data buffers + /// + /// @param outQ output vertex data + /// + /// @param outdQu output derivative along "u" of the vertex data (optional) + /// + /// @param outdQv output derivative along "v" of the vertex data (optional) + /// + template + void BindVertexBuffers( OsdVertexBufferDescriptor const & iDesc, INPUT_BUFFER *inQ, + OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ, + OUTPUT_BUFFER *outdQu=0, + OUTPUT_BUFFER *outdQv=0 ) { + _currentBindState.vertexData.inDesc = iDesc; + _currentBindState.vertexData.in = inQ ? inQ->BindCpuBuffer() : 0; + + _currentBindState.vertexData.outDesc = oDesc; + _currentBindState.vertexData.out = outQ ? outQ->BindCpuBuffer() : 0; + _currentBindState.vertexData.outDu = outdQu ? outdQu->BindCpuBuffer() : 0; + _currentBindState.vertexData.outDv = outdQv ? outdQv->BindCpuBuffer() : 0; + } + + /// \brief Binds the varying-interpolated data streams + /// + /// @param iDesc data descriptor shared by all input data buffers + /// + /// @param inQ input varying data + /// + /// @param oDesc data descriptor shared by all output data buffers + /// + /// @param outQ output varying data + /// + template + void BindVaryingBuffers( OsdVertexBufferDescriptor const & iDesc, INPUT_BUFFER *inQ, + OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) { + _currentBindState.varyingData.inDesc = iDesc; + _currentBindState.varyingData.in = inQ ? inQ->BindCpuBuffer() : 0; + + _currentBindState.varyingData.outDesc = oDesc; + _currentBindState.varyingData.out = outQ ? outQ->BindCpuBuffer() : 0; + } + + /// \brief Binds the face-varying-interpolated data streams + /// + /// Note : currently we only support bilinear boundary interpolation rules + /// for face-varying data. Although Hbr supports 3 addition smooth rule sets, + /// the feature-adaptive patch interpolation code currently does not support + /// them, and neither does this EvalContext + /// + /// @param iDesc data descriptor shared by all input data buffers + /// + /// @param oDesc data descriptor shared by all output data buffers + /// + /// @param outQ output face-varying data + /// + template + void BindFacevaryingBuffers( OsdVertexBufferDescriptor const & iDesc, + OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) { + _currentBindState.facevaryingData.inDesc = iDesc; + + _currentBindState.facevaryingData.outDesc = oDesc; + _currentBindState.facevaryingData.out = outQ ? outQ->BindCpuBuffer() : 0; + } /// \brief Vertex interpolation of a single sample at the limit /// /// Evaluates "vertex" interpolation of a single sample on the surface limit. /// - /// This function is re-entrant and does not require the context to bind - /// output vertex buffers. + /// This function is re-entrant but does not require binding the + /// output vertex buffers. Pointers to memory where the data is + /// output are explicitly passed to the function. /// /// @param coords location on the limit surface to be evaluated /// @@ -68,6 +155,12 @@ public: /// /// @param outDesc data descriptor (offset, length, stride) /// + /// @param outQ output vertex data + /// + /// @param outdQu output derivative along "u" of the vertex data (optional) + /// + /// @param outdQv output derivative along "v" of the vertex data (optional) + /// /// @return 1 if the sample was found /// int EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coord, @@ -77,27 +170,10 @@ public: float * outDQU, float * outDQV ) const; - - /// \brief Vertex interpolation of samples at the limit /// /// Evaluates "vertex" interpolation of a sample on the surface limit. /// - /// Warning : this function is re-entrant but it breaks the Osd API pattern - /// by requiring the client code to bind and unbind the vertex buffers to - /// the EvalLimitContext. - /// - /// Ex : - /// \code - /// evalCtxt->BindVertexBuffers( ... ); - /// - /// parallel_for( int index=0; iEvalLimitSample( coord, evalCtxt, index ); - /// } - /// - /// evalCtxt->UnbindVertexBuffers(); - /// \endcode - /// /// @param coords location on the limit surface to be evaluated /// /// @param context the EvalLimitContext that the controller will evaluate @@ -108,7 +184,6 @@ public: /// @return the number of samples found (0 if the location was tagged as a hole /// or the coordinate was invalid) /// - template int EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords, OsdCpuEvalLimitContext * context, unsigned int index ) const { @@ -120,12 +195,92 @@ public: return n; } + void Unbind() { + _currentBindState.Reset(); + } + +protected: + + + // Vertex interpolated streams + struct VertexData { + + VertexData() : in(0), out(0), outDu(0), outDv(0) { } + + + void Reset() { + in = out = outDu = outDv = NULL; + inDesc.Reset(); + outDesc.Reset(); + } + + OsdVertexBufferDescriptor inDesc, + outDesc; + float * in, + * out, + * outDu, + * outDv; + }; + + // Varying interpolated streams + struct VaryingData { + + VaryingData() : in(0), out(0) { } + + + void Reset() { + in = out = NULL; + inDesc.Reset(); + outDesc.Reset(); + } + + OsdVertexBufferDescriptor inDesc, + outDesc; + float * in, + * out; + }; + + // Facevarying interpolated streams + struct FacevaryingData { + + FacevaryingData() : out(0) { } + + void Reset() { + out = NULL; + inDesc.Reset(); + outDesc.Reset(); + } + + OsdVertexBufferDescriptor inDesc, + outDesc; + float * out; + }; + + private: int _EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords, OsdCpuEvalLimitContext * context, unsigned int index ) const; + // Bind state is a transitional state during refinement. + // It doesn't take an ownership of vertex buffers. + struct BindState { + + BindState() { } + + void Reset() { + vertexData.Reset(); + varyingData.Reset(); + facevaryingData.Reset(); + } + + VertexData vertexData; // vertex interpolated data descriptor + VaryingData varyingData; // varying interpolated data descriptor + FacevaryingData facevaryingData; // face-varying interpolated data descriptor + }; + + BindState _currentBindState; }; } // end namespace OPENSUBDIV_VERSION diff --git a/opensubdiv/osdutil/adaptiveEvaluator.cpp b/opensubdiv/osdutil/adaptiveEvaluator.cpp index 24521925..cfde931c 100644 --- a/opensubdiv/osdutil/adaptiveEvaluator.cpp +++ b/opensubdiv/osdutil/adaptiveEvaluator.cpp @@ -156,14 +156,6 @@ OsdUtilAdaptiveEvaluator::Initialize( _evalLimitContext = OsdCpuEvalLimitContext::Create( fmesh->GetPatchTables(), /*requierFVarData*/ false); - // Setup evaluation context. Values are offset, length, stride */ - OsdVertexBufferDescriptor in_desc(0, 3, 3), out_desc(0, 0, 0); - - OsdCpuEvalLimitContext::VertexData & vertexData = - _evalLimitContext->GetVertexData(); - - vertexData.Bind(in_desc, _vertexBuffer, out_desc, NULL); - return true; } @@ -216,6 +208,11 @@ OsdUtilAdaptiveEvaluator::EvaluateLimit( OsdCpuEvalLimitController cpuEvalLimitController; static OsdVertexBufferDescriptor desc(0,3,3); + + // Setup evaluation controller. Values are offset, length, stride */ + OsdVertexBufferDescriptor in_desc(0, 3, 3), out_desc(0, 0, 0); + + cpuEvalLimitController.BindVertexBuffers(in_desc, _vertexBuffer, out_desc, NULL); cpuEvalLimitController.EvalLimitSample(coords, _evalLimitContext, desc, P, dPdu, dPdv); }