Files
test/intern/opensubdiv/internal/evaluator/gpu_patch_table.hh
Jeroen Bakker 40696ca452 SubDiv: Migrate GPU subdivision to use GPU module
Blender already had its own copy of OpenSubDiv containing some local fixes
and code-style. This code still used gl-calls. This PR updates the calls
to use GPU module. This allows us to use OpenSubDiv to be usable on other
backends as well.

This PR was tested on OpenGL, Vulkan and Metal. Metal can be enabled,
but Vulkan requires some API changes to work with loose geometry.

![metal.png](/attachments/bb042c3a-1a87-4140-9958-a80da10d417b)

# Considerations

**ShaderCreateInfo**

intern/opensubdiv now requires access to GPU module. This to create buffers
in the correct context and trigger correct dispatches. ShaderCreateInfo is used
to construct the shader for cross compilation to Metal/Vulkan. However opensubdiv
shader caching structures are still used.

**Vertex buffers vs storage buffers**

Implementation tries to keep as close to the original OSD implementation. If
they used storage buffers for data, we will use GPUStorageBuf. If it uses vertex
buffers, we will use gpu::VertBuf.

**Evaluator const**

The evaluator cannot be const anymore as the GPU module API only allows
updating SSBOs when constructing. API could be improved to support updating
SSBOs.

Current implementation has a change to use reads out of bounds when constructing
SSBOs. An API change is in the planning to remove this issue. This will be fixed in
an upcoming PR. We wanted to land this PR as the visibility of the issue is not
common and multiple other changes rely on this PR to land.

Pull Request: https://projects.blender.org/blender/blender/pulls/135296
2025-03-10 07:31:59 +01:00

97 lines
2.5 KiB
C++

#pragma once
#include "GPU_storage_buffer.hh"
#include <opensubdiv/version.h>
#include <opensubdiv/osd/nonCopyable.h>
#include <opensubdiv/osd/types.h>
using OpenSubdiv::Far::PatchTable;
using OpenSubdiv::Osd::NonCopyable;
using OpenSubdiv::Osd::PatchArrayVector;
namespace blender::opensubdiv {
// TODO: use Blenlib NonCopyable.
class GPUPatchTable : private NonCopyable<GPUPatchTable> {
public:
~GPUPatchTable();
static GPUPatchTable *Create(PatchTable const *farPatchTable, void *deviceContext = NULL);
/// Returns the patch arrays for vertex index buffer data
PatchArrayVector const &GetPatchArrays() const
{
return _patchArrays;
}
/// Returns the GL index buffer containing the patch control vertices
GPUStorageBuf *GetPatchIndexBuffer() const
{
return _patchIndexBuffer;
}
/// Returns the GL index buffer containing the patch parameter
GPUStorageBuf *GetPatchParamBuffer() const
{
return _patchParamBuffer;
}
/// Returns the patch arrays for varying index buffer data
PatchArrayVector const &GetVaryingPatchArrays() const
{
return _varyingPatchArrays;
}
/// Returns the GL index buffer containing the varying control vertices
GPUStorageBuf *GetVaryingPatchIndexBuffer() const
{
return _varyingIndexBuffer;
}
/// Returns the number of face-varying channel buffers
int GetNumFVarChannels() const
{
return (int)_fvarPatchArrays.size();
}
/// Returns the patch arrays for face-varying index buffer data
PatchArrayVector const &GetFVarPatchArrays(int fvarChannel = 0) const
{
return _fvarPatchArrays[fvarChannel];
}
/// Returns the GL index buffer containing face-varying control vertices
GPUStorageBuf *GetFVarPatchIndexBuffer(int fvarChannel = 0) const
{
return _fvarIndexBuffers[fvarChannel];
}
/// Returns the GL index buffer containing face-varying patch params
GPUStorageBuf *GetFVarPatchParamBuffer(int fvarChannel = 0) const
{
return _fvarParamBuffers[fvarChannel];
}
protected:
GPUPatchTable() {}
// allocate buffers from patchTable
bool allocate(PatchTable const *farPatchTable);
PatchArrayVector _patchArrays;
GPUStorageBuf *_patchIndexBuffer = nullptr;
GPUStorageBuf *_patchParamBuffer = nullptr;
PatchArrayVector _varyingPatchArrays;
GPUStorageBuf *_varyingIndexBuffer = nullptr;
std::vector<PatchArrayVector> _fvarPatchArrays;
std::vector<GPUStorageBuf *> _fvarIndexBuffers;
std::vector<GPUStorageBuf *> _fvarParamBuffers;
};
} // namespace blender::opensubdiv