diff --git a/examples/glBatchViewer/delegate.cpp b/examples/glBatchViewer/delegate.cpp index 5b92a315..dc95f418 100644 --- a/examples/glBatchViewer/delegate.cpp +++ b/examples/glBatchViewer/delegate.cpp @@ -73,11 +73,11 @@ #include "delegate.h" MyDrawContext::MyDrawContext() { - glGenVertexArrays(1, &vao); + glGenVertexArrays(1, &_vao); } MyDrawContext::~MyDrawContext() { - glDeleteVertexArrays(1, &vao); + glDeleteVertexArrays(1, &_vao); } MyDrawContext* @@ -113,57 +113,68 @@ MyDrawContext::Create(OpenSubdiv::FarPatchTables const *patchTables, bool requir // ---------------------------------------------------------------------------- void -MyDrawDelegate::BindBatch(OpenSubdiv::OsdUtilMeshBatchBase *batch) { +MyDrawDelegate::Bind(OpenSubdiv::OsdUtilMeshBatchBase *batch, EffectHandle const &effect) { - MyDrawContext *drawContext = batch->GetDrawContext(); + if (batch != _currentBatch) { + // bind batch + _currentBatch = batch; + MyDrawContext *drawContext = batch->GetDrawContext(); - // bind vao - glBindVertexArray(drawContext->vao); + // bind vao + glBindVertexArray(drawContext->GetVertexArray()); - // bind vbo state - // glBindVertexArray(batch->vao); - glBindBuffer(GL_ARRAY_BUFFER, batch->BindVertexBuffer()); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawContext->patchIndexBuffer); + // bind vbo state + // glBindVertexArray(batch->vao); + glBindBuffer(GL_ARRAY_BUFFER, batch->BindVertexBuffer()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawContext->patchIndexBuffer); - // vertex attrib - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0); + // vertex attrib + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0); - // bind other builtin texture buffers - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_BUFFER, drawContext->vertexTextureBuffer); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_BUFFER, drawContext->vertexValenceTextureBuffer); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_BUFFER, drawContext->quadOffsetTextureBuffer); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_BUFFER, drawContext->ptexCoordinateTextureBuffer); + // bind other builtin texture buffers + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_BUFFER, drawContext->vertexTextureBuffer); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_BUFFER, drawContext->vertexValenceTextureBuffer); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_BUFFER, drawContext->quadOffsetTextureBuffer); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_BUFFER, drawContext->ptexCoordinateTextureBuffer); + } + if (effect != _currentEffect) { + _currentEffect = effect; + + // bind effect + } } void -MyDrawDelegate::UnbindBatch(OpenSubdiv::OsdUtilMeshBatchBase *batch) { +MyDrawDelegate::Unbind(OpenSubdiv::OsdUtilMeshBatchBase *batch, EffectHandle const &effect) { + // does nothing +} +void +MyDrawDelegate::Begin() { + _currentBatch = NULL; + _currentEffect = NULL; +} + +void +MyDrawDelegate::End() { + _currentBatch = NULL; + _currentEffect = NULL; glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void -MyDrawDelegate::BindEffect(MyEffect &effect) { - // cross-patch state - // bind ptex etc -} - -void -MyDrawDelegate::UnbindEffect(MyEffect &effect) { -} - -void -MyDrawDelegate::DrawElements(MyEffect &effect, OpenSubdiv::OsdDrawContext::PatchArray const &patchArray) { +MyDrawDelegate::DrawElements(OpenSubdiv::OsdDrawContext::PatchArray const &patchArray) { // bind patchType-wise effect state // can be skipped (if config is not changed) - MyDrawConfig *config = GetDrawConfig(effect, patchArray.GetDescriptor()); + MyDrawConfig *config = GetDrawConfig(_currentEffect, patchArray.GetDescriptor()); GLuint program = config->program; @@ -176,7 +187,7 @@ MyDrawDelegate::DrawElements(MyEffect &effect, OpenSubdiv::OsdDrawContext::Patch } // apply patch color - effect.BindDrawConfig(config, patchArray.GetDescriptor()); + _currentEffect->BindDrawConfig(config, patchArray.GetDescriptor()); glUniform1i(config->levelBaseUniform, patchArray.GetPatchIndex()); if (patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::GREGORY || @@ -196,8 +207,13 @@ MyDrawDelegate::DrawElements(MyEffect &effect, OpenSubdiv::OsdDrawContext::Patch _numDrawCalls++; } -MyDrawConfig * -MyDrawDelegate::GetDrawConfig(MyEffect &effect, OpenSubdiv::OsdDrawContext::PatchDescriptor desc) { - - return _effectRegistry.GetDrawConfig(effect.GetEffectDescriptor(), desc); +bool +MyDrawDelegate::IsCombinable(EffectHandle const &a, EffectHandle const &b) const { + return a == b; +} + +MyDrawConfig * +MyDrawDelegate::GetDrawConfig(EffectHandle &effect, OpenSubdiv::OsdDrawContext::PatchDescriptor desc) { + + return _effectRegistry.GetDrawConfig(effect->GetEffectDescriptor(), desc); } diff --git a/examples/glBatchViewer/delegate.h b/examples/glBatchViewer/delegate.h index ff00b705..a4c0cc72 100644 --- a/examples/glBatchViewer/delegate.h +++ b/examples/glBatchViewer/delegate.h @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include "effect.h" #include "effectRegistry.h" @@ -74,30 +74,39 @@ public: static MyDrawContext *Create(OpenSubdiv::FarPatchTables const *patchTables, bool requireFVarData=false); -//private: - GLuint vao; + + GLuint GetVertexArray() const { return _vao; } private: MyDrawContext(); + GLuint _vao; }; class MyDrawDelegate { public: - void BindBatch(OpenSubdiv::OsdUtilMeshBatchBase *batch); - void UnbindBatch(OpenSubdiv::OsdUtilMeshBatchBase *batch); - void BindEffect(MyEffect &effect); - void UnbindEffect(MyEffect &effect); - void DrawElements(MyEffect &effect, OpenSubdiv::OsdDrawContext::PatchArray const &patchArray); + typedef MyEffect * EffectHandle; + + void Bind(OpenSubdiv::OsdUtilMeshBatchBase *batch, EffectHandle const &effect); + void Unbind(OpenSubdiv::OsdUtilMeshBatchBase *batch, EffectHandle const &effect); + + void Begin(); + void End(); + + void DrawElements(OpenSubdiv::OsdDrawContext::PatchArray const &patchArray); + + bool IsCombinable(EffectHandle const &a, EffectHandle const &b) const; void ResetNumDrawCalls() { _numDrawCalls = 0; } int GetNumDrawCalls() const { return _numDrawCalls; } private: - MyDrawConfig *GetDrawConfig(MyEffect &effect, OpenSubdiv::OsdDrawContext::PatchDescriptor desc); + MyDrawConfig *GetDrawConfig(EffectHandle &effect, OpenSubdiv::OsdDrawContext::PatchDescriptor desc); MyEffectRegistry _effectRegistry; int _numDrawCalls; + OpenSubdiv::OsdUtilMeshBatchBase *_currentBatch; + EffectHandle _currentEffect; }; #endif /* DELEGATE_H */ diff --git a/examples/glBatchViewer/viewer.cpp b/examples/glBatchViewer/viewer.cpp index b9c3a98c..79104a6e 100644 --- a/examples/glBatchViewer/viewer.cpp +++ b/examples/glBatchViewer/viewer.cpp @@ -130,10 +130,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include "delegate.h" #include "effect.h" @@ -443,47 +443,48 @@ rebuild() delete g_batch; g_batch = NULL; + int numVertexElements = 3, numVaryingElements = 0; + // create multimesh batch if (g_kernel == kCPU) { g_batch = OpenSubdiv::OsdUtilMeshBatch::Create( Controller::GetInstance(), - farMeshes, 0); + farMeshes, numVertexElements, numVaryingElements, 0); #ifdef OPENSUBDIV_HAS_OPENMP } else if (g_kernel == kOPENMP) { g_batch = OpenSubdiv::OsdUtilMeshBatch::Create( Controller::GetInstance(), - farMeshes, 0); + farMeshes, numVertexElements, numVaryingElements, 0); #endif #ifdef OPENSUBDIV_HAS_OPENCL } else if (g_kernel == kCL) { g_batch = OpenSubdiv::OsdUtilMeshBatch::Create( Controller::GetInstance(), - farMeshes, 0); + farMeshes, numVertexElements, numVaryingElements, 0); #endif #ifdef OPENSUBDIV_HAS_CUDA } else if (g_kernel == kCUDA) { g_batch = OpenSubdiv::OsdUtilMeshBatch::Create( Controller::GetInstance(), - farMeshes, 0); + farMeshes, numVertexElements, numVaryingElements, 0); #endif #ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK } else if (g_kernel == kGLSL) { g_batch = OpenSubdiv::OsdUtilMeshBatch::Create( Controller::GetInstance(), - farMeshes, 0); + farMeshes, numVertexElements, numVaryingElements, 0); #endif } else { assert(false); } assert(g_batch); - g_batch->InitializeVertexBuffers(/*numVertexElements=*/3, /*numVaryingElements=*/0); g_scheme = scheme; @@ -536,8 +537,8 @@ display() { Stopwatch s; s.Start(); - OpenSubdiv::OsdUtilDrawItem::Collection items; - OpenSubdiv::OsdUtilDrawItem::Collection cachedDrawItems; + OpenSubdiv::OsdUtilDrawItem::Collection items; + OpenSubdiv::OsdUtilDrawItem::Collection cachedDrawItems; int numModels = g_modelCount*g_modelCount; items.reserve(numModels); @@ -545,13 +546,13 @@ display() { for (int i = 0; i < numModels; ++i) { // Here, client can pack arbitrary mesh and effect into drawItems. - items.push_back(OpenSubdiv::OsdUtilDrawItem( - g_batch, g_effect, g_batch->GetPatchArrays(i))); + items.push_back(OpenSubdiv::OsdUtilDrawItem( + g_batch, &g_effect, g_batch->GetPatchArrays(i))); } if (g_batching) { // create cached draw items - OpenSubdiv::OsdUtil::OptimizeDrawItem(items, cachedDrawItems); + OpenSubdiv::OsdUtil::OptimizeDrawItem(items, cachedDrawItems, &g_drawDelegate); } s.Stop(); diff --git a/opensubdiv/CMakeLists.txt b/opensubdiv/CMakeLists.txt index 3ee406f6..05cceaad 100644 --- a/opensubdiv/CMakeLists.txt +++ b/opensubdiv/CMakeLists.txt @@ -65,7 +65,7 @@ add_subdirectory(far) add_subdirectory(osd) -add_subdirectory(osd_util) +add_subdirectory(osdutil) install( FILES version.h DESTINATION include/ diff --git a/opensubdiv/osd_util/meshHandle.h b/opensubdiv/osd_util/meshHandle.h deleted file mode 100644 index 6090cc08..00000000 --- a/opensubdiv/osd_util/meshHandle.h +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright (C) Pixar. All rights reserved. -// -// This license governs use of the accompanying software. If you -// use the software, you accept this license. If you do not accept -// the license, do not use the software. -// -// 1. Definitions -// The terms "reproduce," "reproduction," "derivative works," and -// "distribution" have the same meaning here as under U.S. -// copyright law. A "contribution" is the original software, or -// any additions or changes to the software. -// A "contributor" is any person or entity that distributes its -// contribution under this license. -// "Licensed patents" are a contributor's patent claims that read -// directly on its contribution. -// -// 2. Grant of Rights -// (A) Copyright Grant- Subject to the terms of this license, -// including the license conditions and limitations in section 3, -// each contributor grants you a non-exclusive, worldwide, -// royalty-free copyright license to reproduce its contribution, -// prepare derivative works of its contribution, and distribute -// its contribution or any derivative works that you create. -// (B) Patent Grant- Subject to the terms of this license, -// including the license conditions and limitations in section 3, -// each contributor grants you a non-exclusive, worldwide, -// royalty-free license under its licensed patents to make, have -// made, use, sell, offer for sale, import, and/or otherwise -// dispose of its contribution in the software or derivative works -// of the contribution in the software. -// -// 3. Conditions and Limitations -// (A) No Trademark License- This license does not grant you -// rights to use any contributor's name, logo, or trademarks. -// (B) If you bring a patent claim against any contributor over -// patents that you claim are infringed by the software, your -// patent license from such contributor to the software ends -// automatically. -// (C) If you distribute any portion of the software, you must -// retain all copyright, patent, trademark, and attribution -// notices that are present in the software. -// (D) If you distribute any portion of the software in source -// code form, you may do so only under this license by including a -// complete copy of this license with your distribution. If you -// distribute any portion of the software in compiled or object -// code form, you may only do so under a license that complies -// with this license. -// (E) The software is licensed "as-is." You bear the risk of -// using it. The contributors give no express warranties, -// guarantees or conditions. You may have additional consumer -// rights under your local laws which this license cannot change. -// To the extent permitted under your local laws, the contributors -// exclude the implied warranties of merchantability, fitness for -// a particular purpose and non-infringement. -// -#ifndef OSD_UTIL_MESH_HANDLE_H -#define OSD_UTIL_MESH_HANDLE_H - -#include "../version.h" -#include - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { - -struct OsdUtilMeshHandle { -public: - typedef std::vector Collection; - - OsdUtilMeshHandle(int batchIndex_, int meshIndex_) : - batchIndex(batchIndex_), meshIndex(meshIndex_) {} - - int batchIndex; - int meshIndex; -}; - -} // end namespace OPENSUBDIV_VERSION -using namespace OPENSUBDIV_VERSION; - -} // end namespace OpenSubdiv - -#endif /* OSD_UTIL_MESH_HANDLE_H */ diff --git a/opensubdiv/osd_util/CMakeLists.txt b/opensubdiv/osdutil/CMakeLists.txt similarity index 98% rename from opensubdiv/osd_util/CMakeLists.txt rename to opensubdiv/osdutil/CMakeLists.txt index e5386bdf..02bd8274 100644 --- a/opensubdiv/osd_util/CMakeLists.txt +++ b/opensubdiv/osdutil/CMakeLists.txt @@ -67,7 +67,6 @@ include_directories( set(PUBLIC_HEADER_FILES batch.h batchCL.h - meshHandle.h drawItem.h drawController.h ) @@ -76,7 +75,7 @@ set(PUBLIC_HEADER_FILES # platform dependent tweaks install( FILES ${PUBLIC_HEADER_FILES} - DESTINATION include/osd_util + DESTINATION include/osdutil PERMISSIONS OWNER_READ GROUP_READ WORLD_READ ) if (ANDROID) diff --git a/opensubdiv/osd_util/batch.h b/opensubdiv/osdutil/batch.h similarity index 81% rename from opensubdiv/osd_util/batch.h rename to opensubdiv/osdutil/batch.h index 281031c5..16761b67 100644 --- a/opensubdiv/osd_util/batch.h +++ b/opensubdiv/osdutil/batch.h @@ -54,8 +54,8 @@ // exclude the implied warranties of merchantability, fitness for // a particular purpose and non-infringement. // -#ifndef OSD_UTIL_MESH_BATCH_H -#define OSD_UTIL_MESH_BATCH_H +#ifndef OSDUTIL_MESH_BATCH_H +#define OSDUTIL_MESH_BATCH_H #include "../version.h" #include "../far/multiMeshFactory.h" @@ -107,9 +107,6 @@ public: OsdDrawContext::PatchArrayVector const & GetPatchArrays(int meshIndex) const { return _entries[meshIndex].patchArrays; } - // vertex buffer initializer - virtual void InitializeVertexBuffers(int numVertexElements, int numVaryingElements) = 0; - // update APIs virtual void UpdateCoarseVertices(int meshIndex, const float *ptrs, int numVertices) = 0; virtual void FinalizeUpdate() = 0; @@ -121,14 +118,17 @@ public: int GetNumPtexFaces() const { return _numPtexFaces; } protected: - OsdUtilMeshBatchBase(OsdUtilMeshBatchEntryVector const & entries, int numVertices, int numPtexFaces, int batchIndex); + OsdUtilMeshBatchBase(OsdUtilMeshBatchEntryVector const & entries, + int numVertices, + int numPtexFaces, + int numVertexElements, + int batchIndex); void setKernelBatches(FarKernelBatchVector const &batches); void setMeshDirty(int meshIndex); void resetMeshDirty(); - void updatePatchArrays(int numVertexElements); - void populateKernelBatches(FarKernelBatchVector &result); + void populateDirtyKernelBatches(FarKernelBatchVector &result); private: // compute batch @@ -138,7 +138,7 @@ private: OsdUtilMeshBatchEntryVector _entries; // update flags - std::vector _dirtyFlags; + std::vector _dirtyFlags; // same size as _entries int _numVertices; int _numPtexFaces; @@ -163,6 +163,8 @@ public: // XXX: not happy with retaining compute controller.. static OsdUtilMeshBatch *Create(ComputeController *computeController, std::vector const * > const &meshVector, + int numVertexElements, + int numVaryingElements, int batchIndex); // constructor (for client defined arbitrary patches) @@ -170,12 +172,12 @@ public: OsdUtilMeshBatchEntryVector const &entries, int numVertices, int numPtexFaces, + int numVertexElements, + int numVaryingElements, int batchIndex); virtual ~OsdUtilMeshBatch(); - virtual void InitializeVertexBuffers(int numVertexElements, int numVaryingElements); - virtual typename DrawContext::VertexBufferBinding BindVertexBuffer() { return _vertexBuffer->BindVBO(); } virtual DrawContext * GetDrawContext() const { return _drawContext; } @@ -195,7 +197,7 @@ public: return; FarKernelBatchVector batches; - Base::populateKernelBatches(batches); + Base::populateDirtyKernelBatches(batches); Base::resetMeshDirty(); _computeController->Refine(_computeContext, batches, _vertexBuffer); @@ -209,11 +211,17 @@ private: OsdUtilMeshBatch(ComputeController *computeController, OsdUtilMeshBatchEntryVector const &entries, FarMesh const *farMultiMesh, + int numVertexElements, + int numVaryingElements, int batchIndex); OsdUtilMeshBatch(FarPatchTables const *patchTables, OsdUtilMeshBatchEntryVector const &entries, - int numVertices, int numPtexFaces, int batchIndex); + int numVertices, + int numPtexFaces, + int numVertexElements, + int numVaryingElements, + int batchIndex); ComputeController *_computeController; ComputeContext *_computeContext; @@ -224,9 +232,22 @@ private: // ----------------------------------------------------------------------------- template - OsdUtilMeshBatchBase::OsdUtilMeshBatchBase(OsdUtilMeshBatchEntryVector const & entries, int numVertices, int numPtexFaces, int batchIndex) : +OsdUtilMeshBatchBase::OsdUtilMeshBatchBase(OsdUtilMeshBatchEntryVector const & entries, + int numVertices, + int numPtexFaces, + int numVertexElements, + int batchIndex) : _entries(entries), _numVertices(numVertices), _numPtexFaces(numPtexFaces), _batchIndex(batchIndex) { + // update patcharrays in entries + for (int i = 0; i < (int)_entries.size(); ++i) { + for (int j = 0; j < (int)_entries[i].patchArrays.size(); ++j) { + OsdDrawContext::PatchDescriptor desc = _entries[i].patchArrays[j].GetDescriptor(); + desc.SetNumElements(numVertexElements); + _entries[i].patchArrays[j].SetDescriptor(desc); + } + } + // init dirty flags _dirtyFlags.resize(entries.size()); resetMeshDirty(); @@ -254,18 +275,7 @@ OsdUtilMeshBatchBase::setKernelBatches(FarKernelBatchVector const } template void -OsdUtilMeshBatchBase::updatePatchArrays(int numVertexElements) { - for (int i = 0; i < (int)_entries.size(); ++i) { - for (int j = 0; j < (int)_entries[i].patchArrays.size(); ++j) { - OsdDrawContext::PatchDescriptor desc = _entries[i].patchArrays[j].GetDescriptor(); - desc.SetNumElements(numVertexElements); - _entries[i].patchArrays[j].SetDescriptor(desc); - } - } -} - -template void -OsdUtilMeshBatchBase::populateKernelBatches(FarKernelBatchVector &result) { +OsdUtilMeshBatchBase::populateDirtyKernelBatches(FarKernelBatchVector &result) { result.clear(); for (FarKernelBatchVector::const_iterator it = _allKernelBatches.begin(); @@ -297,7 +307,7 @@ createEntries(OsdUtilMeshBatchEntryVector &result, int maxValence, std::vector const * > const & meshVector) { - // create osd patch array per mesh (note: numVertexElements will be updated later on InitializeVertexBuffers) + // create osd patch array per mesh (note: numVertexElements will be updated later) int numEntries = (int)multiFarPatchArray.size(); result.resize(numEntries); for (int i = 0; i < numEntries; ++i) { @@ -326,10 +336,13 @@ OsdUtilMeshBatch:: OsdUtilMeshBatch(ComputeController *computeController, OsdUtilMeshBatchEntryVector const &entries, FarMesh const *farMultiMesh, + int numVertexElements, + int numVaryingElements, int batchIndex) : OsdUtilMeshBatchBase(entries, farMultiMesh->GetNumVertices(), farMultiMesh->GetNumPtexFaces(), + numVertexElements, batchIndex), _computeController(computeController), _computeContext(NULL), _vertexBuffer(NULL), _varyingBuffer(NULL), _drawContext(NULL) { @@ -342,8 +355,11 @@ OsdUtilMeshBatch(ComputeController *computeController, FarPatchTables const * patchTables = farMultiMesh->GetPatchTables(); - // create drawcontext + _vertexBuffer = numVertexElements ? VertexBuffer::Create(numVertexElements, Base::GetNumVertices()) : NULL; + _varyingBuffer = numVaryingElements ? VertexBuffer::Create(numVaryingElements, Base::GetNumVertices()) : NULL; + _drawContext = DrawContext::Create(patchTables, /*fvar=*/false); + _drawContext->UpdateVertexTexture(_vertexBuffer); } // Constructor from patch table @@ -351,16 +367,23 @@ template :: OsdUtilMeshBatch(FarPatchTables const *patchTables, OsdUtilMeshBatchEntryVector const &entries, - int numVertices, int numPtexFaces, int batchIndex) : + int numVertices, int numPtexFaces, + int numVertexElements, + int numVaryingElements, + int batchIndex) : OsdUtilMeshBatchBase(entries, numVertices, numPtexFaces, + numVertexElements, batchIndex), _computeController(NULL), _computeContext(NULL), _vertexBuffer(NULL), _varyingBuffer(NULL), _drawContext(NULL) { - // create drawcontext + _vertexBuffer = numVertexElements ? VertexBuffer::Create(numVertexElements, numVertices) : NULL; + _varyingBuffer = numVaryingElements ? VertexBuffer::Create(numVaryingElements, numVertices) : NULL; + _drawContext = DrawContext::Create(patchTables, /*fvar=*/false); + _drawContext->UpdateVertexTexture(_vertexBuffer); } template @@ -375,7 +398,10 @@ OsdUtilMeshBatch::~OsdUtilMeshB template OsdUtilMeshBatch * OsdUtilMeshBatch::Create(ComputeController *computeController, - const std::vector const * > &meshVector, int batchIndex) + const std::vector const * > &meshVector, + int numVertexElements, + int numVaryingElements, + int batchIndex) { std::vector multiFarPatchArray; FarMesh *farMultiMesh = createMultiMesh(meshVector, multiFarPatchArray); @@ -388,7 +414,7 @@ OsdUtilMeshBatch::Create(Comput OsdUtilMeshBatch *batch = new OsdUtilMeshBatch( - computeController, entries, farMultiMesh, batchIndex); + computeController, entries, farMultiMesh, numVertexElements, numVaryingElements, batchIndex); delete farMultiMesh; @@ -398,33 +424,23 @@ OsdUtilMeshBatch::Create(Comput template OsdUtilMeshBatch * OsdUtilMeshBatch::Create(FarPatchTables const *patchTables, - OsdUtilMeshBatchEntryVector const &entries, int numVertices, int numPtexFaces, int batchIndex) + OsdUtilMeshBatchEntryVector const &entries, + int numVertices, + int numPtexFaces, + int numVertexElements, + int numVaryingElements, + int batchIndex) { OsdUtilMeshBatch *batch = new OsdUtilMeshBatch( - patchTables, entries, numVertices, numPtexFaces, batchIndex); + patchTables, entries, numVertices, numPtexFaces, numVertexElements, numVaryingElements, batchIndex); return batch; } -template void -OsdUtilMeshBatch::InitializeVertexBuffers(int numVertexElements, int numVaryingElements) { - - delete _vertexBuffer; - delete _varyingBuffer; - - _vertexBuffer = numVertexElements ? VertexBuffer::Create(numVertexElements, Base::GetNumVertices()) : NULL; - _varyingBuffer = numVaryingElements ? VertexBuffer::Create(numVaryingElements, Base::GetNumVertices()) : NULL; - - _drawContext->UpdateVertexTexture(_vertexBuffer); - - // update patch arrays - Base::updatePatchArrays(numVertexElements); -} - } // end namespace OPENSUBDIV_VERSION using namespace OPENSUBDIV_VERSION; } // end namespace OpenSubdiv -#endif /* OSD_UTIL_MESH_BATCH_H */ +#endif /* OSDUTIL_MESH_BATCH_H */ diff --git a/opensubdiv/osd_util/batchCL.h b/opensubdiv/osdutil/batchCL.h similarity index 82% rename from opensubdiv/osd_util/batchCL.h rename to opensubdiv/osdutil/batchCL.h index e9a0a99b..aa0550b0 100644 --- a/opensubdiv/osd_util/batchCL.h +++ b/opensubdiv/osdutil/batchCL.h @@ -54,11 +54,11 @@ // exclude the implied warranties of merchantability, fitness for // a particular purpose and non-infringement. // -#ifndef OSD_UTIL_MESH_BATCH_CL_H -#define OSD_UTIL_MESH_BATCH_CL_H +#ifndef OSDUTIL_MESH_BATCH_CL_H +#define OSDUTIL_MESH_BATCH_CL_H #include "../version.h" -#include "../osd_util/batch.h" +#include "../osdutil/batch.h" #include "../osd/clComputeController.h" #include @@ -83,12 +83,12 @@ public: // XXX: not happy with retaining compute controller.. static OsdUtilMeshBatch* Create(ComputeController *computeController, const std::vector const * > &meshVector, + int numVertexElements, + int numVaryingElements, int batchIndex); virtual ~OsdUtilMeshBatch(); - virtual void InitializeVertexBuffers(int numVertexElements, int numVaryingElements); - virtual typename DrawContext::VertexBufferBinding BindVertexBuffer() { return _vertexBuffer->BindVBO(); } virtual DrawContext * GetDrawContext() const { return _drawContext; } @@ -105,7 +105,7 @@ public: // create kernel batch for dirty handles FarKernelBatchVector batches; - Base::populateKernelBatches(batches); + Base::populateDirtyKernelBatches(batches); Base::resetMeshDirty(); _computeController->Refine(_computeContext, batches, _vertexBuffer); @@ -120,10 +120,16 @@ private: OsdUtilMeshBatch(ComputeController *computeController, OsdUtilMeshBatchEntryVector const &entries, FarMesh const *farMultiMesh, + int numVertexElements, + int numVaryingElements, int batchIndex); OsdUtilMeshBatch(FarPatchTables const *patchTables, - int numVertices, int numPtexFaces, int batchIndex); + int numVertices, + int numPtexFaces, + int numVertexElements, + int numVaryingElements, + int batchIndex); ComputeController *_computeController; ComputeContext *_computeContext; @@ -140,10 +146,13 @@ OsdUtilMeshBatch:: OsdUtilMeshBatch(ComputeController *computeController, OsdUtilMeshBatchEntryVector const &entries, FarMesh const *farMultiMesh, + int numVertexElements, + int numVaryingElements, int batchIndex) : OsdUtilMeshBatchBase(entries, farMultiMesh->GetNumVertices(), farMultiMesh->GetNumPtexFaces(), + numVertexElements, batchIndex), _computeController(computeController), _computeContext(NULL), _vertexBuffer(NULL), _varyingBuffer(NULL), _drawContext(NULL) { @@ -156,23 +165,34 @@ OsdUtilMeshBatch(ComputeController *computeController, FarPatchTables const * patchTables = farMultiMesh->GetPatchTables(); - // create drawcontext + _vertexBuffer = numVertexElements ? VertexBuffer::Create(numVertexElements, Base::GetNumVertices(), _computeController->GetContext()) : NULL; + _varyingBuffer = numVaryingElements ? VertexBuffer::Create(numVaryingElements, Base::GetNumVertices(), _computeController->GetContext()) : NULL; + _drawContext = DrawContext::Create(patchTables, /*fvar=*/false); + _drawContext->UpdateVertexTexture(_vertexBuffer); } // Constructor from patch table template OsdUtilMeshBatch:: OsdUtilMeshBatch(FarPatchTables const *patchTables, - int numVertices, int numPtexFaces, int batchIndex) : + int numVertices, + int numPtexFaces, + int numVertexElements, + int numVaryingElements, + int batchIndex) : OsdUtilMeshBatchBase(numVertices, numPtexFaces, + numVertexElements, batchIndex), _computeController(NULL), _computeContext(NULL), _vertexBuffer(NULL), _varyingBuffer(NULL), _drawContext(NULL) { - // create drawcontext + _vertexBuffer = numVertexElements ? VertexBuffer::Create(numVertexElements, Base::GetNumVertices(), _computeController->GetContext()) : NULL; + _varyingBuffer = numVaryingElements ? VertexBuffer::Create(numVaryingElements, Base::GetNumVertices(), _computeController->GetContext()) : NULL; + _drawContext = DrawContext::Create(patchTables, /*fvar=*/false); + _drawContext->UpdateVertexTexture(_vertexBuffer); } template @@ -187,7 +207,10 @@ OsdUtilMeshBatch::~OsdUtilM template OsdUtilMeshBatch * OsdUtilMeshBatch::Create(ComputeController *computeController, - const std::vector const * > &meshVector, int batchIndex) + const std::vector const * > &meshVector, + int numVertexElements, + int numVaryingElements, + int batchIndex) { std::vector multiFarPatchArray; FarMesh *farMultiMesh = createMultiMesh(meshVector, multiFarPatchArray); @@ -200,28 +223,13 @@ OsdUtilMeshBatch::Create(Co OsdUtilMeshBatch *batch = new OsdUtilMeshBatch( - computeController, entries, farMultiMesh, batchIndex); + computeController, entries, farMultiMesh, numVertexElements, numVaryingElements, batchIndex); delete farMultiMesh; return batch; } -template void -OsdUtilMeshBatch::InitializeVertexBuffers(int numVertexElements, int numVaryingElements) { - - delete _vertexBuffer; - delete _varyingBuffer; - - _vertexBuffer = numVertexElements ? VertexBuffer::Create(numVertexElements, Base::GetNumVertices(), _computeController->GetContext()) : NULL; - _varyingBuffer = numVaryingElements ? VertexBuffer::Create(numVaryingElements, Base::GetNumVertices(), _computeController->GetContext()) : NULL; - - _drawContext->UpdateVertexTexture(_vertexBuffer); - - // update patch arrays - Base::updatePatchArrays(numVertexElements); -} - #endif /* OPENSUBDIV_HAS_OPENCL */ } // end namespace OPENSUBDIV_VERSION @@ -229,4 +237,4 @@ using namespace OPENSUBDIV_VERSION; } // end namespace OpenSubdiv -#endif /* OSD_UTIL_MESH_BATCH_H */ +#endif /* OSDUTIL_MESH_BATCH_H */ diff --git a/opensubdiv/osd_util/drawController.h b/opensubdiv/osdutil/drawController.h similarity index 80% rename from opensubdiv/osd_util/drawController.h rename to opensubdiv/osdutil/drawController.h index 6a3339b3..872f7203 100644 --- a/opensubdiv/osd_util/drawController.h +++ b/opensubdiv/osdutil/drawController.h @@ -54,8 +54,8 @@ // exclude the implied warranties of merchantability, fitness for // a particular purpose and non-infringement. // -#ifndef OSD_UTIL_DRAW_CONTROLLER_H -#define OSD_UTIL_DRAW_CONTROLLER_H +#ifndef OSDUTIL_DRAW_CONTROLLER_H +#define OSDUTIL_DRAW_CONTROLLER_H #include "../version.h" @@ -65,9 +65,11 @@ namespace OPENSUBDIV_VERSION { /* concept DrawDelegate { - void BindBatch(OsdUtilMeshBatchBase *batch); - void BindEffect(EFFECT *effect); - void DrawElements(EFFECT *effect, OsdDrawContext::PatchArray const &patchArray); + void Begin(); + void End(); + void Bind(OsdUtilMeshBatchBase *batch, EffectHandle effect); + void DrawElements(OsdDrawContext::PatchArray const &patchArray); + bool IsCombinable(EffectHandle &a, EffectHandle &b) } */ @@ -81,36 +83,23 @@ namespace OsdUtil { typedef typename DRAW_ITEM_COLLECTION::value_type DrawItem; - // XXX: Are these caches needed in this class? user delegate can do that? - bool first = true; - typename DrawItem::BatchBase *currentBatch = NULL; - typename DrawItem::EffectHandle currentEffect; // XXX: initial value for pointer? + delegate->Begin(); // iterate over DrawItemCollection for (typename DRAW_ITEM_COLLECTION::const_iterator it = items.begin(); it != items.end(); ++it) { - typename DrawItem::BatchBase *batch = it->GetBatch(); - typename DrawItem::EffectHandle effect = it->GetEffect(); - if (first || currentBatch != batch) { - if (not first) delegate->UnbindBatch(currentBatch); - delegate->BindBatch(batch); - currentBatch = batch; - } - if (first || currentEffect != effect) { - if (not first) delegate->UnbindEffect(currentEffect); - delegate->BindEffect(effect); - currentEffect = effect; - } + + delegate->Bind(it->GetBatch(), it->GetEffect()); // iterate over sub items within a draw item OsdDrawContext::PatchArrayVector const &patchArrays = it->GetPatchArrays(); for (OsdDrawContext::PatchArrayVector::const_iterator pit = patchArrays.begin(); pit != patchArrays.end(); ++pit) { - delegate->DrawElements(currentEffect, *pit); + delegate->DrawElements(*pit); } - first = false; + delegate->Unbind(it->GetBatch(), it->GetEffect()); } - if (not first) delegate->UnbindEffect(currentEffect); - if (not first) delegate->UnbindBatch(currentBatch); + + delegate->End(); } // ------------------------------------------------------------------------ @@ -125,8 +114,8 @@ namespace OsdUtil { }; // XXX: reconsider this function - template - void emit(DRAW_ITEM_COLLECTION &result, BATCH *batch, EFFECT effect) { + template + void emit(DRAW_ITEM_COLLECTION &result, BATCH *batch, EFFECT_HANDLE &effect) { if (dictionary.empty()) return; @@ -169,28 +158,32 @@ namespace OsdUtil { // ------------------------------------------------------------------------ // OptimizeDrawItem // ------------------------------------------------------------------------ - template + template void OptimizeDrawItem(DRAW_ITEM_COLLECTION const &items, - DRAW_ITEM_COLLECTION &result) { + DRAW_ITEM_COLLECTION &result, + DRAW_DELEGATE *delegate) { typedef typename DRAW_ITEM_COLLECTION::value_type DrawItem; - typename DrawItem::BatchBase *currentBatch = NULL; - typename DrawItem::EffectHandle currentEffect; // XXX: initial value? - + if (items.empty()) return; result.reserve(items.size()); + typename DrawItem::BatchBase *currentBatch = items[0].GetBatch(); + typename DrawItem::EffectHandle const *currentEffect = &(items[0].GetEffect()); + PatchArrayCombiner combiner; for (typename DRAW_ITEM_COLLECTION::const_iterator it = items.begin(); it != items.end(); ++it) { typename DrawItem::BatchBase *batch = it->GetBatch(); - typename DrawItem::EffectHandle effect = it->GetEffect(); + typename DrawItem::EffectHandle const &effect = it->GetEffect(); + + if (currentBatch != batch or + (not delegate->IsCombinable(*currentEffect, effect))) { - if (currentBatch != batch || currentEffect != effect) { // emit cached draw item - combiner.emit(result, currentBatch, currentEffect); + combiner.emit(result, currentBatch, *currentEffect); currentBatch = batch; - currentEffect = effect; + currentEffect = &effect; } // merge consecutive items if possible. This operation changes drawing order. @@ -207,7 +200,7 @@ namespace OsdUtil { } // pick up after - combiner.emit(result, currentBatch, currentEffect); + combiner.emit(result, currentBatch, *currentEffect); } }; @@ -217,4 +210,4 @@ using namespace OPENSUBDIV_VERSION; } // end namespace OpenSubdiv -#endif /* OSD_UTIL_DRAW_CONTROLLER_H */ +#endif /* OSDUTIL_DRAW_CONTROLLER_H */ diff --git a/opensubdiv/osd_util/drawItem.h b/opensubdiv/osdutil/drawItem.h similarity index 94% rename from opensubdiv/osd_util/drawItem.h rename to opensubdiv/osdutil/drawItem.h index bb515d1c..7d97267d 100644 --- a/opensubdiv/osd_util/drawItem.h +++ b/opensubdiv/osdutil/drawItem.h @@ -54,8 +54,8 @@ // exclude the implied warranties of merchantability, fitness for // a particular purpose and non-infringement. // -#ifndef OSD_UTIL_DRAW_ITEM_H -#define OSD_UTIL_DRAW_ITEM_H +#ifndef OSDUTIL_DRAW_ITEM_H +#define OSDUTIL_DRAW_ITEM_H #include "../version.h" @@ -76,10 +76,12 @@ public: typedef std::vector > Collection; // contructors + // creates empty draw item OsdUtilDrawItem(OsdUtilMeshBatchBase *batch, EffectHandle effect) : _batch(batch), _effect(effect) {} + // creates draw item with given patcharray OsdUtilDrawItem(OsdUtilMeshBatchBase *batch, EffectHandle effect, OsdDrawContext::PatchArrayVector const &patchArrays) : @@ -87,7 +89,8 @@ public: // accessors will be called by draw controller BatchBase * GetBatch() const { return _batch; } - EffectHandle GetEffect() const { return _effect; } + EffectHandle const & GetEffect() const { return _effect; } + EffectHandle & GetEffect() { return _effect; } OsdDrawContext::PatchArrayVector const &GetPatchArrays() const { return _patchArrays; } OsdDrawContext::PatchArrayVector &GetPatchArrays() { return _patchArrays; } @@ -103,4 +106,4 @@ using namespace OPENSUBDIV_VERSION; } // end namespace OpenSubdiv -#endif /* OSD_UTIL_DRAW_ITEM_H */ +#endif /* OSDUTIL_DRAW_ITEM_H */