Cleanup: Subdiv: Remove wrapper OpenSubdiv_Buffer

`OpenSubdiv_Buffer` is a wrapper that was introduced at the time
that Blender couldn't use CPP directly. It contains a pointer to
a VertBuf and callbacks to use GPU module on that buffer.

This PR replaces OpenSubdiv_Buffer with `blender::gpu::VertBuf` and
removes the wrapper.

NOTE: OpenSubdiv tests are added to blender_test executable to make the
library dependencies not to complicated.

Pull Request: https://projects.blender.org/blender/blender/pulls/135389
This commit is contained in:
Jeroen Bakker
2025-03-04 07:51:15 +01:00
parent 657770dfa6
commit 4a95c0405c
8 changed files with 136 additions and 237 deletions

View File

@@ -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()

View File

@@ -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();
}

View File

@@ -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

View File

@@ -30,26 +30,27 @@ class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer,
const PatchTable *patch_table,
EvaluatorCache *evaluator_cache = nullptr);
void fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer) override;
void fillPatchArraysBuffer(blender::gpu::VertBuf *patch_arrays_buffer) override;
void wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer) override;
void wrapPatchIndexBuffer(blender::gpu::VertBuf *patch_index_buffer) override;
void wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer) override;
void wrapPatchParamBuffer(blender::gpu::VertBuf *patch_param_buffer) override;
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer) override;
void wrapSrcBuffer(blender::gpu::VertBuf *src_buffer) override;
void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer) override;
void wrapSrcVertexDataBuffer(blender::gpu::VertBuf *src_buffer) override;
void fillFVarPatchArraysBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_arrays_buffer) override;
blender::gpu::VertBuf *patch_arrays_buffer) override;
void wrapFVarPatchIndexBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_index_buffer) override;
blender::gpu::VertBuf *patch_index_buffer) override;
void wrapFVarPatchParamBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_param_buffer) override;
blender::gpu::VertBuf *patch_param_buffer) override;
void wrapFVarSrcBuffer(const int face_varying_channel, OpenSubdiv_Buffer *src_buffer) override;
void wrapFVarSrcBuffer(const int face_varying_channel,
blender::gpu::VertBuf *src_buffer) override;
};
} // namespace blender::opensubdiv

View File

@@ -327,8 +327,8 @@ void EvalOutputAPI::evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_coor
}
}
void EvalOutputAPI::getPatchMap(OpenSubdiv_Buffer *patch_map_handles,
OpenSubdiv_Buffer *patch_map_quadtree,
void EvalOutputAPI::getPatchMap(blender::gpu::VertBuf *patch_map_handles,
blender::gpu::VertBuf *patch_map_quadtree,
int *min_patch_face,
int *max_patch_face,
int *max_depth,
@@ -340,65 +340,72 @@ void EvalOutputAPI::getPatchMap(OpenSubdiv_Buffer *patch_map_handles,
*patches_are_triangular = patch_map_->getPatchesAreTriangular();
const std::vector<PatchTable::PatchHandle> &handles = patch_map_->getHandles();
PatchTable::PatchHandle *buffer_handles = static_cast<PatchTable::PatchHandle *>(
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<PatchTable::PatchHandle> buffer_handles =
patch_map_handles->data<PatchTable::PatchHandle>();
memcpy(buffer_handles.data(), handles.data(), sizeof(PatchTable::PatchHandle) * handles.size());
const std::vector<PatchMap::QuadNode> &quadtree = patch_map_->nodes();
PatchMap::QuadNode *buffer_nodes = static_cast<PatchMap::QuadNode *>(
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<PatchMap::QuadNode> buffer_nodes = patch_map_quadtree->data<PatchMap::QuadNode>();
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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<char>().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 :