Blender  V3.3
gl_compute_evaluator.cc
Go to the documentation of this file.
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 "gl_compute_evaluator.h"
26 
27 #include <GL/glew.h>
28 
29 #include <opensubdiv/far/error.h>
30 #include <opensubdiv/far/patchDescriptor.h>
31 #include <opensubdiv/far/stencilTable.h>
32 #include <opensubdiv/osd/glslPatchShaderSource.h>
33 
34 #include <cassert>
35 #include <cmath>
36 #include <sstream>
37 #include <string>
38 #include <vector>
39 
40 using OpenSubdiv::Far::LimitStencilTable;
41 using OpenSubdiv::Far::StencilTable;
42 using OpenSubdiv::Osd::BufferDescriptor;
43 using OpenSubdiv::Osd::PatchArray;
44 using OpenSubdiv::Osd::PatchArrayVector;
45 
47 
48 namespace blender {
49 namespace opensubdiv {
50 
51 template<class T> GLuint createSSBO(std::vector<T> const &src)
52 {
53  if (src.empty()) {
54  return 0;
55  }
56 
57  GLuint devicePtr = 0;
58 
59 #if defined(GL_ARB_direct_state_access)
60  if (GLEW_ARB_direct_state_access) {
61  glCreateBuffers(1, &devicePtr);
62  glNamedBufferData(devicePtr, src.size() * sizeof(T), &src.at(0), GL_STATIC_DRAW);
63  }
64  else
65 #endif
66  {
67  GLint prev = 0;
68  glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &prev);
69  glGenBuffers(1, &devicePtr);
70  glBindBuffer(GL_SHADER_STORAGE_BUFFER, devicePtr);
71  glBufferData(GL_SHADER_STORAGE_BUFFER, src.size() * sizeof(T), &src.at(0), GL_STATIC_DRAW);
72  glBindBuffer(GL_SHADER_STORAGE_BUFFER, prev);
73  }
74 
75  return devicePtr;
76 }
77 
78 GLStencilTableSSBO::GLStencilTableSSBO(StencilTable const *stencilTable)
79 {
80  _numStencils = stencilTable->GetNumStencils();
81  if (_numStencils > 0) {
82  _sizes = createSSBO(stencilTable->GetSizes());
83  _offsets = createSSBO(stencilTable->GetOffsets());
84  _indices = createSSBO(stencilTable->GetControlIndices());
85  _weights = createSSBO(stencilTable->GetWeights());
86  _duWeights = _dvWeights = 0;
87  _duuWeights = _duvWeights = _dvvWeights = 0;
88  }
89  else {
90  _sizes = _offsets = _indices = _weights = 0;
91  _duWeights = _dvWeights = 0;
92  _duuWeights = _duvWeights = _dvvWeights = 0;
93  }
94 }
95 
96 GLStencilTableSSBO::GLStencilTableSSBO(LimitStencilTable const *limitStencilTable)
97 {
98  _numStencils = limitStencilTable->GetNumStencils();
99  if (_numStencils > 0) {
100  _sizes = createSSBO(limitStencilTable->GetSizes());
101  _offsets = createSSBO(limitStencilTable->GetOffsets());
102  _indices = createSSBO(limitStencilTable->GetControlIndices());
103  _weights = createSSBO(limitStencilTable->GetWeights());
104  _duWeights = createSSBO(limitStencilTable->GetDuWeights());
105  _dvWeights = createSSBO(limitStencilTable->GetDvWeights());
106  _duuWeights = createSSBO(limitStencilTable->GetDuuWeights());
107  _duvWeights = createSSBO(limitStencilTable->GetDuvWeights());
108  _dvvWeights = createSSBO(limitStencilTable->GetDvvWeights());
109  }
110  else {
111  _sizes = _offsets = _indices = _weights = 0;
112  _duWeights = _dvWeights = 0;
113  _duuWeights = _duvWeights = _dvvWeights = 0;
114  }
115 }
116 
118 {
119  if (_sizes)
120  glDeleteBuffers(1, &_sizes);
121  if (_offsets)
122  glDeleteBuffers(1, &_offsets);
123  if (_indices)
124  glDeleteBuffers(1, &_indices);
125  if (_weights)
126  glDeleteBuffers(1, &_weights);
127  if (_duWeights)
128  glDeleteBuffers(1, &_duWeights);
129  if (_dvWeights)
130  glDeleteBuffers(1, &_dvWeights);
131  if (_duuWeights)
132  glDeleteBuffers(1, &_duuWeights);
133  if (_duvWeights)
134  glDeleteBuffers(1, &_duvWeights);
135  if (_dvvWeights)
136  glDeleteBuffers(1, &_dvvWeights);
137 }
138 
139 // ---------------------------------------------------------------------------
140 
141 GLComputeEvaluator::GLComputeEvaluator() : _workGroupSize(64), _patchArraysSSBO(0)
142 {
143  memset((void *)&_stencilKernel, 0, sizeof(_stencilKernel));
144  memset((void *)&_patchKernel, 0, sizeof(_patchKernel));
145 }
146 
148 {
149  if (_patchArraysSSBO) {
150  glDeleteBuffers(1, &_patchArraysSSBO);
151  }
152 }
153 
154 static GLuint compileKernel(BufferDescriptor const &srcDesc,
155  BufferDescriptor const &dstDesc,
156  BufferDescriptor const &duDesc,
157  BufferDescriptor const &dvDesc,
158  BufferDescriptor const &duuDesc,
159  BufferDescriptor const &duvDesc,
160  BufferDescriptor const &dvvDesc,
161  const char *kernelDefine,
162  int workGroupSize)
163 {
164  GLuint program = glCreateProgram();
165 
166  GLuint shader = glCreateShader(GL_COMPUTE_SHADER);
167 
168  std::string patchBasisShaderSource =
169  OpenSubdiv::Osd::GLSLPatchShaderSource::GetPatchBasisShaderSource();
170  const char *patchBasisShaderSourceDefine = "#define OSD_PATCH_BASIS_GLSL\n";
171 
172  std::ostringstream defines;
173  defines << "#define LENGTH " << srcDesc.length << "\n"
174  << "#define SRC_STRIDE " << srcDesc.stride << "\n"
175  << "#define DST_STRIDE " << dstDesc.stride << "\n"
176  << "#define WORK_GROUP_SIZE " << workGroupSize << "\n"
177  << kernelDefine << "\n"
178  << patchBasisShaderSourceDefine << "\n";
179 
180  bool deriv1 = (duDesc.length > 0 || dvDesc.length > 0);
181  bool deriv2 = (duuDesc.length > 0 || duvDesc.length > 0 || dvvDesc.length > 0);
182  if (deriv1) {
183  defines << "#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n";
184  }
185  if (deriv2) {
186  defines << "#define OPENSUBDIV_GLSL_COMPUTE_USE_2ND_DERIVATIVES\n";
187  }
188 
189  std::string defineStr = defines.str();
190 
191  const char *shaderSources[4] = {"#version 430\n", 0, 0, 0};
192 
193  shaderSources[1] = defineStr.c_str();
194  shaderSources[2] = patchBasisShaderSource.c_str();
195  shaderSources[3] = datatoc_glsl_compute_kernel_glsl;
196  glShaderSource(shader, 4, shaderSources, NULL);
197  glCompileShader(shader);
198  glAttachShader(program, shader);
199 
200  GLint linked = 0;
201  glLinkProgram(program);
202  glGetProgramiv(program, GL_LINK_STATUS, &linked);
203 
204  if (linked == GL_FALSE) {
205  char buffer[1024];
206  glGetShaderInfoLog(shader, 1024, NULL, buffer);
207  OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR, buffer);
208 
209  glGetProgramInfoLog(program, 1024, NULL, buffer);
210  OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR, buffer);
211 
212  glDeleteProgram(program);
213  return 0;
214  }
215 
216  glDeleteShader(shader);
217 
218  return program;
219 }
220 
221 bool GLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
222  BufferDescriptor const &dstDesc,
223  BufferDescriptor const &duDesc,
224  BufferDescriptor const &dvDesc,
225  BufferDescriptor const &duuDesc,
226  BufferDescriptor const &duvDesc,
227  BufferDescriptor const &dvvDesc)
228 {
229 
230  // create a stencil kernel
231  if (!_stencilKernel.Compile(
232  srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, _workGroupSize)) {
233  return false;
234  }
235 
236  // create a patch kernel
237  if (!_patchKernel.Compile(
238  srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, _workGroupSize)) {
239  return false;
240  }
241 
242  // create a patch arrays buffer
243  if (!_patchArraysSSBO) {
244  glGenBuffers(1, &_patchArraysSSBO);
245  }
246 
247  return true;
248 }
249 
250 /* static */
251 void GLComputeEvaluator::Synchronize(void * /*kernel*/)
252 {
253  // XXX: this is currently just for the performance measuring purpose.
254  // need to be reimplemented by fence and sync.
255  glFinish();
256 }
257 
258 int GLComputeEvaluator::GetDispatchSize(int count) const
259 {
260  return (count + _workGroupSize - 1) / _workGroupSize;
261 }
262 
263 void GLComputeEvaluator::DispatchCompute(int totalDispatchSize) const
264 {
265  int maxWorkGroupCount[2] = {0, 0};
266 
267  glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &maxWorkGroupCount[0]);
268  glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &maxWorkGroupCount[1]);
269 
270  const GLuint maxResX = static_cast<GLuint>(maxWorkGroupCount[0]);
271 
272  const int dispatchSize = GetDispatchSize(totalDispatchSize);
273  GLuint dispatchRX = static_cast<GLuint>(dispatchSize);
274  GLuint dispatchRY = 1u;
275  if (dispatchRX > maxResX) {
276  /* Since there are some limitations with regards to the maximum work group size (could be as
277  * low as 64k elements per call), we split the number elements into a "2d" number, with the
278  * final index being computed as `res_x + res_y * max_work_group_size`. Even with a maximum
279  * work group size of 64k, that still leaves us with roughly `64k * 64k = 4` billion elements
280  * total, which should be enough. If not, we could also use the 3rd dimension. */
281  /* TODO(fclem): We could dispatch fewer groups if we compute the prime factorization and
282  * get the smallest rect fitting the requirements. */
283  dispatchRX = dispatchRY = std::ceil(std::sqrt(dispatchSize));
284  /* Avoid a completely empty dispatch line caused by rounding. */
285  if ((dispatchRX * (dispatchRY - 1)) >= dispatchSize) {
286  dispatchRY -= 1;
287  }
288  }
289 
290  /* X and Y dimensions may have different limits so the above computation may not be right, but
291  * even with the standard 64k minimum on all dimensions we still have a lot of room. Therefore,
292  * we presume it all fits. */
293  assert(dispatchRY < static_cast<GLuint>(maxWorkGroupCount[1]));
294 
295  glDispatchCompute(dispatchRX, dispatchRY, 1);
296 }
297 
298 bool GLComputeEvaluator::EvalStencils(GLuint srcBuffer,
299  BufferDescriptor const &srcDesc,
300  GLuint dstBuffer,
301  BufferDescriptor const &dstDesc,
302  GLuint duBuffer,
303  BufferDescriptor const &duDesc,
304  GLuint dvBuffer,
305  BufferDescriptor const &dvDesc,
306  GLuint sizesBuffer,
307  GLuint offsetsBuffer,
308  GLuint indicesBuffer,
309  GLuint weightsBuffer,
310  GLuint duWeightsBuffer,
311  GLuint dvWeightsBuffer,
312  int start,
313  int end) const
314 {
315 
316  return EvalStencils(srcBuffer,
317  srcDesc,
318  dstBuffer,
319  dstDesc,
320  duBuffer,
321  duDesc,
322  dvBuffer,
323  dvDesc,
324  0,
325  BufferDescriptor(),
326  0,
327  BufferDescriptor(),
328  0,
329  BufferDescriptor(),
330  sizesBuffer,
331  offsetsBuffer,
332  indicesBuffer,
333  weightsBuffer,
334  duWeightsBuffer,
335  dvWeightsBuffer,
336  0,
337  0,
338  0,
339  start,
340  end);
341 }
342 
343 bool GLComputeEvaluator::EvalStencils(GLuint srcBuffer,
344  BufferDescriptor const &srcDesc,
345  GLuint dstBuffer,
346  BufferDescriptor const &dstDesc,
347  GLuint duBuffer,
348  BufferDescriptor const &duDesc,
349  GLuint dvBuffer,
350  BufferDescriptor const &dvDesc,
351  GLuint duuBuffer,
352  BufferDescriptor const &duuDesc,
353  GLuint duvBuffer,
354  BufferDescriptor const &duvDesc,
355  GLuint dvvBuffer,
356  BufferDescriptor const &dvvDesc,
357  GLuint sizesBuffer,
358  GLuint offsetsBuffer,
359  GLuint indicesBuffer,
360  GLuint weightsBuffer,
361  GLuint duWeightsBuffer,
362  GLuint dvWeightsBuffer,
363  GLuint duuWeightsBuffer,
364  GLuint duvWeightsBuffer,
365  GLuint dvvWeightsBuffer,
366  int start,
367  int end) const
368 {
369 
370  if (!_stencilKernel.program)
371  return false;
372  int count = end - start;
373  if (count <= 0) {
374  return true;
375  }
376 
377  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, srcBuffer);
378  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, dstBuffer);
379  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, duBuffer);
380  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, dvBuffer);
381  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, duuBuffer);
382  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 11, duvBuffer);
383  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 12, dvvBuffer);
384  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, sizesBuffer);
385  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, offsetsBuffer);
386  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, indicesBuffer);
387  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, weightsBuffer);
388  if (duWeightsBuffer)
389  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, duWeightsBuffer);
390  if (dvWeightsBuffer)
391  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 9, dvWeightsBuffer);
392  if (duuWeightsBuffer)
393  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 13, duuWeightsBuffer);
394  if (duvWeightsBuffer)
395  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 14, duvWeightsBuffer);
396  if (dvvWeightsBuffer)
397  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 15, dvvWeightsBuffer);
398 
399  GLint activeProgram;
400  glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
401  glUseProgram(_stencilKernel.program);
402 
403  glUniform1i(_stencilKernel.uniformStart, start);
404  glUniform1i(_stencilKernel.uniformEnd, end);
405  glUniform1i(_stencilKernel.uniformSrcOffset, srcDesc.offset);
406  glUniform1i(_stencilKernel.uniformDstOffset, dstDesc.offset);
407  if (_stencilKernel.uniformDuDesc > 0) {
408  glUniform3i(_stencilKernel.uniformDuDesc, duDesc.offset, duDesc.length, duDesc.stride);
409  }
410  if (_stencilKernel.uniformDvDesc > 0) {
411  glUniform3i(_stencilKernel.uniformDvDesc, dvDesc.offset, dvDesc.length, dvDesc.stride);
412  }
413  if (_stencilKernel.uniformDuuDesc > 0) {
414  glUniform3i(_stencilKernel.uniformDuuDesc, duuDesc.offset, duuDesc.length, duuDesc.stride);
415  }
416  if (_stencilKernel.uniformDuvDesc > 0) {
417  glUniform3i(_stencilKernel.uniformDuvDesc, duvDesc.offset, duvDesc.length, duvDesc.stride);
418  }
419  if (_stencilKernel.uniformDvvDesc > 0) {
420  glUniform3i(_stencilKernel.uniformDvvDesc, dvvDesc.offset, dvvDesc.length, dvvDesc.stride);
421  }
422 
423  DispatchCompute(count);
424 
425  glUseProgram(activeProgram);
426 
427  glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
428  for (int i = 0; i < 16; ++i) {
429  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, 0);
430  }
431 
432  return true;
433 }
434 
435 bool GLComputeEvaluator::EvalPatches(GLuint srcBuffer,
436  BufferDescriptor const &srcDesc,
437  GLuint dstBuffer,
438  BufferDescriptor const &dstDesc,
439  GLuint duBuffer,
440  BufferDescriptor const &duDesc,
441  GLuint dvBuffer,
442  BufferDescriptor const &dvDesc,
443  int numPatchCoords,
444  GLuint patchCoordsBuffer,
445  const PatchArrayVector &patchArrays,
446  GLuint patchIndexBuffer,
447  GLuint patchParamsBuffer) const
448 {
449 
450  return EvalPatches(srcBuffer,
451  srcDesc,
452  dstBuffer,
453  dstDesc,
454  duBuffer,
455  duDesc,
456  dvBuffer,
457  dvDesc,
458  0,
459  BufferDescriptor(),
460  0,
461  BufferDescriptor(),
462  0,
463  BufferDescriptor(),
464  numPatchCoords,
465  patchCoordsBuffer,
466  patchArrays,
467  patchIndexBuffer,
468  patchParamsBuffer);
469 }
470 
471 bool GLComputeEvaluator::EvalPatches(GLuint srcBuffer,
472  BufferDescriptor const &srcDesc,
473  GLuint dstBuffer,
474  BufferDescriptor const &dstDesc,
475  GLuint duBuffer,
476  BufferDescriptor const &duDesc,
477  GLuint dvBuffer,
478  BufferDescriptor const &dvDesc,
479  GLuint duuBuffer,
480  BufferDescriptor const &duuDesc,
481  GLuint duvBuffer,
482  BufferDescriptor const &duvDesc,
483  GLuint dvvBuffer,
484  BufferDescriptor const &dvvDesc,
485  int numPatchCoords,
486  GLuint patchCoordsBuffer,
487  const PatchArrayVector &patchArrays,
488  GLuint patchIndexBuffer,
489  GLuint patchParamsBuffer) const
490 {
491 
492  if (!_patchKernel.program)
493  return false;
494 
495  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, srcBuffer);
496  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, dstBuffer);
497  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, duBuffer);
498  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, dvBuffer);
499  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, duuBuffer);
500  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 11, duvBuffer);
501  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 12, dvvBuffer);
502  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, patchCoordsBuffer);
503  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, patchIndexBuffer);
504  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, patchParamsBuffer);
505 
506  GLint activeProgram;
507  glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
508  glUseProgram(_patchKernel.program);
509 
510  glUniform1i(_patchKernel.uniformSrcOffset, srcDesc.offset);
511  glUniform1i(_patchKernel.uniformDstOffset, dstDesc.offset);
512 
513  int patchArraySize = sizeof(PatchArray);
514  glBindBuffer(GL_SHADER_STORAGE_BUFFER, _patchArraysSSBO);
515  glBufferData(
516  GL_SHADER_STORAGE_BUFFER, patchArrays.size() * patchArraySize, NULL, GL_STATIC_DRAW);
517  for (int i = 0; i < (int)patchArrays.size(); ++i) {
518  glBufferSubData(
519  GL_SHADER_STORAGE_BUFFER, i * patchArraySize, sizeof(PatchArray), &patchArrays[i]);
520  }
521  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, _patchArraysSSBO);
522 
523  if (_patchKernel.uniformDuDesc > 0) {
524  glUniform3i(_patchKernel.uniformDuDesc, duDesc.offset, duDesc.length, duDesc.stride);
525  }
526  if (_patchKernel.uniformDvDesc > 0) {
527  glUniform3i(_patchKernel.uniformDvDesc, dvDesc.offset, dvDesc.length, dvDesc.stride);
528  }
529  if (_patchKernel.uniformDuuDesc > 0) {
530  glUniform3i(_patchKernel.uniformDuuDesc, duuDesc.offset, duuDesc.length, duuDesc.stride);
531  }
532  if (_patchKernel.uniformDuvDesc > 0) {
533  glUniform3i(_patchKernel.uniformDuvDesc, duvDesc.offset, duvDesc.length, duvDesc.stride);
534  }
535  if (_patchKernel.uniformDvvDesc > 0) {
536  glUniform3i(_patchKernel.uniformDvvDesc, dvvDesc.offset, dvvDesc.length, dvvDesc.stride);
537  }
538 
539  DispatchCompute(numPatchCoords);
540 
541  glUseProgram(activeProgram);
542 
543  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
544  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
545  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
546  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
547  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 0);
548  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, 0);
549  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, 0);
550 
551  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, 0);
552  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 11, 0);
553  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 12, 0);
554 
555  return true;
556 }
557 // ---------------------------------------------------------------------------
558 
559 GLComputeEvaluator::_StencilKernel::_StencilKernel() : program(0)
560 {
561 }
562 GLComputeEvaluator::_StencilKernel::~_StencilKernel()
563 {
564  if (program) {
565  glDeleteProgram(program);
566  }
567 }
568 
569 bool GLComputeEvaluator::_StencilKernel::Compile(BufferDescriptor const &srcDesc,
570  BufferDescriptor const &dstDesc,
571  BufferDescriptor const &duDesc,
572  BufferDescriptor const &dvDesc,
573  BufferDescriptor const &duuDesc,
574  BufferDescriptor const &duvDesc,
575  BufferDescriptor const &dvvDesc,
576  int workGroupSize)
577 {
578  // create stencil kernel
579  if (program) {
580  glDeleteProgram(program);
581  }
582 
583  const char *kernelDefine = "#define OPENSUBDIV_GLSL_COMPUTE_KERNEL_EVAL_STENCILS\n";
584 
586  srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, kernelDefine, workGroupSize);
587  if (program == 0)
588  return false;
589 
590  // cache uniform locations (TODO: use uniform block)
591  uniformStart = glGetUniformLocation(program, "batchStart");
592  uniformEnd = glGetUniformLocation(program, "batchEnd");
593  uniformSrcOffset = glGetUniformLocation(program, "srcOffset");
594  uniformDstOffset = glGetUniformLocation(program, "dstOffset");
595  uniformDuDesc = glGetUniformLocation(program, "duDesc");
596  uniformDvDesc = glGetUniformLocation(program, "dvDesc");
597  uniformDuuDesc = glGetUniformLocation(program, "duuDesc");
598  uniformDuvDesc = glGetUniformLocation(program, "duvDesc");
599  uniformDvvDesc = glGetUniformLocation(program, "dvvDesc");
600 
601  return true;
602 }
603 
604 // ---------------------------------------------------------------------------
605 
606 GLComputeEvaluator::_PatchKernel::_PatchKernel() : program(0)
607 {
608 }
609 GLComputeEvaluator::_PatchKernel::~_PatchKernel()
610 {
611  if (program) {
612  glDeleteProgram(program);
613  }
614 }
615 
616 bool GLComputeEvaluator::_PatchKernel::Compile(BufferDescriptor const &srcDesc,
617  BufferDescriptor const &dstDesc,
618  BufferDescriptor const &duDesc,
619  BufferDescriptor const &dvDesc,
620  BufferDescriptor const &duuDesc,
621  BufferDescriptor const &duvDesc,
622  BufferDescriptor const &dvvDesc,
623  int workGroupSize)
624 {
625  // create stencil kernel
626  if (program) {
627  glDeleteProgram(program);
628  }
629 
630  const char *kernelDefine = "#define OPENSUBDIV_GLSL_COMPUTE_KERNEL_EVAL_PATCHES\n";
631 
633  srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, kernelDefine, workGroupSize);
634  if (program == 0)
635  return false;
636 
637  // cache uniform locations
638  uniformSrcOffset = glGetUniformLocation(program, "srcOffset");
639  uniformDstOffset = glGetUniformLocation(program, "dstOffset");
640  uniformPatchArray = glGetUniformLocation(program, "patchArray");
641  uniformDuDesc = glGetUniformLocation(program, "duDesc");
642  uniformDvDesc = glGetUniformLocation(program, "dvDesc");
643  uniformDuuDesc = glGetUniformLocation(program, "duuDesc");
644  uniformDuvDesc = glGetUniformLocation(program, "duvDesc");
645  uniformDvvDesc = glGetUniformLocation(program, "dvvDesc");
646 
647  return true;
648 }
649 
650 } // namespace opensubdiv
651 } // namespace blender
sqrt(x)+1/max(0
bool Compile(OpenSubdiv::Osd::BufferDescriptor const &srcDesc, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, OpenSubdiv::Osd::BufferDescriptor const &duDesc=OpenSubdiv::Osd::BufferDescriptor(), OpenSubdiv::Osd::BufferDescriptor const &dvDesc=OpenSubdiv::Osd::BufferDescriptor(), OpenSubdiv::Osd::BufferDescriptor const &duuDesc=OpenSubdiv::Osd::BufferDescriptor(), OpenSubdiv::Osd::BufferDescriptor const &duvDesc=OpenSubdiv::Osd::BufferDescriptor(), OpenSubdiv::Osd::BufferDescriptor const &dvvDesc=OpenSubdiv::Osd::BufferDescriptor())
static bool EvalPatches(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, int numPatchCoords, PATCHCOORD_BUFFER *patchCoords, PATCH_TABLE *patchTable, GLComputeEvaluator const *instance, void *deviceContext=NULL)
Generic limit eval function. This function has a same signature as other device kernels have so that ...
static bool EvalStencils(SRC_BUFFER *srcBuffer, OpenSubdiv::Osd::BufferDescriptor const &srcDesc, DST_BUFFER *dstBuffer, OpenSubdiv::Osd::BufferDescriptor const &dstDesc, STENCIL_TABLE const *stencilTable, GLComputeEvaluator const *instance, void *deviceContext=NULL)
Generic static stencil function. This function has a same signature as other device kernels have so t...
static void Synchronize(void *deviceContext)
Wait the dispatched kernel finishes.
~GLComputeEvaluator()
Destructor. note that the GL context must be made current.
GLStencilTableSSBO(OpenSubdiv::Far::StencilTable const *stencilTable)
SyclQueue void void * src
char datatoc_glsl_compute_kernel_glsl[]
int count
ccl_global float * buffer
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
#define T
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
static GLuint compileKernel(BufferDescriptor const &srcDesc, BufferDescriptor const &dstDesc, BufferDescriptor const &duDesc, BufferDescriptor const &dvDesc, BufferDescriptor const &duuDesc, BufferDescriptor const &duvDesc, BufferDescriptor const &dvvDesc, const char *kernelDefine, int workGroupSize)
GLuint createSSBO(std::vector< T > const &src)