Blender V5.0
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 }
20 delete instance;
21 return nullptr;
22}
23
24static void discard_buffer(gpu::StorageBuf **buffer)
25{
26 if (*buffer != nullptr) {
27 GPU_storagebuf_free(*buffer);
28 *buffer = nullptr;
29 }
30}
31
32static void discard_list(std::vector<gpu::StorageBuf *> &buffers)
33{
34 while (!buffers.empty()) {
35 gpu::StorageBuf *buffer = buffers.back();
36 buffers.pop_back();
37 GPU_storagebuf_free(buffer);
38 }
39}
40
49
50bool GPUPatchTable::allocate(PatchTable const *far_patch_table)
51{
52 CpuPatchTable patch_table(far_patch_table);
53
54 /* Patch array */
55 size_t num_patch_arrays = patch_table.GetNumPatchArrays();
56 _patchArrays.assign(patch_table.GetPatchArrayBuffer(),
57 patch_table.GetPatchArrayBuffer() + num_patch_arrays);
58
59 /* Patch index buffer */
60 const size_t index_size = patch_table.GetPatchIndexSize();
62 index_size * sizeof(int32_t),
63 static_cast<const void *>(patch_table.GetPatchIndexBuffer()),
65 "osd_patch_index");
66
67 /* Patch param buffer */
68 const size_t patch_param_size = patch_table.GetPatchParamSize();
69 _patchParamBuffer = GPU_storagebuf_create_ex(patch_param_size * sizeof(PatchParam),
70 patch_table.GetPatchParamBuffer(),
72 "osd_patch_param");
73
74 /* Varying patch array */
75 _varyingPatchArrays.assign(patch_table.GetVaryingPatchArrayBuffer(),
76 patch_table.GetVaryingPatchArrayBuffer() + num_patch_arrays);
77
78 /* Varying index buffer */
79 _varyingIndexBuffer = GPU_storagebuf_create_ex(patch_table.GetVaryingPatchIndexSize() *
80 sizeof(uint32_t),
81 patch_table.GetVaryingPatchIndexBuffer(),
83 "osd_varying_index");
84
85 /* Face varying */
86 const int num_face_varying_channels = patch_table.GetNumFVarChannels();
87 _fvarPatchArrays.resize(num_face_varying_channels);
88 _fvarIndexBuffers.resize(num_face_varying_channels);
89 _fvarParamBuffers.resize(num_face_varying_channels);
90 for (int index = 0; index < num_face_varying_channels; index++) {
91 /* Face varying patch arrays */
92 _fvarPatchArrays[index].assign(patch_table.GetFVarPatchArrayBuffer(),
93 patch_table.GetFVarPatchArrayBuffer() + num_patch_arrays);
94
95 /* Face varying patch index buffer */
96 _fvarIndexBuffers[index] = GPU_storagebuf_create_ex(patch_table.GetFVarPatchIndexSize(index) *
97 sizeof(int32_t),
98 patch_table.GetFVarPatchIndexBuffer(index),
100 "osd_face_varying_index");
101
102 /* Face varying patch param buffer */
103 _fvarParamBuffers[index] = GPU_storagebuf_create_ex(patch_table.GetFVarPatchParamSize(index) *
104 sizeof(PatchParam),
105 patch_table.GetFVarPatchParamBuffer(index),
107 "osd_face_varying_params");
108 }
109
110 return true;
111}
112
113} // namespace blender::opensubdiv
void GPU_storagebuf_free(blender::gpu::StorageBuf *ssbo)
blender::gpu::StorageBuf * GPU_storagebuf_create_ex(size_t size, const void *data, GPUUsageType usage, const char *name)
@ GPU_USAGE_STATIC
std::vector< gpu::StorageBuf * > _fvarParamBuffers
std::vector< gpu::StorageBuf * > _fvarIndexBuffers
static GPUPatchTable * Create(PatchTable const *farPatchTable, void *deviceContext=NULL)
bool allocate(PatchTable const *farPatchTable)
std::vector< PatchArrayVector > _fvarPatchArrays
static void discard_buffer(gpu::StorageBuf **buffer)
static void discard_list(std::vector< gpu::StorageBuf * > &buffers)
char * buffers[2]