patch_eval_simd.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "patch.h"
  18. #include "feature_adaptive_eval_simd.h"
  19. namespace embree
  20. {
  21. namespace isa
  22. {
  23. template<typename vbool, typename vint, typename vfloat, typename Vertex, typename Vertex_t = Vertex>
  24. struct PatchEvalSimd
  25. {
  26. public:
  27. typedef PatchT<Vertex,Vertex_t> Patch;
  28. typedef typename Patch::Ref Ref;
  29. typedef CatmullClarkPatchT<Vertex,Vertex_t> CatmullClarkPatch;
  30. PatchEvalSimd (SharedLazyTessellationCache::CacheEntry& entry, size_t commitCounter,
  31. const HalfEdge* edge, const char* vertices, size_t stride, const vbool& valid0, const vfloat& u, const vfloat& v,
  32. float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, const size_t dstride, const size_t N)
  33. : P(P), dPdu(dPdu), dPdv(dPdv), ddPdudu(ddPdudu), ddPdvdv(ddPdvdv), ddPdudv(ddPdudv), dstride(dstride), N(N)
  34. {
  35. /* conservative time for the very first allocation */
  36. auto time = SharedLazyTessellationCache::sharedLazyTessellationCache.getTime(commitCounter);
  37. Ref patch = SharedLazyTessellationCache::lookup(entry,commitCounter,[&] () {
  38. auto alloc = [](size_t bytes) { return SharedLazyTessellationCache::malloc(bytes); };
  39. return Patch::create(alloc,edge,vertices,stride);
  40. }, true);
  41. auto curTime = SharedLazyTessellationCache::sharedLazyTessellationCache.getTime(commitCounter);
  42. const bool allAllocationsValid = SharedLazyTessellationCache::validTime(time,curTime);
  43. patch = allAllocationsValid ? patch : nullptr;
  44. /* use cached data structure for calculations */
  45. const vbool valid1 = patch ? eval(valid0,patch,u,v,1.0f,0) : vbool(false);
  46. SharedLazyTessellationCache::unlock();
  47. const vbool valid2 = valid0 & !valid1;
  48. if (any(valid2)) {
  49. FeatureAdaptiveEvalSimd<vbool,vint,vfloat,Vertex,Vertex_t>(edge,vertices,stride,valid2,u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dstride,N);
  50. }
  51. }
  52. vbool eval_quad(const vbool& valid, const typename Patch::SubdividedQuadPatch* This, const vfloat& u, const vfloat& v, const float dscale, const size_t depth)
  53. {
  54. vbool ret = false;
  55. const vbool u0_mask = u < 0.5f, u1_mask = u >= 0.5f;
  56. const vbool v0_mask = v < 0.5f, v1_mask = v >= 0.5f;
  57. const vbool u0v0_mask = valid & u0_mask & v0_mask;
  58. const vbool u0v1_mask = valid & u0_mask & v1_mask;
  59. const vbool u1v0_mask = valid & u1_mask & v0_mask;
  60. const vbool u1v1_mask = valid & u1_mask & v1_mask;
  61. if (any(u0v0_mask)) ret |= eval(u0v0_mask,This->child[0],2.0f*u,2.0f*v,2.0f*dscale,depth+1);
  62. if (any(u1v0_mask)) ret |= eval(u1v0_mask,This->child[1],2.0f*u-1.0f,2.0f*v,2.0f*dscale,depth+1);
  63. if (any(u1v1_mask)) ret |= eval(u1v1_mask,This->child[2],2.0f*u-1.0f,2.0f*v-1.0f,2.0f*dscale,depth+1);
  64. if (any(u0v1_mask)) ret |= eval(u0v1_mask,This->child[3],2.0f*u,2.0f*v-1.0f,2.0f*dscale,depth+1);
  65. return ret;
  66. }
  67. vbool eval_general(const vbool& valid, const typename Patch::SubdividedGeneralPatch* patch, const vfloat& U, const vfloat& V, const size_t depth)
  68. {
  69. vbool ret = false;
  70. const vint l = (vint)floor(4.0f*U); const vfloat u = 2.0f*frac(4.0f*U);
  71. const vint h = (vint)floor(4.0f*V); const vfloat v = 2.0f*frac(4.0f*V);
  72. const vint i = (h<<2)+l; assert(all(valid,i<patch->N));
  73. foreach_unique(valid,i,[&](const vbool& valid, const int i) {
  74. ret |= eval(valid,patch->child[i],u,v,8.0f,depth+1);
  75. });
  76. return ret;
  77. }
  78. vbool eval(const vbool& valid, Ref This, const vfloat& u, const vfloat& v, const float dscale, const size_t depth)
  79. {
  80. if (!This) return false;
  81. switch (This.type())
  82. {
  83. case Patch::BILINEAR_PATCH: {
  84. ((typename Patch::BilinearPatch*)This.object())->patch.eval(valid,u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale,dstride,N);
  85. return valid;
  86. }
  87. case Patch::BSPLINE_PATCH: {
  88. ((typename Patch::BSplinePatch*)This.object())->patch.eval(valid,u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale,dstride,N);
  89. return valid;
  90. }
  91. case Patch::BEZIER_PATCH: {
  92. ((typename Patch::BezierPatch*)This.object())->patch.eval(valid,u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale,dstride,N);
  93. return valid;
  94. }
  95. case Patch::GREGORY_PATCH: {
  96. ((typename Patch::GregoryPatch*)This.object())->patch.eval(valid,u,v,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dscale,dstride,N);
  97. return valid;
  98. }
  99. case Patch::SUBDIVIDED_QUAD_PATCH: {
  100. return eval_quad(valid,((typename Patch::SubdividedQuadPatch*)This.object()),u,v,dscale,depth);
  101. }
  102. case Patch::SUBDIVIDED_GENERAL_PATCH: {
  103. assert(dscale == 1.0f);
  104. return eval_general(valid,((typename Patch::SubdividedGeneralPatch*)This.object()),u,v,depth);
  105. }
  106. case Patch::EVAL_PATCH: {
  107. CatmullClarkPatch patch; patch.deserialize(This.object());
  108. FeatureAdaptiveEvalSimd<vbool,vint,vfloat,Vertex,Vertex_t>(patch,valid,u,v,dscale,depth,P,dPdu,dPdv,ddPdudu,ddPdvdv,ddPdudv,dstride,N);
  109. return valid;
  110. }
  111. default:
  112. assert(false);
  113. return false;
  114. }
  115. }
  116. private:
  117. float* const P;
  118. float* const dPdu;
  119. float* const dPdv;
  120. float* const ddPdudu;
  121. float* const ddPdvdv;
  122. float* const ddPdudv;
  123. const size_t dstride;
  124. const size_t N;
  125. };
  126. }
  127. }