Blender V4.5
gpu_patch_table.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Foundation
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "gpu_patch_table.hh"
6
7#include "opensubdiv/far/patchTable.h"
8#include "opensubdiv/osd/cpuPatchTable.h"
9
10using namespace OpenSubdiv::Osd;
11
12namespace blender::opensubdiv {
13
14GPUPatchTable *GPUPatchTable::Create(PatchTable const *far_patch_table, void * /*deviceContext*/)
15{
16 GPUPatchTable *instance = new GPUPatchTable();
17 if (instance->allocate(far_patch_table))
18 return instance;
19 delete instance;
20 return nullptr;
21}
22
23static void discard_buffer(GPUStorageBuf **buffer)
24{
25 if (*buffer != nullptr) {
26 GPU_storagebuf_free(*buffer);
27 *buffer = nullptr;
28 }
29}
30
31static void discard_list(std::vector<GPUStorageBuf *> &buffers)
32{
33 while (!buffers.empty()) {
34 GPUStorageBuf *buffer = buffers.back();
35 buffers.pop_back();
36 GPU_storagebuf_free(buffer);
37 }
38}
39
48
49bool GPUPatchTable::allocate(PatchTable const *far_patch_table)
50{
51 CpuPatchTable patch_table(far_patch_table);
52
53 /* Patch array */
54 size_t num_patch_arrays = patch_table.GetNumPatchArrays();
55 _patchArrays.assign(patch_table.GetPatchArrayBuffer(),
56 patch_table.GetPatchArrayBuffer() + num_patch_arrays);
57
58 /* Patch index buffer */
59 const size_t index_size = patch_table.GetPatchIndexSize();
61 index_size * sizeof(int32_t),
62 static_cast<const void *>(patch_table.GetPatchIndexBuffer()),
64 "osd_patch_index");
65
66 /* Patch param buffer */
67 const size_t patch_param_size = patch_table.GetPatchParamSize();
68 _patchParamBuffer = GPU_storagebuf_create_ex(patch_param_size * sizeof(PatchParam),
69 patch_table.GetPatchParamBuffer(),
71 "osd_patch_param");
72
73 /* Varying patch array */
74 _varyingPatchArrays.assign(patch_table.GetVaryingPatchArrayBuffer(),
75 patch_table.GetVaryingPatchArrayBuffer() + num_patch_arrays);
76
77 /* Varying index buffer */
78 _varyingIndexBuffer = GPU_storagebuf_create_ex(patch_table.GetVaryingPatchIndexSize() *
79 sizeof(uint32_t),
80 patch_table.GetVaryingPatchIndexBuffer(),
82 "osd_varying_index");
83
84 /* Face varying */
85 const int num_face_varying_channels = patch_table.GetNumFVarChannels();
86 _fvarPatchArrays.resize(num_face_varying_channels);
87 _fvarIndexBuffers.resize(num_face_varying_channels);
88 _fvarParamBuffers.resize(num_face_varying_channels);
89 for (int index = 0; index < num_face_varying_channels; index++) {
90 /* Face varying patch arrays */
91 _fvarPatchArrays[index].assign(patch_table.GetFVarPatchArrayBuffer(),
92 patch_table.GetFVarPatchArrayBuffer() + num_patch_arrays);
93
94 /* Face varying patch index buffer */
95 _fvarIndexBuffers[index] = GPU_storagebuf_create_ex(patch_table.GetFVarPatchIndexSize(index) *
96 sizeof(int32_t),
97 patch_table.GetFVarPatchIndexBuffer(index),
99 "osd_face_varying_index");
100
101 /* Face varying patch param buffer */
102 _fvarParamBuffers[index] = GPU_storagebuf_create_ex(patch_table.GetFVarPatchParamSize(index) *
103 sizeof(PatchParam),
104 patch_table.GetFVarPatchParamBuffer(index),
106 "osd_face_varying_params");
107 }
108
109 return true;
110}
111
112} // namespace blender::opensubdiv
GPUStorageBuf * GPU_storagebuf_create_ex(size_t size, const void *data, GPUUsageType usage, const char *name)
void GPU_storagebuf_free(GPUStorageBuf *ssbo)
@ GPU_USAGE_STATIC
std::vector< GPUStorageBuf * > _fvarParamBuffers
static GPUPatchTable * Create(PatchTable const *farPatchTable, void *deviceContext=NULL)
bool allocate(PatchTable const *farPatchTable)
std::vector< GPUStorageBuf * > _fvarIndexBuffers
std::vector< PatchArrayVector > _fvarPatchArrays
static void discard_buffer(GPUStorageBuf **buffer)
static void discard_list(std::vector< GPUStorageBuf * > &buffers)
char * buffers[2]