diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt index 0b8beb95b7a..5fcd8d963e4 100644 --- a/intern/opensubdiv/CMakeLists.txt +++ b/intern/opensubdiv/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRC set(LIB PRIVATE bf::blenlib PRIVATE bf::intern::guardedalloc + PRIVATE bf::gpu ) if(WITH_OPENSUBDIV) @@ -105,5 +106,9 @@ if(WITH_GTESTS AND WITH_OPENSUBDIV) add_definitions(${GFLAGS_DEFINES}) add_definitions(${GLOG_DEFINES}) - blender_add_test_executable(opensubdiv_mesh_topology "internal/topology/mesh_topology_test.cc" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv") + set(TEST_SRC + internal/topology/mesh_topology_test.cc + ) + + blender_add_test_suite_lib(intern_opensubdiv "${TEST_SRC}" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv") endif() diff --git a/intern/opensubdiv/internal/evaluator/eval_output.h b/intern/opensubdiv/internal/evaluator/eval_output.h index 112ee9dc995..864f525b881 100644 --- a/intern/opensubdiv/internal/evaluator/eval_output.h +++ b/intern/opensubdiv/internal/evaluator/eval_output.h @@ -76,36 +76,38 @@ class EvalOutputAPI::EvalOutput { // data structure. They need to be overridden in the specific instances of the EvalOutput derived // classes if needed, while the interfaces above are overridden through VolatileEvalOutput. - virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer * /*patch_arrays_buffer*/) {} + virtual void fillPatchArraysBuffer(blender::gpu::VertBuf * /*patch_arrays_buffer*/) {} - virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer * /*patch_index_buffer*/) {} + virtual void wrapPatchIndexBuffer(blender::gpu::VertBuf * /*patch_index_buffer*/) {} - virtual void wrapPatchParamBuffer(OpenSubdiv_Buffer * /*patch_param_buffer*/) {} + virtual void wrapPatchParamBuffer(blender::gpu::VertBuf * /*patch_param_buffer*/) {} - virtual void wrapSrcBuffer(OpenSubdiv_Buffer * /*src_buffer*/) {} + virtual void wrapSrcBuffer(blender::gpu::VertBuf * /*src_buffer*/) {} - virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer * /*src_buffer*/) {} + virtual void wrapSrcVertexDataBuffer(blender::gpu::VertBuf * /*src_buffer*/) {} virtual void fillFVarPatchArraysBuffer(const int /*face_varying_channel*/, - OpenSubdiv_Buffer * /*patch_arrays_buffer*/) + blender::gpu::VertBuf * /*patch_arrays_buffer*/) { } virtual void wrapFVarPatchIndexBuffer(const int /*face_varying_channel*/, - OpenSubdiv_Buffer * /*patch_index_buffer*/) + blender::gpu::VertBuf * /*patch_index_buffer*/) { } virtual void wrapFVarPatchParamBuffer(const int /*face_varying_channel*/, - OpenSubdiv_Buffer * /*patch_param_buffer*/) + blender::gpu::VertBuf * /*patch_param_buffer*/) { } virtual void wrapFVarSrcBuffer(const int /*face_varying_channel*/, - OpenSubdiv_Buffer * /*src_buffer*/) + blender::gpu::VertBuf * /*src_buffer*/) { } + virtual int getFVarSrcBufferOffset(const int face_varying_channel) const = 0; + virtual bool hasVertexData() const { return false; @@ -609,7 +611,7 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { return face_varying_evaluators_[face_varying_channel]->getSrcBuffer(); } - int getFVarSrcBufferOffset(const int face_varying_channel) const + int getFVarSrcBufferOffset(const int face_varying_channel) const override { return face_varying_evaluators_[face_varying_channel]->getFVarSrcBufferOffset(); } diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc index 36b566d4272..64da58e4ca6 100644 --- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc +++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc @@ -14,14 +14,13 @@ using OpenSubdiv::Osd::PatchArrayVector; namespace blender::opensubdiv { static void buildPatchArraysBufferFromVector(const PatchArrayVector &patch_arrays, - OpenSubdiv_Buffer *patch_arrays_buffer) + blender::gpu::VertBuf *patch_arrays_buffer) { const size_t patch_array_size = sizeof(PatchArray); const size_t patch_array_byte_site = patch_array_size * patch_arrays.size(); - patch_arrays_buffer->device_alloc(patch_arrays_buffer, patch_arrays.size()); - patch_arrays_buffer->bind_gpu(patch_arrays_buffer); - patch_arrays_buffer->device_update( - patch_arrays_buffer, 0, patch_array_byte_site, patch_arrays.data()); + GPU_vertbuf_data_alloc(*patch_arrays_buffer, patch_arrays.size()); + GPU_vertbuf_use(patch_arrays_buffer); + GPU_vertbuf_update_sub(patch_arrays_buffer, 0, patch_array_byte_site, patch_arrays.data()); } GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils, @@ -43,38 +42,38 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils, { } -void GpuEvalOutput::fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer) +void GpuEvalOutput::fillPatchArraysBuffer(blender::gpu::VertBuf *patch_arrays_buffer) { GLPatchTable *patch_table = getPatchTable(); buildPatchArraysBufferFromVector(patch_table->GetPatchArrays(), patch_arrays_buffer); } -void GpuEvalOutput::wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer) +void GpuEvalOutput::wrapPatchIndexBuffer(blender::gpu::VertBuf *patch_index_buffer) { GLPatchTable *patch_table = getPatchTable(); - patch_index_buffer->wrap_device_handle(patch_index_buffer, patch_table->GetPatchIndexBuffer()); + GPU_vertbuf_wrap_handle(patch_index_buffer, patch_table->GetPatchIndexBuffer()); } -void GpuEvalOutput::wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer) +void GpuEvalOutput::wrapPatchParamBuffer(blender::gpu::VertBuf *patch_param_buffer) { GLPatchTable *patch_table = getPatchTable(); - patch_param_buffer->wrap_device_handle(patch_param_buffer, patch_table->GetPatchParamBuffer()); + GPU_vertbuf_wrap_handle(patch_param_buffer, patch_table->GetPatchParamBuffer()); } -void GpuEvalOutput::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer) +void GpuEvalOutput::wrapSrcBuffer(blender::gpu::VertBuf *src_buffer) { GLVertexBuffer *vertex_buffer = getSrcBuffer(); - src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO()); + GPU_vertbuf_wrap_handle(src_buffer, vertex_buffer->BindVBO()); } -void GpuEvalOutput::wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer) +void GpuEvalOutput::wrapSrcVertexDataBuffer(blender::gpu::VertBuf *src_buffer) { GLVertexBuffer *vertex_buffer = getSrcVertexDataBuffer(); - src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO()); + GPU_vertbuf_wrap_handle(src_buffer, vertex_buffer->BindVBO()); } void GpuEvalOutput::fillFVarPatchArraysBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_arrays_buffer) + blender::gpu::VertBuf *patch_arrays_buffer) { GLPatchTable *patch_table = getFVarPatchTable(face_varying_channel); buildPatchArraysBufferFromVector(patch_table->GetFVarPatchArrays(face_varying_channel), @@ -82,27 +81,26 @@ void GpuEvalOutput::fillFVarPatchArraysBuffer(const int face_varying_channel, } void GpuEvalOutput::wrapFVarPatchIndexBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_index_buffer) + blender::gpu::VertBuf *patch_index_buffer) { GLPatchTable *patch_table = getFVarPatchTable(face_varying_channel); - patch_index_buffer->wrap_device_handle( - patch_index_buffer, patch_table->GetFVarPatchIndexBuffer(face_varying_channel)); + GPU_vertbuf_wrap_handle(patch_index_buffer, + patch_table->GetFVarPatchIndexBuffer(face_varying_channel)); } void GpuEvalOutput::wrapFVarPatchParamBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_param_buffer) + blender::gpu::VertBuf *patch_param_buffer) { GLPatchTable *patch_table = getFVarPatchTable(face_varying_channel); - patch_param_buffer->wrap_device_handle( - patch_param_buffer, patch_table->GetFVarPatchParamBuffer(face_varying_channel)); + GPU_vertbuf_wrap_handle(patch_param_buffer, + patch_table->GetFVarPatchParamBuffer(face_varying_channel)); } void GpuEvalOutput::wrapFVarSrcBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *src_buffer) + blender::gpu::VertBuf *src_buffer) { GLVertexBuffer *vertex_buffer = getFVarSrcBuffer(face_varying_channel); - src_buffer->buffer_offset = getFVarSrcBufferOffset(face_varying_channel); - src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO()); + GPU_vertbuf_wrap_handle(src_buffer, vertex_buffer->BindVBO()); } } // namespace blender::opensubdiv diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h index f590016f171..f52454ddc07 100644 --- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h +++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h @@ -30,26 +30,27 @@ class GpuEvalOutput : public VolatileEvalOutputgetPatchesAreTriangular(); const std::vector &handles = patch_map_->getHandles(); - PatchTable::PatchHandle *buffer_handles = static_cast( - patch_map_handles->alloc(patch_map_handles, handles.size())); - memcpy(buffer_handles, handles.data(), sizeof(PatchTable::PatchHandle) * handles.size()); + // TODO(jbakker): should these be SSBO's they are never bound as vertex buffers. + GPU_vertbuf_data_alloc(*patch_map_handles, handles.size()); + MutableSpan buffer_handles = + patch_map_handles->data(); + memcpy(buffer_handles.data(), handles.data(), sizeof(PatchTable::PatchHandle) * handles.size()); const std::vector &quadtree = patch_map_->nodes(); - PatchMap::QuadNode *buffer_nodes = static_cast( - patch_map_quadtree->alloc(patch_map_quadtree, quadtree.size())); - memcpy(buffer_nodes, quadtree.data(), sizeof(PatchMap::QuadNode) * quadtree.size()); + GPU_vertbuf_data_alloc(*patch_map_quadtree, quadtree.size()); + MutableSpan buffer_nodes = patch_map_quadtree->data(); + memcpy(buffer_nodes.data(), quadtree.data(), sizeof(PatchMap::QuadNode) * quadtree.size()); } -void EvalOutputAPI::fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer) +void EvalOutputAPI::fillPatchArraysBuffer(blender::gpu::VertBuf *patch_arrays_buffer) { implementation_->fillPatchArraysBuffer(patch_arrays_buffer); } -void EvalOutputAPI::wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer) +void EvalOutputAPI::wrapPatchIndexBuffer(blender::gpu::VertBuf *patch_index_buffer) { implementation_->wrapPatchIndexBuffer(patch_index_buffer); } -void EvalOutputAPI::wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer) +void EvalOutputAPI::wrapPatchParamBuffer(blender::gpu::VertBuf *patch_param_buffer) { implementation_->wrapPatchParamBuffer(patch_param_buffer); } -void EvalOutputAPI::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer) +void EvalOutputAPI::wrapSrcBuffer(blender::gpu::VertBuf *src_buffer) { implementation_->wrapSrcBuffer(src_buffer); } -void EvalOutputAPI::wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer) +void EvalOutputAPI::wrapSrcVertexDataBuffer(blender::gpu::VertBuf *src_buffer) { implementation_->wrapSrcVertexDataBuffer(src_buffer); } void EvalOutputAPI::fillFVarPatchArraysBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_arrays_buffer) + blender::gpu::VertBuf *patch_arrays_buffer) { implementation_->fillFVarPatchArraysBuffer(face_varying_channel, patch_arrays_buffer); } void EvalOutputAPI::wrapFVarPatchIndexBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_index_buffer) + blender::gpu::VertBuf *patch_index_buffer) { implementation_->wrapFVarPatchIndexBuffer(face_varying_channel, patch_index_buffer); } void EvalOutputAPI::wrapFVarPatchParamBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_param_buffer) + blender::gpu::VertBuf *patch_param_buffer) { implementation_->wrapFVarPatchParamBuffer(face_varying_channel, patch_param_buffer); } void EvalOutputAPI::wrapFVarSrcBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *src_buffer) + blender::gpu::VertBuf *src_buffer) { implementation_->wrapFVarSrcBuffer(face_varying_channel, src_buffer); } +int EvalOutputAPI::getFVarSrcBufferOffset(const int face_varying_channel) const +{ + return implementation_->getFVarSrcBufferOffset(face_varying_channel); +} + bool EvalOutputAPI::hasVertexData() const { return implementation_->hasVertexData(); diff --git a/intern/opensubdiv/opensubdiv_evaluator.hh b/intern/opensubdiv/opensubdiv_evaluator.hh index 676db03b141..0386a320ba1 100644 --- a/intern/opensubdiv/opensubdiv_evaluator.hh +++ b/intern/opensubdiv/opensubdiv_evaluator.hh @@ -16,11 +16,12 @@ #include "opensubdiv_capi_type.hh" -struct OpenSubdiv_Buffer; struct OpenSubdiv_EvaluatorCache; struct OpenSubdiv_EvaluatorSettings; struct OpenSubdiv_PatchCoord; - +namespace blender::gpu { +class VertBuf; +} namespace blender::opensubdiv { class TopologyRefinerImpl; @@ -128,45 +129,47 @@ class EvalOutputAPI { float *dPdv); // Fill the output buffers and variables with data from the PatchMap. - void getPatchMap(OpenSubdiv_Buffer *patch_map_handles, - OpenSubdiv_Buffer *patch_map_quadtree, + void getPatchMap(blender::gpu::VertBuf *patch_map_handles, + blender::gpu::VertBuf *patch_map_quadtree, int *min_patch_face, int *max_patch_face, int *max_depth, int *patches_are_triangular); // Copy the patch arrays buffer used by OpenSubDiv for the source data to the given buffer. - void fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer); + void fillPatchArraysBuffer(blender::gpu::VertBuf *patch_arrays_buffer); // Wrap the patch index buffer used by OpenSubDiv for the source data with the given buffer. - void wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer); + void wrapPatchIndexBuffer(blender::gpu::VertBuf *patch_index_buffer); // Wrap the patch param buffer used by OpenSubDiv for the source data with the given buffer. - void wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer); + void wrapPatchParamBuffer(blender::gpu::VertBuf *patch_param_buffer); // Wrap the buffer used by OpenSubDiv for the source data with the given buffer. - void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer); + void wrapSrcBuffer(blender::gpu::VertBuf *src_buffer); // Wrap the buffer used by OpenSubDiv for the extra source data with the given buffer. - void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer); + void wrapSrcVertexDataBuffer(blender::gpu::VertBuf *src_buffer); // Copy the patch arrays buffer used by OpenSubDiv for the face varying channel with the given // buffer. void fillFVarPatchArraysBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_arrays_buffer); + blender::gpu::VertBuf *patch_arrays_buffer); // Wrap the patch index buffer used by OpenSubDiv for the face varying channel with the given // buffer. void wrapFVarPatchIndexBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_index_buffer); + blender::gpu::VertBuf *patch_index_buffer); // Wrap the patch param buffer used by OpenSubDiv for the face varying channel with the given // buffer. void wrapFVarPatchParamBuffer(const int face_varying_channel, - OpenSubdiv_Buffer *patch_param_buffer); + blender::gpu::VertBuf *patch_param_buffer); // Wrap thebuffer used by OpenSubDiv for the face varying channel with the given buffer. - void wrapFVarSrcBuffer(const int face_varying_channel, OpenSubdiv_Buffer *src_buffer); + void wrapFVarSrcBuffer(const int face_varying_channel, blender::gpu::VertBuf *src_buffer); + /** Get the source buffer offset for the given channel. */ + int getFVarSrcBufferOffset(const int face_varying_channel) const; // Return true if source vertex data has been set. bool hasVertexData() const; diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.hh b/intern/opensubdiv/opensubdiv_evaluator_capi.hh index a3b1c6c364f..474b0831c94 100644 --- a/intern/opensubdiv/opensubdiv_evaluator_capi.hh +++ b/intern/opensubdiv/opensubdiv_evaluator_capi.hh @@ -8,6 +8,8 @@ #include "opensubdiv_capi_type.hh" +#include "GPU_vertex_buffer.hh" + struct OpenSubdiv_EvaluatorCacheImpl; struct OpenSubdiv_PatchCoord; namespace blender::opensubdiv { @@ -19,38 +21,6 @@ struct OpenSubdiv_EvaluatorSettings { int num_vertex_data; }; -// Callback type for doing input/output operations on buffers. -// Useful to abstract GPU buffers. -struct OpenSubdiv_Buffer { - // Bind the buffer to the GPU. - void (*bind_gpu)(const OpenSubdiv_Buffer *buffer); - - // Allocate the buffer directly on the host for the given size in bytes. This has to return - // a pointer to the newly allocated memory. - void *(*alloc)(const OpenSubdiv_Buffer *buffer, const unsigned int size); - - // Allocate the buffer directly on the device for the given size in bytes. - void (*device_alloc)(const OpenSubdiv_Buffer *buffer, const unsigned int size); - - // Update the given range of the buffer with new data. - void (*device_update)(const OpenSubdiv_Buffer *buffer, - unsigned int start, - unsigned int len, - const void *data); - - // Wrap an existing GPU buffer, given its device handle, into the client's buffer type for - // read-only use. - void (*wrap_device_handle)(const OpenSubdiv_Buffer *buffer, uint64_t device_ptr); - - // Offset in the buffer where the data starts, if a single buffer is used for multiple data - // channels. - int buffer_offset; - - // Pointer to the client buffer data, which is modified or initialized through the various - // callbacks. - void *data; -}; - struct OpenSubdiv_EvaluatorCache { // Implementation of the evaluator cache. OpenSubdiv_EvaluatorCacheImpl *impl; diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 46b5bd5bd31..5dc1f4883a7 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -199,72 +199,6 @@ const GPUVertFormat &draw_subdiv_get_pos_nor_format() /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Utilities to initialize a OpenSubdiv_Buffer for a gpu::VertBuf. - * \{ */ - -#ifdef WITH_OPENSUBDIV - -static void vertbuf_bind_gpu(const OpenSubdiv_Buffer *buffer) -{ - gpu::VertBuf *verts = (gpu::VertBuf *)(buffer->data); - GPU_vertbuf_use(verts); -} - -static void *vertbuf_alloc(const OpenSubdiv_Buffer *interface, const uint len) -{ - gpu::VertBuf *verts = (gpu::VertBuf *)(interface->data); - GPU_vertbuf_data_alloc(*verts, len); - return verts->data().data(); -} - -static void vertbuf_device_alloc(const OpenSubdiv_Buffer *interface, const uint len) -{ - gpu::VertBuf *verts = (gpu::VertBuf *)(interface->data); - /* This assumes that GPU_USAGE_DEVICE_ONLY was used, which won't allocate host memory. */ - // BLI_assert(GPU_vertbuf_get_usage(verts) == GPU_USAGE_DEVICE_ONLY); - GPU_vertbuf_data_alloc(*verts, len); -} - -static void vertbuf_wrap_device_handle(const OpenSubdiv_Buffer *interface, uint64_t handle) -{ - gpu::VertBuf *verts = (gpu::VertBuf *)(interface->data); - GPU_vertbuf_wrap_handle(verts, handle); -} - -static void vertbuf_update_data(const OpenSubdiv_Buffer *interface, - uint start, - uint len, - const void *data) -{ - gpu::VertBuf *verts = (gpu::VertBuf *)(interface->data); - GPU_vertbuf_update_sub(verts, start, len, data); -} - -static void opensubdiv_gpu_buffer_init(OpenSubdiv_Buffer *buffer_interface, gpu::VertBuf *vertbuf) -{ - buffer_interface->data = vertbuf; - buffer_interface->bind_gpu = vertbuf_bind_gpu; - buffer_interface->buffer_offset = 0; - buffer_interface->wrap_device_handle = vertbuf_wrap_device_handle; - buffer_interface->alloc = vertbuf_alloc; - buffer_interface->device_alloc = vertbuf_device_alloc; - buffer_interface->device_update = vertbuf_update_data; -} - -static gpu::VertBuf *create_buffer_and_interface(OpenSubdiv_Buffer *interface, - const GPUVertFormat &format) -{ - gpu::VertBuf *buffer = GPU_vertbuf_calloc(); - GPU_vertbuf_init_with_format_ex(*buffer, format, GPU_USAGE_DEVICE_ONLY); - opensubdiv_gpu_buffer_init(interface, buffer); - return buffer; -} - -#endif - -/** \} */ - // -------------------------------------------------------- static uint tris_count_from_number_of_loops(const uint number_of_loops) @@ -311,20 +245,14 @@ static void draw_patch_map_build(DRWPatchMap *gpu_patch_map, bke::subdiv::Subdiv gpu::VertBuf *patch_map_quadtree = GPU_vertbuf_calloc(); GPU_vertbuf_init_with_format_ex(*patch_map_quadtree, get_quadtree_format(), GPU_USAGE_STATIC); - OpenSubdiv_Buffer patch_map_handles_interface; - opensubdiv_gpu_buffer_init(&patch_map_handles_interface, patch_map_handles); - - OpenSubdiv_Buffer patch_map_quad_tree_interface; - opensubdiv_gpu_buffer_init(&patch_map_quad_tree_interface, patch_map_quadtree); - int min_patch_face = 0; int max_patch_face = 0; int max_depth = 0; int patches_are_triangular = 0; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; - evaluator->eval_output->getPatchMap(&patch_map_handles_interface, - &patch_map_quad_tree_interface, + evaluator->eval_output->getPatchMap(patch_map_handles, + patch_map_quadtree, &min_patch_face, &max_patch_face, &max_depth, @@ -1126,33 +1054,28 @@ void draw_subdiv_extract_pos_nor(const DRWSubdivCache &cache, bke::subdiv::Subdiv *subdiv = cache.subdiv; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; - OpenSubdiv_Buffer src_buffer_interface; - gpu::VertBuf *src_buffer = create_buffer_and_interface(&src_buffer_interface, - get_subdiv_vertex_format()); - evaluator->eval_output->wrapSrcBuffer(&src_buffer_interface); + gpu::VertBuf *src_buffer = GPU_vertbuf_create_with_format_ex(get_subdiv_vertex_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapSrcBuffer(src_buffer); gpu::VertBuf *src_extra_buffer = nullptr; if (orco) { - OpenSubdiv_Buffer src_extra_buffer_interface; - src_extra_buffer = create_buffer_and_interface(&src_extra_buffer_interface, - get_subdiv_vertex_format()); - evaluator->eval_output->wrapSrcVertexDataBuffer(&src_extra_buffer_interface); + src_extra_buffer = GPU_vertbuf_create_with_format_ex(get_subdiv_vertex_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapSrcVertexDataBuffer(src_extra_buffer); } - OpenSubdiv_Buffer patch_arrays_buffer_interface; - gpu::VertBuf *patch_arrays_buffer = create_buffer_and_interface(&patch_arrays_buffer_interface, - get_patch_array_format()); - evaluator->eval_output->fillPatchArraysBuffer(&patch_arrays_buffer_interface); + gpu::VertBuf *patch_arrays_buffer = GPU_vertbuf_create_with_format_ex(get_patch_array_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->fillPatchArraysBuffer(patch_arrays_buffer); - OpenSubdiv_Buffer patch_index_buffer_interface; - gpu::VertBuf *patch_index_buffer = create_buffer_and_interface(&patch_index_buffer_interface, - get_patch_index_format()); - evaluator->eval_output->wrapPatchIndexBuffer(&patch_index_buffer_interface); + gpu::VertBuf *patch_index_buffer = GPU_vertbuf_create_with_format_ex(get_patch_index_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapPatchIndexBuffer(patch_index_buffer); - OpenSubdiv_Buffer patch_param_buffer_interface; - gpu::VertBuf *patch_param_buffer = create_buffer_and_interface(&patch_param_buffer_interface, - get_patch_param_format()); - evaluator->eval_output->wrapPatchParamBuffer(&patch_param_buffer_interface); + gpu::VertBuf *patch_param_buffer = GPU_vertbuf_create_with_format_ex(get_patch_param_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapPatchParamBuffer(patch_param_buffer); GPUShader *shader = DRW_shader_subdiv_get(orco ? SubdivShaderType::PATCH_EVALUATION_ORCO : SubdivShaderType::PATCH_EVALUATION); @@ -1213,27 +1136,22 @@ void draw_subdiv_extract_uvs(const DRWSubdivCache &cache, bke::subdiv::Subdiv *subdiv = cache.subdiv; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; - OpenSubdiv_Buffer src_buffer_interface; - gpu::VertBuf *src_buffer = create_buffer_and_interface(&src_buffer_interface, get_uvs_format()); - evaluator->eval_output->wrapFVarSrcBuffer(face_varying_channel, &src_buffer_interface); + gpu::VertBuf *src_buffer = GPU_vertbuf_create_with_format_ex(get_uvs_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapFVarSrcBuffer(face_varying_channel, src_buffer); + int src_buffer_offset = evaluator->eval_output->getFVarSrcBufferOffset(face_varying_channel); - OpenSubdiv_Buffer patch_arrays_buffer_interface; - gpu::VertBuf *patch_arrays_buffer = create_buffer_and_interface(&patch_arrays_buffer_interface, - get_patch_array_format()); - evaluator->eval_output->fillFVarPatchArraysBuffer(face_varying_channel, - &patch_arrays_buffer_interface); + gpu::VertBuf *patch_arrays_buffer = GPU_vertbuf_create_with_format_ex(get_patch_array_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->fillFVarPatchArraysBuffer(face_varying_channel, patch_arrays_buffer); - OpenSubdiv_Buffer patch_index_buffer_interface; - gpu::VertBuf *patch_index_buffer = create_buffer_and_interface(&patch_index_buffer_interface, - get_patch_index_format()); - evaluator->eval_output->wrapFVarPatchIndexBuffer(face_varying_channel, - &patch_index_buffer_interface); + gpu::VertBuf *patch_index_buffer = GPU_vertbuf_create_with_format_ex(get_patch_index_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapFVarPatchIndexBuffer(face_varying_channel, patch_index_buffer); - OpenSubdiv_Buffer patch_param_buffer_interface; - gpu::VertBuf *patch_param_buffer = create_buffer_and_interface(&patch_param_buffer_interface, - get_patch_param_format()); - evaluator->eval_output->wrapFVarPatchParamBuffer(face_varying_channel, - &patch_param_buffer_interface); + gpu::VertBuf *patch_param_buffer = GPU_vertbuf_create_with_format_ex(get_patch_param_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapFVarPatchParamBuffer(face_varying_channel, patch_param_buffer); GPUShader *shader = DRW_shader_subdiv_get(SubdivShaderType::PATCH_EVALUATION_FVAR); GPU_shader_bind(shader); @@ -1253,8 +1171,8 @@ void draw_subdiv_extract_uvs(const DRWSubdivCache &cache, /* The buffer offset has the stride baked in (which is 2 as we have UVs) so remove the stride by * dividing by 2 */ - const int src_offset = src_buffer_interface.buffer_offset / 2; - drw_subdiv_compute_dispatch(cache, shader, src_offset, dst_offset, cache.num_subdiv_quads); + drw_subdiv_compute_dispatch( + cache, shader, src_buffer_offset / 2, dst_offset, cache.num_subdiv_quads); /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. * Since it may also be used for computing UV stretches, we also need a barrier on the shader @@ -1457,26 +1375,21 @@ void draw_subdiv_build_fdots_buffers(const DRWSubdivCache &cache, bke::subdiv::Subdiv *subdiv = cache.subdiv; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; - OpenSubdiv_Buffer src_buffer_interface; - gpu::VertBuf *src_buffer = create_buffer_and_interface(&src_buffer_interface, - get_subdiv_vertex_format()); - evaluator->eval_output->wrapSrcBuffer(&src_buffer_interface); + gpu::VertBuf *src_buffer = GPU_vertbuf_create_with_format_ex(get_subdiv_vertex_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapSrcBuffer(src_buffer); - OpenSubdiv_Buffer patch_arrays_buffer_interface; - gpu::VertBuf *patch_arrays_buffer = create_buffer_and_interface(&patch_arrays_buffer_interface, - get_patch_array_format()); - opensubdiv_gpu_buffer_init(&patch_arrays_buffer_interface, patch_arrays_buffer); - evaluator->eval_output->fillPatchArraysBuffer(&patch_arrays_buffer_interface); + gpu::VertBuf *patch_arrays_buffer = GPU_vertbuf_create_with_format_ex(get_patch_array_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->fillPatchArraysBuffer(patch_arrays_buffer); - OpenSubdiv_Buffer patch_index_buffer_interface; - gpu::VertBuf *patch_index_buffer = create_buffer_and_interface(&patch_index_buffer_interface, - get_patch_index_format()); - evaluator->eval_output->wrapPatchIndexBuffer(&patch_index_buffer_interface); + gpu::VertBuf *patch_index_buffer = GPU_vertbuf_create_with_format_ex(get_patch_index_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapPatchIndexBuffer(patch_index_buffer); - OpenSubdiv_Buffer patch_param_buffer_interface; - gpu::VertBuf *patch_param_buffer = create_buffer_and_interface(&patch_param_buffer_interface, - get_patch_param_format()); - evaluator->eval_output->wrapPatchParamBuffer(&patch_param_buffer_interface); + gpu::VertBuf *patch_param_buffer = GPU_vertbuf_create_with_format_ex(get_patch_param_format(), + GPU_USAGE_DEVICE_ONLY); + evaluator->eval_output->wrapPatchParamBuffer(patch_param_buffer); GPUShader *shader = DRW_shader_subdiv_get( fdots_nor ? SubdivShaderType::PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS :