// // Copyright 2013 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // //------------------------------------------------------------------------------ layout(local_size_x=WORK_GROUP_SIZE, local_size_y=1, local_size_z=1) in; layout(std430) buffer; // source and destination buffers uniform int srcOffset = 0; uniform int dstOffset = 0; layout(binding=0) buffer src_buffer { float srcVertexBuffer[]; }; layout(binding=1) buffer dst_buffer { float dstVertexBuffer[]; }; // derivative buffers (if needed) #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES) uniform ivec3 duDesc; uniform ivec3 dvDesc; layout(binding=2) buffer du_buffer { float duBuffer[]; }; layout(binding=3) buffer dv_buffer { float dvBuffer[]; }; #endif #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_2ND_DERIVATIVES) uniform ivec3 duuDesc; uniform ivec3 duvDesc; uniform ivec3 dvvDesc; layout(binding=10) buffer duu_buffer { float duuBuffer[]; }; layout(binding=11) buffer duv_buffer { float duvBuffer[]; }; layout(binding=12) buffer dvv_buffer { float dvvBuffer[]; }; #endif // stencil buffers #if defined(OPENSUBDIV_GLSL_COMPUTE_KERNEL_EVAL_STENCILS) uniform int batchStart = 0; uniform int batchEnd = 0; layout(binding=4) buffer stencilSizes { int _sizes[]; }; layout(binding=5) buffer stencilOffsets { int _offsets[]; }; layout(binding=6) buffer stencilIndices { int _indices[]; }; layout(binding=7) buffer stencilWeights { float _weights[]; }; #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES) layout(binding=8) buffer stencilDuWeights { float _duWeights[]; }; layout(binding=9) buffer stencilDvWeights { float _dvWeights[]; }; #endif #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_2ND_DERIVATIVES) layout(binding=13) buffer stencilDuuWeights { float _duuWeights[]; }; layout(binding=14) buffer stencilDuvWeights { float _duvWeights[]; }; layout(binding=15) buffer stencilDvvWeights { float _dvvWeights[]; }; #endif #endif // patch buffers #if defined(OPENSUBDIV_GLSL_COMPUTE_KERNEL_EVAL_PATCHES) layout(binding=4) buffer patchArray_buffer { OsdPatchArray patchArrayBuffer[]; }; layout(binding=5) buffer patchCoord_buffer { OsdPatchCoord patchCoords[]; }; layout(binding=6) buffer patchIndex_buffer { int patchIndexBuffer[]; }; layout(binding=7) buffer patchParam_buffer { OsdPatchParam patchParamBuffer[]; }; OsdPatchCoord GetPatchCoord(int coordIndex) { return patchCoords[coordIndex]; } OsdPatchArray GetPatchArray(int arrayIndex) { return patchArrayBuffer[arrayIndex]; } OsdPatchParam GetPatchParam(int patchIndex) { return patchParamBuffer[patchIndex]; } #endif //------------------------------------------------------------------------------ struct Vertex { float vertexData[LENGTH]; }; void clear(out Vertex v) { for (int i = 0; i < LENGTH; ++i) { v.vertexData[i] = 0; } } Vertex readVertex(int index) { Vertex v; int vertexIndex = srcOffset + index * SRC_STRIDE; for (int i = 0; i < LENGTH; ++i) { v.vertexData[i] = srcVertexBuffer[vertexIndex + i]; } return v; } void writeVertex(int index, Vertex v) { int vertexIndex = dstOffset + index * DST_STRIDE; for (int i = 0; i < LENGTH; ++i) { dstVertexBuffer[vertexIndex + i] = v.vertexData[i]; } } void addWithWeight(inout Vertex v, const Vertex src, float weight) { for (int i = 0; i < LENGTH; ++i) { v.vertexData[i] += weight * src.vertexData[i]; } } #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES) void writeDu(int index, Vertex du) { int duIndex = duDesc.x + index * duDesc.z; for (int i = 0; i < LENGTH; ++i) { duBuffer[duIndex + i] = du.vertexData[i]; } } void writeDv(int index, Vertex dv) { int dvIndex = dvDesc.x + index * dvDesc.z; for (int i = 0; i < LENGTH; ++i) { dvBuffer[dvIndex + i] = dv.vertexData[i]; } } #endif #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_2ND_DERIVATIVES) void writeDuu(int index, Vertex duu) { int duuIndex = duuDesc.x + index * duuDesc.z; for (int i = 0; i < LENGTH; ++i) { duuBuffer[duuIndex + i] = duu.vertexData[i]; } } void writeDuv(int index, Vertex duv) { int duvIndex = duvDesc.x + index * duvDesc.z; for (int i = 0; i < LENGTH; ++i) { duvBuffer[duvIndex + i] = duv.vertexData[i]; } } void writeDvv(int index, Vertex dvv) { int dvvIndex = dvvDesc.x + index * dvvDesc.z; for (int i = 0; i < LENGTH; ++i) { dvvBuffer[dvvIndex + i] = dvv.vertexData[i]; } } #endif //------------------------------------------------------------------------------ #if defined(OPENSUBDIV_GLSL_COMPUTE_KERNEL_EVAL_STENCILS) void main() { int current = int(gl_GlobalInvocationID.x) + batchStart; if (current>=batchEnd) { return; } Vertex dst; clear(dst); int offset = _offsets[current], size = _sizes[current]; for (int stencil = 0; stencil < size; ++stencil) { int vindex = offset + stencil; addWithWeight( dst, readVertex(_indices[vindex]), _weights[vindex]); } writeVertex(current, dst); #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES) Vertex du, dv; clear(du); clear(dv); for (int i=0; i 0) { // length writeDu(current, du); } if (dvDesc.y > 0) { writeDv(current, dv); } #endif #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_2ND_DERIVATIVES) Vertex duu, duv, dvv; clear(duu); clear(duv); clear(dvv); for (int i=0; i 0) { // length writeDuu(current, duu); } if (duvDesc.y > 0) { writeDuv(current, duv); } if (dvvDesc.y > 0) { writeDvv(current, dvv); } #endif } #endif //------------------------------------------------------------------------------ #if defined(OPENSUBDIV_GLSL_COMPUTE_KERNEL_EVAL_PATCHES) // PERFORMANCE: stride could be constant, but not as significant as length void main() { int current = int(gl_GlobalInvocationID.x); OsdPatchCoord coord = GetPatchCoord(current); OsdPatchArray array = GetPatchArray(coord.arrayIndex); OsdPatchParam param = GetPatchParam(coord.patchIndex); int patchType = OsdPatchParamIsRegular(param) ? array.regDesc : array.desc; float wP[20], wDu[20], wDv[20], wDuu[20], wDuv[20], wDvv[20]; int nPoints = OsdEvaluatePatchBasis(patchType, param, coord.s, coord.t, wP, wDu, wDv, wDuu, wDuv, wDvv); Vertex dst, du, dv, duu, duv, dvv; clear(dst); clear(du); clear(dv); clear(duu); clear(duv); clear(dvv); int indexBase = array.indexBase + array.stride * (coord.patchIndex - array.primitiveIdBase); for (int cv = 0; cv < nPoints; ++cv) { int index = patchIndexBuffer[indexBase + cv]; addWithWeight(dst, readVertex(index), wP[cv]); addWithWeight(du, readVertex(index), wDu[cv]); addWithWeight(dv, readVertex(index), wDv[cv]); addWithWeight(duu, readVertex(index), wDuu[cv]); addWithWeight(duv, readVertex(index), wDuv[cv]); addWithWeight(dvv, readVertex(index), wDvv[cv]); } writeVertex(current, dst); #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES) if (duDesc.y > 0) { // length writeDu(current, du); } if (dvDesc.y > 0) { writeDv(current, dv); } #endif #if defined(OPENSUBDIV_GLSL_COMPUTE_USE_2ND_DERIVATIVES) if (duuDesc.y > 0) { // length writeDuu(current, duu); } if (duvDesc.y > 0) { // length writeDuv(current, duv); } if (dvvDesc.y > 0) { writeDvv(current, dvv); } #endif } #endif