Path: blob/master/thirdparty/embree/kernels/subdiv/tessellation.h
9913 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45namespace embree6{7/* adjust discret tessellation level for feature-adaptive pre-subdivision */8__forceinline float adjustTessellationLevel(float l, const size_t sublevel)9{10for (size_t i=0; i<sublevel; i++) l *= 0.5f;11float r = ceilf(l);12for (size_t i=0; i<sublevel; i++) r *= 2.0f;13return r;14}1516__forceinline int stitch(const int x, const int fine, const int coarse) {17return (2*x+1)*coarse/(2*fine);18}1920__forceinline void stitchGridEdges(const unsigned int low_rate,21const unsigned int high_rate,22const unsigned int x0,23const unsigned int x1,24float * __restrict__ const uv_array,25const unsigned int uv_array_step)26{27#if 128const float inv_low_rate = rcp((float)(low_rate-1));29for (unsigned x=x0; x<=x1; x++) {30uv_array[(x-x0)*uv_array_step] = float(stitch(x,high_rate-1,low_rate-1))*inv_low_rate;31}32if (unlikely(x1 == high_rate-1))33uv_array[(x1-x0)*uv_array_step] = 1.0f;34#else35assert(low_rate < high_rate);36assert(high_rate >= 2);3738const float inv_low_rate = rcp((float)(low_rate-1));39const unsigned int dy = low_rate - 1;40const unsigned int dx = high_rate - 1;4142int p = 2*dy-dx;4344unsigned int offset = 0;45unsigned int y = 0;46float value = 0.0f;47for(unsigned int x=0;x<high_rate-1; x++) // '<=' would be correct but we will leave the 1.0f at the end48{49uv_array[offset] = value;5051offset += uv_array_step;52if (unlikely(p > 0))53{54y++;55value = (float)y * inv_low_rate;56p -= 2*dx;57}58p += 2*dy;59}60#endif61}6263__forceinline void stitchUVGrid(const float edge_levels[4],64const unsigned int swidth,65const unsigned int sheight,66const unsigned int x0,67const unsigned int y0,68const unsigned int grid_u_res,69const unsigned int grid_v_res,70float * __restrict__ const u_array,71float * __restrict__ const v_array)72{73const unsigned int x1 = x0+grid_u_res-1;74const unsigned int y1 = y0+grid_v_res-1;75const unsigned int int_edge_points0 = (unsigned int)edge_levels[0] + 1;76const unsigned int int_edge_points1 = (unsigned int)edge_levels[1] + 1;77const unsigned int int_edge_points2 = (unsigned int)edge_levels[2] + 1;78const unsigned int int_edge_points3 = (unsigned int)edge_levels[3] + 1;7980if (unlikely(y0 == 0 && int_edge_points0 < swidth))81stitchGridEdges(int_edge_points0,swidth,x0,x1,u_array,1);8283if (unlikely(y1 == sheight-1 && int_edge_points2 < swidth))84stitchGridEdges(int_edge_points2,swidth,x0,x1,&u_array[(grid_v_res-1)*grid_u_res],1);8586if (unlikely(x0 == 0 && int_edge_points1 < sheight))87stitchGridEdges(int_edge_points1,sheight,y0,y1,&v_array[grid_u_res-1],grid_u_res);8889if (unlikely(x1 == swidth-1 && int_edge_points3 < sheight))90stitchGridEdges(int_edge_points3,sheight,y0,y1,v_array,grid_u_res);91}9293__forceinline void gridUVTessellator(const float edge_levels[4],94const unsigned int swidth,95const unsigned int sheight,96const unsigned int x0,97const unsigned int y0,98const unsigned int grid_u_res,99const unsigned int grid_v_res,100float * __restrict__ const u_array,101float * __restrict__ const v_array)102{103assert( grid_u_res >= 1);104assert( grid_v_res >= 1);105assert( edge_levels[0] >= 1.0f );106assert( edge_levels[1] >= 1.0f );107assert( edge_levels[2] >= 1.0f );108assert( edge_levels[3] >= 1.0f );109110#if defined(__AVX__)111const vint8 grid_u_segments = vint8(swidth)-1;112const vint8 grid_v_segments = vint8(sheight)-1;113114const vfloat8 inv_grid_u_segments = rcp(vfloat8(grid_u_segments));115const vfloat8 inv_grid_v_segments = rcp(vfloat8(grid_v_segments));116117unsigned int index = 0;118vint8 v_i( zero );119for (unsigned int y=0;y<grid_v_res;y++,index+=grid_u_res,v_i += 1)120{121vint8 u_i ( step );122123const vbool8 m_v = v_i < grid_v_segments;124125for (unsigned int x=0;x<grid_u_res;x+=8, u_i += 8)126{127const vbool8 m_u = u_i < grid_u_segments;128const vfloat8 u = select(m_u, vfloat8(x0+u_i) * inv_grid_u_segments, 1.0f);129const vfloat8 v = select(m_v, vfloat8(y0+v_i) * inv_grid_v_segments, 1.0f);130vfloat8::storeu(&u_array[index + x],u);131vfloat8::storeu(&v_array[index + x],v);132}133}134#else135const vint4 grid_u_segments = vint4(swidth)-1;136const vint4 grid_v_segments = vint4(sheight)-1;137138const vfloat4 inv_grid_u_segments = rcp(vfloat4(grid_u_segments));139const vfloat4 inv_grid_v_segments = rcp(vfloat4(grid_v_segments));140141unsigned int index = 0;142vint4 v_i( zero );143for (unsigned int y=0;y<grid_v_res;y++,index+=grid_u_res,v_i += 1)144{145vint4 u_i ( step );146147const vbool4 m_v = v_i < grid_v_segments;148149for (unsigned int x=0;x<grid_u_res;x+=4, u_i += 4)150{151const vbool4 m_u = u_i < grid_u_segments;152const vfloat4 u = select(m_u, vfloat4(x0+u_i) * inv_grid_u_segments, 1.0f);153const vfloat4 v = select(m_v, vfloat4(y0+v_i) * inv_grid_v_segments, 1.0f);154vfloat4::storeu(&u_array[index + x],u);155vfloat4::storeu(&v_array[index + x],v);156}157}158#endif159}160}161162163