void computeWithDerivative(tbb::blocked_range<int> const &r) const { float wP[20], wDs[20], wDt[20]; BufferAdapter<const float> srcT(_src + _srcDesc.offset, _srcDesc.length, _srcDesc.stride); BufferAdapter<float> dstT(_dst + _dstDesc.offset + r.begin() * _dstDesc.stride, _dstDesc.length, _dstDesc.stride); BufferAdapter<float> dstDuT(_dstDu + _dstDuDesc.offset + r.begin() * _dstDuDesc.stride, _dstDuDesc.length, _dstDuDesc.stride); BufferAdapter<float> dstDvT(_dstDv + _dstDvDesc.offset + r.begin() * _dstDvDesc.stride, _dstDvDesc.length, _dstDvDesc.stride); for (int i = r.begin(); i < r.end(); ++i) { PatchCoord const &coord = _patchCoords[i]; PatchArray const &array = _patchArrayBuffer[coord.handle.arrayIndex]; int patchType = array.GetPatchType(); Far::PatchParam const & param = _patchParamBuffer[coord.handle.patchIndex]; int numControlVertices = 0; if (patchType == Far::PatchDescriptor::REGULAR) { Far::internal::GetBSplineWeights(param, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 16; } else if (patchType == Far::PatchDescriptor::GREGORY_BASIS) { Far::internal::GetGregoryWeights(param, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 20; } else if (patchType == Far::PatchDescriptor::QUADS) { Far::internal::GetBilinearWeights(param, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 4; } else { assert(0); } const int *cvs = &_patchIndexBuffer[array.indexBase + coord.handle.vertIndex]; dstT.Clear(); dstDuT.Clear(); dstDvT.Clear(); for (int j = 0; j < numControlVertices; ++j) { dstT.AddWithWeight(srcT[cvs[j]], wP[j]); dstDuT.AddWithWeight(srcT[cvs[j]], wDs[j]); dstDvT.AddWithWeight(srcT[cvs[j]], wDt[j]); } ++dstT; ++dstDuT; ++dstDvT; } }
/* static */ bool OmpEvaluator::EvalPatches( const float *src, BufferDescriptor const &srcDesc, float *dst, BufferDescriptor const &dstDesc, int numPatchCoords, const PatchCoord *patchCoords, const PatchArray *patchArrays, const int *patchIndexBuffer, const PatchParam *patchParamBuffer){ src += srcDesc.offset; if (dst) dst += dstDesc.offset; else return false; BufferAdapter<const float> srcT(src, srcDesc.length, srcDesc.stride); #pragma omp parallel for for (int i = 0; i < numPatchCoords; ++i) { BufferAdapter<float> dstT(dst + dstDesc.stride*i, dstDesc.length, dstDesc.stride); float wP[20], wDs[20], wDt[20]; PatchCoord const &coord = patchCoords[i]; PatchArray const &array = patchArrays[coord.handle.arrayIndex]; int patchType = array.GetPatchType(); // XXX: patchIndex is absolute. not sure it's consistent. // (should be offsetted by array.primitiveIdBase?) // patchParamBuffer[array.primitiveIdBase + coord.handle.patchIndex] Far::PatchParam::BitField patchBits = *(Far::PatchParam::BitField*) &patchParamBuffer[coord.handle.patchIndex].patchBits; int numControlVertices = 0; if (patchType == Far::PatchDescriptor::REGULAR) { Far::internal::GetBSplineWeights(patchBits, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 16; } else if (patchType == Far::PatchDescriptor::GREGORY_BASIS) { Far::internal::GetGregoryWeights(patchBits, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 20; } else if (patchType == Far::PatchDescriptor::QUADS) { Far::internal::GetBilinearWeights(patchBits, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 4; } else { continue; } const int *cvs = &patchIndexBuffer[array.indexBase + coord.handle.vertIndex]; dstT.Clear(); for (int j = 0; j < numControlVertices; ++j) { dstT.AddWithWeight(srcT[cvs[j]], wP[j]); } } return true; }
/* static */ bool OmpEvaluator::EvalPatches( const float *src, BufferDescriptor const &srcDesc, float *dst, BufferDescriptor const &dstDesc, float *du, BufferDescriptor const &duDesc, float *dv, BufferDescriptor const &dvDesc, int numPatchCoords, PatchCoord const *patchCoords, PatchArray const *patchArrays, const int *patchIndexBuffer, PatchParam const *patchParamBuffer) { src += srcDesc.offset; if (dst) dst += dstDesc.offset; if (du) du += duDesc.offset; if (dv) dv += dvDesc.offset; BufferAdapter<const float> srcT(src, srcDesc.length, srcDesc.stride); #pragma omp parallel for for (int i = 0; i < numPatchCoords; ++i) { float wP[20], wDs[20], wDt[20]; BufferAdapter<float> dstT(dst + dstDesc.stride*i, dstDesc.length, dstDesc.stride); BufferAdapter<float> duT(du + duDesc.stride*i, duDesc.length, duDesc.stride); BufferAdapter<float> dvT(dv + dvDesc.stride*i, dvDesc.length, dvDesc.stride); PatchCoord const &coord = patchCoords[i]; PatchArray const &array = patchArrays[coord.handle.arrayIndex]; int patchType = array.GetPatchType(); Far::PatchParam::BitField patchBits = *(Far::PatchParam::BitField*) &patchParamBuffer[coord.handle.patchIndex].patchBits; int numControlVertices = 0; if (patchType == Far::PatchDescriptor::REGULAR) { Far::internal::GetBSplineWeights(patchBits, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 16; } else if (patchType == Far::PatchDescriptor::GREGORY_BASIS) { Far::internal::GetGregoryWeights(patchBits, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 20; } else if (patchType == Far::PatchDescriptor::QUADS) { Far::internal::GetBilinearWeights(patchBits, coord.s, coord.t, wP, wDs, wDt); numControlVertices = 4; } else { continue; } const int *cvs = &patchIndexBuffer[array.indexBase + coord.handle.vertIndex]; dstT.Clear(); duT.Clear(); dvT.Clear(); for (int j = 0; j < numControlVertices; ++j) { dstT.AddWithWeight(srcT[cvs[j]], wP[j]); duT.AddWithWeight(srcT[cvs[j]], wDs[j]); dvT.AddWithWeight(srcT[cvs[j]], wDt[j]); } ++dstT; ++duT; ++dvT; } return true; }