1 //
2 //   Copyright 2015 Pixar
3 //
4 //   Licensed under the Apache License, Version 2.0 (the "Apache License")
5 //   with the following modification; you may not use this file except in
6 //   compliance with the Apache License and the following modification to it:
7 //   Section 6. Trademarks. is deleted and replaced with:
8 //
9 //   6. Trademarks. This License does not grant permission to use the trade
10 //      names, trademarks, service marks, or product names of the Licensor
11 //      and its affiliates, except as required to comply with Section 4(c) of
12 //      the License and to reproduce the content of the NOTICE file.
13 //
14 //   You may obtain a copy of the Apache License at
15 //
16 //       http://www.apache.org/licenses/LICENSE-2.0
17 //
18 //   Unless required by applicable law or agreed to in writing, software
19 //   distributed under the Apache License with the above modification is
20 //   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 //   KIND, either express or implied. See the Apache License for the specific
22 //   language governing permissions and limitations under the Apache License.
23 //
24 
25 #include "../osd/cudaPatchTable.h"
26 
27 #include <cuda_runtime.h>
28 
29 #include "../far/patchTable.h"
30 #include "../osd/cpuPatchTable.h"
31 
32 namespace OpenSubdiv {
33 namespace OPENSUBDIV_VERSION {
34 
35 namespace Osd {
36 
CudaPatchTable()37 CudaPatchTable::CudaPatchTable() :
38     _patchArrays(NULL), _indexBuffer(NULL), _patchParamBuffer(NULL),
39     _varyingPatchArrays(NULL), _varyingIndexBuffer(NULL) {
40 }
41 
~CudaPatchTable()42 CudaPatchTable::~CudaPatchTable() {
43     if (_patchArrays) cudaFree(_patchArrays);
44     if (_indexBuffer) cudaFree(_indexBuffer);
45     if (_patchParamBuffer) cudaFree(_patchParamBuffer);
46     if (_varyingPatchArrays) cudaFree(_varyingPatchArrays);
47     if (_varyingIndexBuffer) cudaFree(_varyingIndexBuffer);
48     for (int fvc=0; fvc<(int)_fvarPatchArrays.size(); ++fvc) {
49         if (_fvarPatchArrays[fvc]) cudaFree(_fvarPatchArrays[fvc]);
50     }
51     for (int fvc=0; fvc<(int)_fvarIndexBuffers.size(); ++fvc) {
52         if (_fvarIndexBuffers[fvc]) cudaFree(_fvarIndexBuffers[fvc]);
53     }
54     for (int fvc=0; fvc<(int)_fvarParamBuffers.size(); ++fvc) {
55         if (_fvarParamBuffers[fvc]) cudaFree(_fvarParamBuffers[fvc]);
56     }
57 }
58 
59 CudaPatchTable *
Create(Far::PatchTable const * farPatchTable,void *)60 CudaPatchTable::Create(Far::PatchTable const *farPatchTable,
61                        void * /*deviceContext*/) {
62     CudaPatchTable *instance = new CudaPatchTable();
63     if (instance->allocate(farPatchTable)) return instance;
64     delete instance;
65     return 0;
66 }
67 
68 bool
allocate(Far::PatchTable const * farPatchTable)69 CudaPatchTable::allocate(Far::PatchTable const *farPatchTable) {
70     CpuPatchTable patchTable(farPatchTable);
71 
72     size_t numPatchArrays = patchTable.GetNumPatchArrays();
73     size_t indexSize = patchTable.GetPatchIndexSize();
74     size_t patchParamSize = patchTable.GetPatchParamSize();
75 
76     cudaError_t err;
77     err = cudaMalloc(&_patchArrays, numPatchArrays * sizeof(Osd::PatchArray));
78     if (err != cudaSuccess) return false;
79 
80     err = cudaMalloc(&_indexBuffer, indexSize * sizeof(int));
81     if (err != cudaSuccess) return false;
82 
83     err = cudaMalloc(&_patchParamBuffer, patchParamSize * sizeof(Osd::PatchParam));
84     if (err != cudaSuccess) return false;
85 
86     err = cudaMalloc(&_varyingPatchArrays, numPatchArrays * sizeof(Osd::PatchArray));
87     if (err != cudaSuccess) return false;
88 
89     size_t varyingIndexSize = patchTable.GetVaryingPatchIndexSize();
90     err = cudaMalloc(&_varyingIndexBuffer, varyingIndexSize * sizeof(int));
91     if (err != cudaSuccess) return false;
92 
93     size_t numFVarChannels = patchTable.GetNumFVarChannels();
94     _fvarPatchArrays.resize(numFVarChannels, 0);
95     _fvarIndexBuffers.resize(numFVarChannels, 0);
96     _fvarParamBuffers.resize(numFVarChannels, 0);
97     for (int fvc=0; fvc<(int)numFVarChannels; ++fvc) {
98         err = cudaMalloc(&_fvarPatchArrays[fvc], numPatchArrays * sizeof(Osd::PatchArray));
99         if (err != cudaSuccess) return false;
100 
101         err = cudaMemcpy(_fvarPatchArrays[fvc],
102                          patchTable.GetFVarPatchArrayBuffer(fvc),
103                          numPatchArrays * sizeof(Osd::PatchArray),
104                          cudaMemcpyHostToDevice);
105         if (err != cudaSuccess) return false;
106 
107         size_t fvarIndexSize = patchTable.GetFVarPatchIndexSize(fvc);
108         err = cudaMalloc(&_fvarIndexBuffers[fvc], fvarIndexSize * sizeof(int));
109         if (err != cudaSuccess) return false;
110 
111         err = cudaMemcpy(_fvarIndexBuffers[fvc],
112                          patchTable.GetFVarPatchIndexBuffer(fvc),
113                          fvarIndexSize * sizeof(int),
114                          cudaMemcpyHostToDevice);
115         if (err != cudaSuccess) return false;
116 
117         size_t fvarParamSize = patchTable.GetFVarPatchParamSize(fvc);
118         err = cudaMalloc(&_fvarParamBuffers[fvc], fvarParamSize * sizeof(Osd::PatchParam));
119         if (err != cudaSuccess) return false;
120 
121         err = cudaMemcpy(_fvarParamBuffers[fvc],
122                          patchTable.GetFVarPatchParamBuffer(fvc),
123                          patchParamSize * sizeof(PatchParam),
124                          cudaMemcpyHostToDevice);
125         if (err != cudaSuccess) return false;
126     }
127 
128     // copy patch array
129     err = cudaMemcpy(_patchArrays,
130                      patchTable.GetPatchArrayBuffer(),
131                      numPatchArrays * sizeof(Osd::PatchArray),
132                      cudaMemcpyHostToDevice);
133     if (err != cudaSuccess) return false;
134 
135     // copy index buffer
136     err = cudaMemcpy(_indexBuffer,
137                      patchTable.GetPatchIndexBuffer(),
138                      indexSize * sizeof(int),
139                      cudaMemcpyHostToDevice);
140     if (err != cudaSuccess) return false;
141 
142     // patch param buffer
143     err = cudaMemcpy(_patchParamBuffer,
144                      patchTable.GetPatchParamBuffer(),
145                      patchParamSize * sizeof(Osd::PatchParam),
146                      cudaMemcpyHostToDevice);
147     if (err != cudaSuccess) return false;
148 
149     // copy varying patch arrays and index buffer
150     err = cudaMemcpy(_varyingPatchArrays,
151                      patchTable.GetVaryingPatchArrayBuffer(),
152                      numPatchArrays * sizeof(Osd::PatchArray),
153                      cudaMemcpyHostToDevice);
154     if (err != cudaSuccess) return false;
155     err = cudaMemcpy(_varyingIndexBuffer,
156                      patchTable.GetVaryingPatchIndexBuffer(),
157                      varyingIndexSize * sizeof(int),
158                      cudaMemcpyHostToDevice);
159     if (err != cudaSuccess) return false;
160 
161     return true;
162 }
163 
164 
165 }  // end namespace Osd
166 
167 }  // end namespace OPENSUBDIV_VERSION
168 }  // end namespace OpenSubdiv
169 
170