From a040157e5dd7227fc61ee2608f30f2492db167be Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 20 Jul 2015 15:18:35 +0200 Subject: OpenSubdiv: Add new OpenSubdiv related files This includes C-API bindings in intern/opensubdiv and CMAke module which finds the OpenSubdiv library. This filea are not in use so far, making it a separate commit to make actual integration commit more clear. --- intern/opensubdiv/opensubdiv_capi.cc | 303 +++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 intern/opensubdiv/opensubdiv_capi.cc (limited to 'intern/opensubdiv/opensubdiv_capi.cc') diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc new file mode 100644 index 00000000000..717af4fa4f2 --- /dev/null +++ b/intern/opensubdiv/opensubdiv_capi.cc @@ -0,0 +1,303 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * Brecht van Lommel + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "opensubdiv_capi.h" + +#ifdef _MSC_VER +# include "iso646.h" +#endif + +#include + +#include + +/* CPU Backend */ +#include +#include + +#ifdef OPENSUBDIV_HAS_OPENMP +# include +#endif /* OPENSUBDIV_HAS_OPENMP */ + +#ifdef OPENSUBDIV_HAS_OPENCL +# include +# include +# include "opensubdiv_device_context_opencl.h" +#endif /* OPENSUBDIV_HAS_OPENCL */ + +#ifdef OPENSUBDIV_HAS_CUDA +# include +# include +# include "opensubdiv_device_context_cuda.h" +#endif /* OPENSUBDIV_HAS_CUDA */ + +#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK +# include +# include +#endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */ + +#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE +# include +# include +#endif /* OPENSUBDIV_HAS_GLSL_COMPUTE */ + +#include +#include + +#include "opensubdiv_intern.h" +#include "opensubdiv_partitioned.h" + +#include "MEM_guardedalloc.h" + +/* **************** Types declaration **************** */ + +using OpenSubdiv::Osd::GLMeshInterface; +using OpenSubdiv::Osd::Mesh; +using OpenSubdiv::Osd::MeshBitset; +using OpenSubdiv::Far::StencilTable; +using OpenSubdiv::Osd::GLPatchTable; + +using OpenSubdiv::Osd::PartitionedMesh; + +/* CPU backend */ +using OpenSubdiv::Osd::CpuGLVertexBuffer; +using OpenSubdiv::Osd::CpuEvaluator; +typedef PartitionedMesh OsdCpuMesh; + +#ifdef OPENSUBDIV_HAS_OPENMP +using OpenSubdiv::Osd::OmpEvaluator; +typedef PartitionedMesh OsdOmpMesh; +#endif /* OPENSUBDIV_HAS_OPENMP */ + +#ifdef OPENSUBDIV_HAS_OPENCL +using OpenSubdiv::Osd::CLEvaluator; +using OpenSubdiv::Osd::CLGLVertexBuffer; +using OpenSubdiv::Osd::CLStencilTable; +/* TODO(sergey): Use CLDeviceCOntext similar to OSD examples? */ +typedef PartitionedMesh OsdCLMesh; +static CLDeviceContext g_clDeviceContext; +#endif /* OPENSUBDIV_HAS_OPENCL */ + +#ifdef OPENSUBDIV_HAS_CUDA +using OpenSubdiv::Osd::CudaEvaluator; +using OpenSubdiv::Osd::CudaGLVertexBuffer; +using OpenSubdiv::Osd::CudaStencilTable; +typedef PartitionedMesh OsdCudaMesh; +static CudaDeviceContext g_cudaDeviceContext; +#endif /* OPENSUBDIV_HAS_CUDA */ + +#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK +using OpenSubdiv::Osd::GLXFBEvaluator; +using OpenSubdiv::Osd::GLStencilTableTBO; +using OpenSubdiv::Osd::GLVertexBuffer; +typedef PartitionedMesh OsdGLSLTransformFeedbackMesh; +#endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */ + +#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE +using OpenSubdiv::Osd::GLComputeEvaluator; +using OpenSubdiv::Osd::GLStencilTableSSBO; +using OpenSubdiv::Osd::GLVertexBuffer; +typedef PartitionedMesh OsdGLSLComputeMesh; +#endif + +struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner( + OpenSubdiv_TopologyRefinerDescr *topology_refiner, + int evaluator_type, + int level, + int /*subdivide_uvs*/) +{ + using OpenSubdiv::Far::TopologyRefiner; + + MeshBitset bits; + /* TODO(sergey): Adaptive subdivisions are not currently + * possible because of the lack of tessellation shader. + */ + bits.set(OpenSubdiv::Osd::MeshAdaptive, 0); + bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0); + bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 0); + bits.set(OpenSubdiv::Osd::MeshFVarData, 1); + bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1); + // bits.set(Osd::MeshEndCapGregoryBasis, 1); + // bits.set(Osd::MeshEndCapLegacyGregory, 1); + + const int num_vertex_elements = 6; + const int num_varying_elements = 0; + + GLMeshInterface *mesh = NULL; + TopologyRefiner *refiner = (TopologyRefiner*)topology_refiner; + + switch(evaluator_type) { +#define CHECK_EVALUATOR_TYPE(type, class) \ + case OPENSUBDIV_EVALUATOR_ ## type: \ + mesh = new class(refiner, \ + num_vertex_elements, \ + num_varying_elements, \ + level, \ + bits); \ + break; + + CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh) + +#ifdef OPENSUBDIV_HAS_OPENMP + CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh) +#endif + +#ifdef OPENSUBDIV_HAS_OPENCL + CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh) +#endif + +#ifdef OPENSUBDIV_HAS_CUDA + CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh) +#endif + +#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK + CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, + OsdGLSLTransformFeedbackMesh) +#endif + +#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE + CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh) +#endif + +#undef CHECK_EVALUATOR_TYPE + } + + if (mesh == NULL) { + return NULL; + } + + OpenSubdiv_GLMesh *gl_mesh = + (OpenSubdiv_GLMesh *) OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh); + gl_mesh->evaluator_type = evaluator_type; + gl_mesh->descriptor = (OpenSubdiv_GLMeshDescr *) mesh; + gl_mesh->topology_refiner = (OpenSubdiv_TopologyRefinerDescr*)refiner; + + return gl_mesh; +} + +void openSubdiv_deleteOsdGLMesh(struct OpenSubdiv_GLMesh *gl_mesh) +{ + switch (gl_mesh->evaluator_type) { +#define CHECK_EVALUATOR_TYPE(type, class) \ + case OPENSUBDIV_EVALUATOR_ ## type: \ + delete (class *) gl_mesh->descriptor; \ + break; + + CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh) + +#ifdef OPENSUBDIV_HAS_OPENMP + CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh) +#endif + +#ifdef OPENSUBDIV_HAS_OPENCL + CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh) +#endif + +#ifdef OPENSUBDIV_HAS_CUDA + CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh) +#endif + +#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK + CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, + OsdGLSLTransformFeedbackMesh) +#endif + +#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE + CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh) +#endif + +#undef CHECK_EVALUATOR_TYPE + } + + OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh); +} + +unsigned int openSubdiv_getOsdGLMeshPatchIndexBuffer(struct OpenSubdiv_GLMesh *gl_mesh) +{ + return ((GLMeshInterface *)gl_mesh->descriptor)->GetPatchTable()->GetPatchIndexBuffer(); +} + +unsigned int openSubdiv_getOsdGLMeshVertexBuffer(struct OpenSubdiv_GLMesh *gl_mesh) +{ + return ((GLMeshInterface *)gl_mesh->descriptor)->BindVertexBuffer(); +} + +void openSubdiv_osdGLMeshUpdateVertexBuffer(struct OpenSubdiv_GLMesh *gl_mesh, + const float *vertex_data, + int start_vertex, + int num_verts) +{ + ((GLMeshInterface *)gl_mesh->descriptor)->UpdateVertexBuffer(vertex_data, + start_vertex, + num_verts); +} + +void openSubdiv_osdGLMeshRefine(struct OpenSubdiv_GLMesh *gl_mesh) +{ + ((GLMeshInterface *)gl_mesh->descriptor)->Refine(); +} + +void openSubdiv_osdGLMeshSynchronize(struct OpenSubdiv_GLMesh *gl_mesh) +{ + ((GLMeshInterface *)gl_mesh->descriptor)->Synchronize(); +} + +void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh) +{ + ((GLMeshInterface *)gl_mesh->descriptor)->BindVertexBuffer(); +} + +const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefiner( + OpenSubdiv_GLMesh *gl_mesh) +{ + return gl_mesh->topology_refiner;; +} + +int openSubdiv_supportGPUDisplay(void) +{ + return GL_EXT_geometry_shader4 && + GL_ARB_gpu_shader5 && + glProgramParameteriEXT; +} -- cgit v1.2.3