mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-09 08:10:07 +00:00
Mtl implementation whitespace fixes
Fixed numerous whitespace inconsistencies and violations in the core osd metal implementation and examples.
This commit is contained in:
parent
24c37eecd3
commit
291eff0bed
@ -48,42 +48,42 @@ const constant float4 patchColors[] = {
|
|||||||
float4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
float4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
||||||
float4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
|
float4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
|
||||||
float4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
|
float4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
|
||||||
|
|
||||||
float4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
|
float4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
|
||||||
float4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
|
float4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
|
||||||
float4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
|
float4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
|
||||||
float4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
|
float4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
|
||||||
float4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
|
float4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
|
||||||
float4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
|
float4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
|
||||||
|
|
||||||
float4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
|
float4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
|
||||||
float4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
|
float4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
|
||||||
float4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
|
float4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
|
||||||
float4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
|
float4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
|
||||||
float4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
|
float4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
|
||||||
float4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
|
float4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
|
||||||
|
|
||||||
float4(0.0f, 1.0f, 0.0f, 1.0f), // corner
|
float4(0.0f, 1.0f, 0.0f, 1.0f), // corner
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
|
||||||
|
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
|
||||||
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
@ -94,10 +94,10 @@ const constant float4 patchColors[] = {
|
|||||||
|
|
||||||
float4
|
float4
|
||||||
getAdaptivePatchColor(int3 patchParam, float sharpness)
|
getAdaptivePatchColor(int3 patchParam, float sharpness)
|
||||||
{
|
{
|
||||||
int pattern = popcount(OsdGetPatchTransitionMask(patchParam));
|
int pattern = popcount(OsdGetPatchTransitionMask(patchParam));
|
||||||
int edgeCount = popcount(OsdGetPatchBoundaryMask(patchParam));
|
int edgeCount = popcount(OsdGetPatchBoundaryMask(patchParam));
|
||||||
|
|
||||||
int patchType = 0;
|
int patchType = 0;
|
||||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||||
if (sharpness > 0) {
|
if (sharpness > 0) {
|
||||||
@ -111,7 +111,7 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
|
|||||||
if (edgeCount == 2) {
|
if (edgeCount == 2) {
|
||||||
patchType = 3; // CORNER
|
patchType = 3; // CORNER
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: it looks like edgeCount != 0 for some gregory boundary patches.
|
// XXX: it looks like edgeCount != 0 for some gregory boundary patches.
|
||||||
// there might be a bug somewhere...
|
// there might be a bug somewhere...
|
||||||
#if OSD_PATCH_GREGORY
|
#if OSD_PATCH_GREGORY
|
||||||
@ -121,7 +121,7 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
|
|||||||
#elif OSD_PATCH_GREGORY_BASIS
|
#elif OSD_PATCH_GREGORY_BASIS
|
||||||
patchType = 6;
|
patchType = 6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return patchColors[6*patchType + pattern];
|
return patchColors[6*patchType + pattern];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ float3 displacement(float3 position, float3 normal, float4 patchCoord, float mip
|
|||||||
,device ushort* textureDisplace_Packing
|
,device ushort* textureDisplace_Packing
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if DISPLACEMENT_HW_BILINEAR
|
#if DISPLACEMENT_HW_BILINEAR
|
||||||
float disp = PtexLookupFast(patchCoord, mipmapBias,
|
float disp = PtexLookupFast(patchCoord, mipmapBias,
|
||||||
textureDisplace_Data,
|
textureDisplace_Data,
|
||||||
@ -184,7 +184,7 @@ perturbNormalFromDisplacement(float3 position, float3 normal, float4 patchCoord,
|
|||||||
{
|
{
|
||||||
// by Morten S. Mikkelsen
|
// by Morten S. Mikkelsen
|
||||||
// http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf
|
// http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf
|
||||||
// slightly modified for ptex guttering
|
// slightly modified for ptex guttering
|
||||||
float3 vSigmaS = dfdx(position);
|
float3 vSigmaS = dfdx(position);
|
||||||
float3 vSigmaT = dfdy(position);
|
float3 vSigmaT = dfdy(position);
|
||||||
float3 vN = normal;
|
float3 vN = normal;
|
||||||
@ -198,11 +198,11 @@ perturbNormalFromDisplacement(float3 position, float3 normal, float4 patchCoord,
|
|||||||
#else
|
#else
|
||||||
float2 texDx = dfdx(patchCoord.xy);
|
float2 texDx = dfdx(patchCoord.xy);
|
||||||
float2 texDy = dfdy(patchCoord.xy);
|
float2 texDy = dfdy(patchCoord.xy);
|
||||||
|
|
||||||
// limit forward differencing to the width of ptex gutter
|
// limit forward differencing to the width of ptex gutter
|
||||||
const float resolution = 128.0;
|
const float resolution = 128.0;
|
||||||
float d = min(1.0f, (0.5/resolution)/max(length(texDx), length(texDy)));
|
float d = min(1.0f, (0.5/resolution)/max(length(texDx), length(texDy)));
|
||||||
|
|
||||||
float4 STll = patchCoord;
|
float4 STll = patchCoord;
|
||||||
float4 STlr = patchCoord + d * float4(texDx.x, texDx.y, 0, 0);
|
float4 STlr = patchCoord + d * float4(texDx.x, texDx.y, 0, 0);
|
||||||
float4 STul = patchCoord + d * float4(texDy.x, texDy.y, 0, 0);
|
float4 STul = patchCoord + d * float4(texDy.x, texDy.y, 0, 0);
|
||||||
@ -218,7 +218,7 @@ perturbNormalFromDisplacement(float3 position, float3 normal, float4 patchCoord,
|
|||||||
float dBs = (Hlr - Hll)/d;
|
float dBs = (Hlr - Hll)/d;
|
||||||
float dBt = (Hul - Hll)/d;
|
float dBt = (Hul - Hll)/d;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2);
|
float3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2);
|
||||||
return normalize(abs(fDet) * vN - vSurfGrad);
|
return normalize(abs(fDet) * vN - vSurfGrad);
|
||||||
}
|
}
|
||||||
@ -251,7 +251,7 @@ struct FragmentInput
|
|||||||
#if OSD_PATCH_REGULAR
|
#if OSD_PATCH_REGULAR
|
||||||
struct ControlPoint
|
struct ControlPoint
|
||||||
{
|
{
|
||||||
|
|
||||||
float3 P [[attribute(0)]];
|
float3 P [[attribute(0)]];
|
||||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||||
float3 P1 [[attribute(1)]];
|
float3 P1 [[attribute(1)]];
|
||||||
@ -274,7 +274,7 @@ struct PatchInput
|
|||||||
#elif OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
#elif OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||||
struct ControlPoint
|
struct ControlPoint
|
||||||
{
|
{
|
||||||
|
|
||||||
float3 P [[attribute(0)]];
|
float3 P [[attribute(0)]];
|
||||||
float3 Ep [[attribute(1)]];
|
float3 Ep [[attribute(1)]];
|
||||||
float3 Em [[attribute(2)]];
|
float3 Em [[attribute(2)]];
|
||||||
@ -333,7 +333,7 @@ kernel void compute_main(
|
|||||||
if(validThread)
|
if(validThread)
|
||||||
{
|
{
|
||||||
patchParam[subthreadgroup_in_threadgroup] = OsdGetPatchParam(real_threadgroup, osdBuffers.patchParamBuffer);
|
patchParam[subthreadgroup_in_threadgroup] = OsdGetPatchParam(real_threadgroup, osdBuffers.patchParamBuffer);
|
||||||
|
|
||||||
for(unsigned threadOffset = 0; threadOffset < CONTROL_POINTS_PER_THREAD; threadOffset++)
|
for(unsigned threadOffset = 0; threadOffset < CONTROL_POINTS_PER_THREAD; threadOffset++)
|
||||||
{
|
{
|
||||||
const auto vertexId = osdBuffers.indexBuffer[(thread_position_in_grid * CONTROL_POINTS_PER_THREAD + threadOffset) * IndexLookupStride];
|
const auto vertexId = osdBuffers.indexBuffer[(thread_position_in_grid * CONTROL_POINTS_PER_THREAD + threadOffset) * IndexLookupStride];
|
||||||
@ -440,20 +440,20 @@ vertex FragmentInput vertex_main(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
FragmentInput out;
|
FragmentInput out;
|
||||||
|
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
int3 patchParam = patchInput.patchParam;
|
int3 patchParam = patchInput.patchParam;
|
||||||
#else
|
#else
|
||||||
int3 patchParam = patchInput.patchParamBuffer[patch_id];
|
int3 patchParam = patchInput.patchParamBuffer[patch_id];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int refinementLevel = OsdGetPatchRefinementLevel(patchParam);
|
int refinementLevel = OsdGetPatchRefinementLevel(patchParam);
|
||||||
float tessLevel = min(frameConsts.TessLevel, (float)OSD_MAX_TESS_LEVEL) /
|
float tessLevel = min(frameConsts.TessLevel, (float)OSD_MAX_TESS_LEVEL) /
|
||||||
exp2((float)refinementLevel - 1);
|
exp2((float)refinementLevel - 1);
|
||||||
|
|
||||||
auto patchVertex = OsdComputePatch(tessLevel, position_in_patch, patch_id, patchInput);
|
auto patchVertex = OsdComputePatch(tessLevel, position_in_patch, patch_id, patchInput);
|
||||||
|
|
||||||
|
|
||||||
#if USE_DISPLACEMENT
|
#if USE_DISPLACEMENT
|
||||||
float3 position = displacement(patchVertex.position,
|
float3 position = displacement(patchVertex.position,
|
||||||
patchVertex.normal,
|
patchVertex.normal,
|
||||||
@ -468,7 +468,7 @@ vertex FragmentInput vertex_main(
|
|||||||
float3 position = patchVertex.position;
|
float3 position = patchVertex.position;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
out.positionOut = mul(frameConsts.ModelViewProjectionMatrix, float4(position, 1));
|
out.positionOut = mul(frameConsts.ModelViewProjectionMatrix, float4(position, 1));
|
||||||
out.position = mul(frameConsts.ModelViewMatrix, float4(position,1)).xyz;
|
out.position = mul(frameConsts.ModelViewMatrix, float4(position,1)).xyz;
|
||||||
out.normal = mul(frameConsts.ModelViewMatrix,float4(patchVertex.normal, 0)).xyz;
|
out.normal = mul(frameConsts.ModelViewMatrix,float4(patchVertex.normal, 0)).xyz;
|
||||||
@ -500,29 +500,29 @@ struct LightSource {
|
|||||||
float4 diffuse;
|
float4 diffuse;
|
||||||
float4 specular;
|
float4 specular;
|
||||||
};
|
};
|
||||||
|
|
||||||
float4
|
float4
|
||||||
lighting(float4 texColor, float3 Peye, float3 Neye, float occ, const constant LightSource (&lightSource)[NUM_LIGHTS])
|
lighting(float4 texColor, float3 Peye, float3 Neye, float occ, const constant LightSource (&lightSource)[NUM_LIGHTS])
|
||||||
{
|
{
|
||||||
float4 color = float4(0.0, 0.0, 0.0, 0.0);
|
float4 color = float4(0.0, 0.0, 0.0, 0.0);
|
||||||
float3 n = Neye;
|
float3 n = Neye;
|
||||||
|
|
||||||
for (int i = 0; i < NUM_LIGHTS; ++i) {
|
for (int i = 0; i < NUM_LIGHTS; ++i) {
|
||||||
|
|
||||||
float4 Plight = lightSource[i].position;
|
float4 Plight = lightSource[i].position;
|
||||||
float3 l = (Plight.w == 0.0)
|
float3 l = (Plight.w == 0.0)
|
||||||
? normalize(Plight.xyz) : normalize(Plight.xyz - Peye);
|
? normalize(Plight.xyz) : normalize(Plight.xyz - Peye);
|
||||||
|
|
||||||
float3 h = normalize(l + float3(0,0,1)); // directional viewer
|
float3 h = normalize(l + float3(0,0,1)); // directional viewer
|
||||||
|
|
||||||
float d = max(0.0, dot(n, l));
|
float d = max(0.0, dot(n, l));
|
||||||
float s = pow(max(0.0, dot(n, h)), 64.0f);
|
float s = pow(max(0.0, dot(n, h)), 64.0f);
|
||||||
|
|
||||||
color += (1.0 - occ) * ((lightSource[i].ambient +
|
color += (1.0 - occ) * ((lightSource[i].ambient +
|
||||||
d * lightSource[i].diffuse) * texColor +
|
d * lightSource[i].diffuse) * texColor +
|
||||||
s * lightSource[i].specular);
|
s * lightSource[i].specular);
|
||||||
}
|
}
|
||||||
|
|
||||||
color.a = 1.0;
|
color.a = 1.0;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
@ -546,11 +546,11 @@ edgeColor(float4 Cfill, float4 edgeDistance)
|
|||||||
#endif
|
#endif
|
||||||
float4 Cedge = float4(1.0, 1.0, 0.0, 1.0);
|
float4 Cedge = float4(1.0, 1.0, 0.0, 1.0);
|
||||||
float p = exp2(-2 * d * d);
|
float p = exp2(-2 * d * d);
|
||||||
|
|
||||||
#if defined(GEOMETRY_OUT_WIRE)
|
#if defined(GEOMETRY_OUT_WIRE)
|
||||||
if (p < 0.25) discard;
|
if (p < 0.25) discard;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Cfill.rgb = lerp(Cfill.rgb, Cedge.rgb, p);
|
Cfill.rgb = lerp(Cfill.rgb, Cedge.rgb, p);
|
||||||
#endif
|
#endif
|
||||||
return Cfill;
|
return Cfill;
|
||||||
@ -599,8 +599,8 @@ fragment float4 fragment_main(
|
|||||||
,const constant float4& shade [[buffer(2)]]
|
,const constant float4& shade [[buffer(2)]]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const auto displacementScale = config.displacementScale;
|
const auto displacementScale = config.displacementScale;
|
||||||
const auto mipmapBias = config.mipmapBias;
|
const auto mipmapBias = config.mipmapBias;
|
||||||
float4 outColor;
|
float4 outColor;
|
||||||
// ------------ normal ---------------
|
// ------------ normal ---------------
|
||||||
#if NORMAL_HW_SCREENSPACE || NORMAL_SCREENSPACE
|
#if NORMAL_HW_SCREENSPACE || NORMAL_SCREENSPACE
|
||||||
@ -617,25 +617,25 @@ fragment float4 fragment_main(
|
|||||||
config.mipmapBias,
|
config.mipmapBias,
|
||||||
textureDisplace_Data,
|
textureDisplace_Data,
|
||||||
textureDisplace_Packing);
|
textureDisplace_Packing);
|
||||||
|
|
||||||
disp *= displacementScale;
|
disp *= displacementScale;
|
||||||
du *= displacementScale;
|
du *= displacementScale;
|
||||||
dv *= displacementScale;
|
dv *= displacementScale;
|
||||||
|
|
||||||
float3 n = normalize(cross(input.tangent, input.bitangent));
|
float3 n = normalize(cross(input.tangent, input.bitangent));
|
||||||
float3 tangent = input.tangent + n * du.x;
|
float3 tangent = input.tangent + n * du.x;
|
||||||
float3 bitangent = input.bitangent + n * dv.x;
|
float3 bitangent = input.bitangent + n * dv.x;
|
||||||
|
|
||||||
#if NORMAL_BIQUADRATIC_WG
|
#if NORMAL_BIQUADRATIC_WG
|
||||||
tangent += input.Nu * disp.x;
|
tangent += input.Nu * disp.x;
|
||||||
bitangent += input.Nv * disp.x;
|
bitangent += input.Nv * disp.x;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float3 normal = normalize(cross(tangent, bitangent));
|
float3 normal = normalize(cross(tangent, bitangent));
|
||||||
#else
|
#else
|
||||||
float3 normal = input.normal;
|
float3 normal = input.normal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------ color ---------------
|
// ------------ color ---------------
|
||||||
#if COLOR_PTEX_NEAREST
|
#if COLOR_PTEX_NEAREST
|
||||||
float4 texColor = PtexLookupNearest(input.patchCoord,
|
float4 texColor = PtexLookupNearest(input.patchCoord,
|
||||||
@ -653,7 +653,7 @@ fragment float4 fragment_main(
|
|||||||
float4 texColor = PtexMipmapLookupQuadratic(input.patchCoord, mipmapBias,
|
float4 texColor = PtexMipmapLookupQuadratic(input.patchCoord, mipmapBias,
|
||||||
textureImage_Data,
|
textureImage_Data,
|
||||||
textureImage_Packing);
|
textureImage_Packing);
|
||||||
#elif COLOR_PATCHTYPE
|
#elif COLOR_PATCHTYPE
|
||||||
float4 texColor = lighting(float4(input.patchColor), input.position.xyz, normal, 0, lightSource);
|
float4 texColor = lighting(float4(input.patchColor), input.position.xyz, normal, 0, lightSource);
|
||||||
outColor = texColor;
|
outColor = texColor;
|
||||||
return outColor;
|
return outColor;
|
||||||
@ -668,9 +668,9 @@ fragment float4 fragment_main(
|
|||||||
#else // COLOR_NONE
|
#else // COLOR_NONE
|
||||||
float4 texColor = float4(0.5, 0.5, 0.5, 1);
|
float4 texColor = float4(0.5, 0.5, 0.5, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------ occlusion ---------------
|
// ------------ occlusion ---------------
|
||||||
|
|
||||||
#if USE_PTEX_OCCLUSION
|
#if USE_PTEX_OCCLUSION
|
||||||
float occ = PtexMipmapLookup(input.patchCoord, config.mipmapBias,
|
float occ = PtexMipmapLookup(input.patchCoord, config.mipmapBias,
|
||||||
textureOcclusion_Data,
|
textureOcclusion_Data,
|
||||||
@ -678,9 +678,9 @@ fragment float4 fragment_main(
|
|||||||
#else
|
#else
|
||||||
float occ = 0.0;
|
float occ = 0.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------ specular ---------------
|
// ------------ specular ---------------
|
||||||
|
|
||||||
#if USE_PTEX_SPECULAR
|
#if USE_PTEX_SPECULAR
|
||||||
float specular = PtexMipmapLookup(input.patchCoord, config.mipmapBias,
|
float specular = PtexMipmapLookup(input.patchCoord, config.mipmapBias,
|
||||||
textureSpecular_Data,
|
textureSpecular_Data,
|
||||||
@ -690,7 +690,7 @@ fragment float4 fragment_main(
|
|||||||
#endif
|
#endif
|
||||||
// ------------ lighting ---------------
|
// ------------ lighting ---------------
|
||||||
float4 Cf = lighting(texColor, input.position.xyz, normal, occ, lightSource);
|
float4 Cf = lighting(texColor, input.position.xyz, normal, occ, lightSource);
|
||||||
|
|
||||||
// ------------ wireframe ---------------
|
// ------------ wireframe ---------------
|
||||||
outColor = max(Cf, shade);
|
outColor = max(Cf, shade);
|
||||||
return outColor;
|
return outColor;
|
||||||
|
@ -122,33 +122,33 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
@implementation OSDRenderer {
|
@implementation OSDRenderer {
|
||||||
|
|
||||||
MTLRingBuffer<Light, 1> _lightsBuffer;
|
MTLRingBuffer<Light, 1> _lightsBuffer;
|
||||||
|
|
||||||
PerFrameBuffer<PerFrameConstants> _frameConstantsBuffer;
|
PerFrameBuffer<PerFrameConstants> _frameConstantsBuffer;
|
||||||
PerFrameBuffer<MTLQuadTessellationFactorsHalf> _tessFactorsBuffer;
|
PerFrameBuffer<MTLQuadTessellationFactorsHalf> _tessFactorsBuffer;
|
||||||
PerFrameBuffer<unsigned> _patchIndexBuffers[4];
|
PerFrameBuffer<unsigned> _patchIndexBuffers[4];
|
||||||
PerFrameBuffer<uint8_t> _perPatchDataBuffer;
|
PerFrameBuffer<uint8_t> _perPatchDataBuffer;
|
||||||
PerFrameBuffer<uint8_t> _hsDataBuffer;
|
PerFrameBuffer<uint8_t> _hsDataBuffer;
|
||||||
PerFrameBuffer<MTLDrawPatchIndirectArguments> _drawIndirectCommandsBuffer;
|
PerFrameBuffer<MTLDrawPatchIndirectArguments> _drawIndirectCommandsBuffer;
|
||||||
|
|
||||||
unsigned _tessFactorOffsets[4];
|
unsigned _tessFactorOffsets[4];
|
||||||
unsigned _perPatchDataOffsets[4];
|
unsigned _perPatchDataOffsets[4];
|
||||||
|
|
||||||
id<MTLComputePipelineState> _computePipelines[10];
|
id<MTLComputePipelineState> _computePipelines[10];
|
||||||
id<MTLRenderPipelineState> _renderPipelines[10];
|
id<MTLRenderPipelineState> _renderPipelines[10];
|
||||||
id<MTLDepthStencilState> _readWriteDepthStencilState;
|
id<MTLDepthStencilState> _readWriteDepthStencilState;
|
||||||
id<MTLDepthStencilState> _readOnlyDepthStencilState;
|
id<MTLDepthStencilState> _readOnlyDepthStencilState;
|
||||||
|
|
||||||
Camera _cameraData;
|
Camera _cameraData;
|
||||||
Osd::MTLContext _context;
|
Osd::MTLContext _context;
|
||||||
|
|
||||||
std::unique_ptr<MTLMeshInterface> _mesh;
|
std::unique_ptr<MTLMeshInterface> _mesh;
|
||||||
std::unique_ptr<Shape> _shape;
|
std::unique_ptr<Shape> _shape;
|
||||||
|
|
||||||
std::unique_ptr<MTLPtexMipmapTexture> _colorPtexture;
|
std::unique_ptr<MTLPtexMipmapTexture> _colorPtexture;
|
||||||
std::unique_ptr<MTLPtexMipmapTexture> _displacementPtexture;
|
std::unique_ptr<MTLPtexMipmapTexture> _displacementPtexture;
|
||||||
std::unique_ptr<MTLPtexMipmapTexture> _occlusionPtexture;
|
std::unique_ptr<MTLPtexMipmapTexture> _occlusionPtexture;
|
||||||
std::unique_ptr<MTLPtexMipmapTexture> _specularPtexture;
|
std::unique_ptr<MTLPtexMipmapTexture> _specularPtexture;
|
||||||
|
|
||||||
bool _needsRebuild, _doAdaptive;
|
bool _needsRebuild, _doAdaptive;
|
||||||
NSString* _osdShaderSource;
|
NSString* _osdShaderSource;
|
||||||
simd::float3 _meshCenter;
|
simd::float3 _meshCenter;
|
||||||
@ -180,27 +180,27 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
self.displacementMode = kDisplacementModeNone;
|
self.displacementMode = kDisplacementModeNone;
|
||||||
self.useAdaptive = true;
|
self.useAdaptive = true;
|
||||||
self.displayStyle = kDisplayStyleShaded;
|
self.displayStyle = kDisplayStyleShaded;
|
||||||
|
|
||||||
const auto colorFilename = getenv("COLOR_FILENAME");
|
const auto colorFilename = getenv("COLOR_FILENAME");
|
||||||
const auto displacementFilename = getenv("DISPLACEMENT_FILENAME");
|
const auto displacementFilename = getenv("DISPLACEMENT_FILENAME");
|
||||||
|
|
||||||
if(colorFilename)
|
if(colorFilename)
|
||||||
_ptexColorFilename = [NSString stringWithUTF8String:colorFilename];
|
_ptexColorFilename = [NSString stringWithUTF8String:colorFilename];
|
||||||
|
|
||||||
if(displacementFilename)
|
if(displacementFilename)
|
||||||
_ptexDisplacementFilename = [NSString stringWithUTF8String:displacementFilename];
|
_ptexDisplacementFilename = [NSString stringWithUTF8String:displacementFilename];
|
||||||
|
|
||||||
_delegate = delegate;
|
_delegate = delegate;
|
||||||
_context.device = [delegate deviceFor:self];
|
_context.device = [delegate deviceFor:self];
|
||||||
_context.commandQueue = [delegate commandQueueFor:self];
|
_context.commandQueue = [delegate commandQueueFor:self];
|
||||||
|
|
||||||
_osdShaderSource = @(shaderSource);
|
_osdShaderSource = @(shaderSource);
|
||||||
|
|
||||||
_needsRebuild = true;
|
_needsRebuild = true;
|
||||||
_numFrames = 0;
|
_numFrames = 0;
|
||||||
_animationFrames = 0;
|
_animationFrames = 0;
|
||||||
|
|
||||||
|
|
||||||
[self _initializeBuffers];
|
[self _initializeBuffers];
|
||||||
[self _initializeCamera];
|
[self _initializeCamera];
|
||||||
[self _initializeLights];
|
[self _initializeLights];
|
||||||
@ -213,13 +213,13 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
if(_needsRebuild) {
|
if(_needsRebuild) {
|
||||||
[self _rebuildState];
|
[self _rebuildState];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_freeze) {
|
if(!_freeze) {
|
||||||
if(_animateVertices) {
|
if(_animateVertices) {
|
||||||
_animatedVertices.resize(_vertexData.size());
|
_animatedVertices.resize(_vertexData.size());
|
||||||
auto p = _vertexData.data();
|
auto p = _vertexData.data();
|
||||||
auto n = _animatedVertices.data();
|
auto n = _animatedVertices.data();
|
||||||
|
|
||||||
float r = sin(_animationFrames*0.01f) * _animateVertices;
|
float r = sin(_animationFrames*0.01f) * _animateVertices;
|
||||||
for (int i = 0; i < _numVertices; ++i) {
|
for (int i = 0; i < _numVertices; ++i) {
|
||||||
float move = 0.05f*cosf(p[0]*20+_animationFrames*0.01f);
|
float move = 0.05f*cosf(p[0]*20+_animationFrames*0.01f);
|
||||||
@ -228,36 +228,36 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
n[0] = p[0]*ct + p[1]*st;
|
n[0] = p[0]*ct + p[1]*st;
|
||||||
n[1] = -p[0]*st + p[1]*ct;
|
n[1] = -p[0]*st + p[1]*ct;
|
||||||
n[2] = p[2];
|
n[2] = p[2];
|
||||||
|
|
||||||
p += _numVertexElements;
|
p += _numVertexElements;
|
||||||
n += _numVertexElements;
|
n += _numVertexElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mesh->UpdateVertexBuffer(_animatedVertices.data(), 0, _numVertices);
|
_mesh->UpdateVertexBuffer(_animatedVertices.data(), 0, _numVertices);
|
||||||
_animationFrames++;
|
_animationFrames++;
|
||||||
}
|
}
|
||||||
_mesh->Refine();
|
_mesh->Refine();
|
||||||
_mesh->Synchronize();
|
_mesh->Synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _updateState];
|
[self _updateState];
|
||||||
|
|
||||||
if(_doAdaptive) {
|
if(_doAdaptive) {
|
||||||
auto computeEncoder = [commandBuffer computeCommandEncoder];
|
auto computeEncoder = [commandBuffer computeCommandEncoder];
|
||||||
[self _computeTessFactors:computeEncoder];
|
[self _computeTessFactors:computeEncoder];
|
||||||
[computeEncoder endEncoding];
|
[computeEncoder endEncoding];
|
||||||
}
|
}
|
||||||
|
|
||||||
auto renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:[_delegate renderPassDescriptorFor: self]];
|
auto renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:[_delegate renderPassDescriptorFor: self]];
|
||||||
|
|
||||||
if(_usePrimitiveBackfaceCulling) {
|
if(_usePrimitiveBackfaceCulling) {
|
||||||
[renderEncoder setCullMode:MTLCullModeBack];
|
[renderEncoder setCullMode:MTLCullModeBack];
|
||||||
} else {
|
} else {
|
||||||
[renderEncoder setCullMode:MTLCullModeNone];
|
[renderEncoder setCullMode:MTLCullModeNone];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _renderMesh:renderEncoder];
|
[self _renderMesh:renderEncoder];
|
||||||
|
|
||||||
_frameConstantsBuffer.next();
|
_frameConstantsBuffer.next();
|
||||||
_tessFactorsBuffer.next();
|
_tessFactorsBuffer.next();
|
||||||
_patchIndexBuffers[0].next();
|
_patchIndexBuffers[0].next();
|
||||||
@ -268,25 +268,25 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
_perPatchDataBuffer.next();
|
_perPatchDataBuffer.next();
|
||||||
_hsDataBuffer.next();
|
_hsDataBuffer.next();
|
||||||
_drawIndirectCommandsBuffer.next();
|
_drawIndirectCommandsBuffer.next();
|
||||||
|
|
||||||
_numFrames++;
|
_numFrames++;
|
||||||
|
|
||||||
return renderEncoder;
|
return renderEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)_renderMesh:(id<MTLRenderCommandEncoder>)renderCommandEncoder {
|
-(void)_renderMesh:(id<MTLRenderCommandEncoder>)renderCommandEncoder {
|
||||||
auto buffer = _mesh->BindVertexBuffer();
|
auto buffer = _mesh->BindVertexBuffer();
|
||||||
assert(buffer);
|
assert(buffer);
|
||||||
|
|
||||||
auto pav = _mesh->GetPatchTable()->GetPatchArrays();
|
auto pav = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
auto pib = _mesh->GetPatchTable()->GetPatchIndexBuffer();
|
auto pib = _mesh->GetPatchTable()->GetPatchIndexBuffer();
|
||||||
|
|
||||||
[renderCommandEncoder setVertexBuffer:buffer offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:buffer offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer: pib offset:0 atIndex:INDICES_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer: pib offset:0 atIndex:INDICES_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:_frameConstantsBuffer offset:offsetof(PerFrameConstants, displacementConfig) atIndex:CONFIG_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_frameConstantsBuffer offset:offsetof(PerFrameConstants, displacementConfig) atIndex:CONFIG_BUFFER_INDEX];
|
||||||
|
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setVertexBuffer:_hsDataBuffer offset:0 atIndex:OSD_PERPATCHTESSFACTORS_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_hsDataBuffer offset:0 atIndex:OSD_PERPATCHTESSFACTORS_BUFFER_INDEX];
|
||||||
@ -294,49 +294,49 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder setVertexBuffer:_mesh->GetPatchTable()->GetPatchParamBuffer() offset:0 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_mesh->GetPatchTable()->GetPatchParamBuffer() offset:0 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
[renderCommandEncoder setFragmentBuffer:_frameConstantsBuffer offset:offsetof(PerFrameConstants, displacementConfig) atIndex:1];
|
[renderCommandEncoder setFragmentBuffer:_frameConstantsBuffer offset:offsetof(PerFrameConstants, displacementConfig) atIndex:1];
|
||||||
[renderCommandEncoder setFragmentBuffer:_lightsBuffer offset:0 atIndex:0];
|
[renderCommandEncoder setFragmentBuffer:_lightsBuffer offset:0 atIndex:0];
|
||||||
|
|
||||||
[renderCommandEncoder setFragmentTexture:_colorPtexture->GetTexelsTexture() atIndex:IMAGE_TEXTURE_INDEX];
|
[renderCommandEncoder setFragmentTexture:_colorPtexture->GetTexelsTexture() atIndex:IMAGE_TEXTURE_INDEX];
|
||||||
[renderCommandEncoder setFragmentBuffer:_colorPtexture->GetLayoutBuffer() offset:0 atIndex:IMAGE_BUFFER_INDEX];
|
[renderCommandEncoder setFragmentBuffer:_colorPtexture->GetLayoutBuffer() offset:0 atIndex:IMAGE_BUFFER_INDEX];
|
||||||
if(_displacementPtexture)
|
if(_displacementPtexture)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setFragmentTexture:_displacementPtexture->GetTexelsTexture() atIndex:DISPLACEMENT_TEXTURE_INDEX];
|
[renderCommandEncoder setFragmentTexture:_displacementPtexture->GetTexelsTexture() atIndex:DISPLACEMENT_TEXTURE_INDEX];
|
||||||
[renderCommandEncoder setFragmentBuffer:_displacementPtexture->GetLayoutBuffer() offset:0 atIndex:DISPLACEMENT_BUFFER_INDEX];
|
[renderCommandEncoder setFragmentBuffer:_displacementPtexture->GetLayoutBuffer() offset:0 atIndex:DISPLACEMENT_BUFFER_INDEX];
|
||||||
|
|
||||||
[renderCommandEncoder setVertexTexture:_displacementPtexture->GetTexelsTexture() atIndex:DISPLACEMENT_TEXTURE_INDEX];
|
[renderCommandEncoder setVertexTexture:_displacementPtexture->GetTexelsTexture() atIndex:DISPLACEMENT_TEXTURE_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:_displacementPtexture->GetLayoutBuffer() offset:0 atIndex:DISPLACEMENT_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_displacementPtexture->GetLayoutBuffer() offset:0 atIndex:DISPLACEMENT_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < pav.size(); i++)
|
for(int i = 0; i < pav.size(); i++)
|
||||||
{
|
{
|
||||||
auto& patch = pav[i];
|
auto& patch = pav[i];
|
||||||
auto d = patch.GetDescriptor();
|
auto d = patch.GetDescriptor();
|
||||||
auto patchType = d.GetType();
|
auto patchType = d.GetType();
|
||||||
auto offset = patchType - Far::PatchDescriptor::REGULAR;
|
auto offset = patchType - Far::PatchDescriptor::REGULAR;
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setVertexBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
[renderCommandEncoder setVertexBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
||||||
|
|
||||||
|
|
||||||
simd::float4 shade{.0f,0.0f,0.0f,1.0f};
|
simd::float4 shade{.0f,0.0f,0.0f,1.0f};
|
||||||
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
||||||
[renderCommandEncoder setDepthBias:0 slopeScale:1.0 clamp:0];
|
[renderCommandEncoder setDepthBias:0 slopeScale:1.0 clamp:0];
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||||
|
|
||||||
[renderCommandEncoder setDepthStencilState:_readWriteDepthStencilState];
|
[renderCommandEncoder setDepthStencilState:_readWriteDepthStencilState];
|
||||||
[renderCommandEncoder setRenderPipelineState:_renderPipelines[patchType]];
|
[renderCommandEncoder setRenderPipelineState:_renderPipelines[patchType]];
|
||||||
|
|
||||||
if(_displayStyle == kDisplayStyleWire)
|
if(_displayStyle == kDisplayStyleWire)
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
||||||
else
|
else
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||||
|
|
||||||
switch(patchType)
|
switch(patchType)
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::GREGORY_BASIS:
|
case Far::PatchDescriptor::GREGORY_BASIS:
|
||||||
@ -347,8 +347,8 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder setVertexBufferOffset:_perPatchDataOffsets[offset] atIndex:OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBufferOffset:_perPatchDataOffsets[offset] atIndex:OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch(patchType)
|
switch(patchType)
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::POINTS:
|
case Far::PatchDescriptor::POINTS:
|
||||||
@ -379,7 +379,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
||||||
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder drawIndexedPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
[renderCommandEncoder drawIndexedPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
||||||
@ -414,14 +414,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
||||||
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
|
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_displayStyle == kDisplayStyleWireOnShaded)
|
if(_displayStyle == kDisplayStyleWireOnShaded)
|
||||||
{
|
{
|
||||||
simd::float4 shade = {1, 1,1,1};
|
simd::float4 shade = {1, 1,1,1};
|
||||||
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
||||||
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
||||||
|
|
||||||
#if !TARGET_OS_EMBEDDED
|
#if !TARGET_OS_EMBEDDED
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
@ -439,8 +439,8 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case Far::PatchDescriptor::QUADS:
|
case Far::PatchDescriptor::QUADS:
|
||||||
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:patch.GetNumPatches() * 6];
|
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:patch.GetNumPatches() * 6];
|
||||||
break;
|
break;
|
||||||
@ -456,7 +456,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
|
|
||||||
-(void)_computeTessFactors:(id<MTLComputeCommandEncoder>)computeCommandEncoder {
|
-(void)_computeTessFactors:(id<MTLComputeCommandEncoder>)computeCommandEncoder {
|
||||||
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
|
|
||||||
[computeCommandEncoder setBuffer:_mesh->BindVertexBuffer() offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_mesh->BindVertexBuffer() offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchIndexBuffer() offset:0 atIndex:CONTROL_INDICES_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchIndexBuffer() offset:0 atIndex:CONTROL_INDICES_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchParamBuffer() offset:0 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchParamBuffer() offset:0 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
||||||
@ -465,40 +465,40 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[computeCommandEncoder setBuffer:_tessFactorsBuffer offset:0 atIndex:QUAD_TESSFACTORS_INDEX];
|
[computeCommandEncoder setBuffer:_tessFactorsBuffer offset:0 atIndex:QUAD_TESSFACTORS_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
||||||
|
|
||||||
for(auto& patch : patchArray)
|
for(auto& patch : patchArray)
|
||||||
{
|
{
|
||||||
auto usefulControlPoints = patch.GetDescriptor().GetNumControlVertices();
|
auto usefulControlPoints = patch.GetDescriptor().GetNumControlVertices();
|
||||||
if(patch.GetDescriptor().GetType() == Far::PatchDescriptor::GREGORY_BASIS)
|
if(patch.GetDescriptor().GetType() == Far::PatchDescriptor::GREGORY_BASIS)
|
||||||
usefulControlPoints = 4;
|
usefulControlPoints = 4;
|
||||||
|
|
||||||
auto threadsPerThreadgroup = MTLSizeMake([_computePipelines[patch.GetPatchType()] threadExecutionWidth], 1, 1);
|
auto threadsPerThreadgroup = MTLSizeMake([_computePipelines[patch.GetPatchType()] threadExecutionWidth], 1, 1);
|
||||||
auto threadsPerControlPoint = std::max<int>(1, usefulControlPoints / threadsPerThreadgroup.width);
|
auto threadsPerControlPoint = std::max<int>(1, usefulControlPoints / threadsPerThreadgroup.width);
|
||||||
|
|
||||||
auto groupPerControlPoint = MTLSizeMake(patch.GetNumPatches() * usefulControlPoints, 1, 1);
|
auto groupPerControlPoint = MTLSizeMake(patch.GetNumPatches() * usefulControlPoints, 1, 1);
|
||||||
|
|
||||||
groupPerControlPoint.width /= threadsPerControlPoint;
|
groupPerControlPoint.width /= threadsPerControlPoint;
|
||||||
|
|
||||||
groupPerControlPoint.width = (groupPerControlPoint.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
groupPerControlPoint.width = (groupPerControlPoint.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
||||||
groupPerControlPoint.width = groupPerControlPoint.width / threadsPerThreadgroup.width;
|
groupPerControlPoint.width = groupPerControlPoint.width / threadsPerThreadgroup.width;
|
||||||
|
|
||||||
|
|
||||||
auto groupPerPatch = MTLSizeMake(patch.GetNumPatches(), 1, 1);
|
auto groupPerPatch = MTLSizeMake(patch.GetNumPatches(), 1, 1);
|
||||||
groupPerPatch.width = (groupPerPatch.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
groupPerPatch.width = (groupPerPatch.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
||||||
groupPerPatch.width = groupPerPatch.width / threadsPerThreadgroup.width;
|
groupPerPatch.width = groupPerPatch.width / threadsPerThreadgroup.width;
|
||||||
|
|
||||||
[computeCommandEncoder setBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
[computeCommandEncoder setBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
[computeCommandEncoder setBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
||||||
|
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
[computeCommandEncoder setBuffer:_patchIndexBuffers[patch.desc.GetType() - Far::PatchDescriptor::REGULAR] offset:0 atIndex:OSD_PATCH_INDEX_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_patchIndexBuffers[patch.desc.GetType() - Far::PatchDescriptor::REGULAR] offset:0 atIndex:OSD_PATCH_INDEX_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_drawIndirectCommandsBuffer offset:sizeof(MTLDrawPatchIndirectArguments) * (patch.desc.GetType() - Far::PatchDescriptor::REGULAR) atIndex:OSD_DRAWINDIRECT_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_drawIndirectCommandsBuffer offset:sizeof(MTLDrawPatchIndirectArguments) * (patch.desc.GetType() - Far::PatchDescriptor::REGULAR) atIndex:OSD_DRAWINDIRECT_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
[computeCommandEncoder setComputePipelineState:_computePipelines[patch.desc.GetType()]];
|
[computeCommandEncoder setComputePipelineState:_computePipelines[patch.desc.GetType()]];
|
||||||
|
|
||||||
unsigned kernelExecutionLimit;
|
unsigned kernelExecutionLimit;
|
||||||
switch(patch.desc.GetType())
|
switch(patch.desc.GetType())
|
||||||
{
|
{
|
||||||
@ -514,7 +514,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
break;
|
break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[computeCommandEncoder setBytes:&kernelExecutionLimit length:sizeof(kernelExecutionLimit) atIndex:OSD_KERNELLIMIT_BUFFER_INDEX];
|
[computeCommandEncoder setBytes:&kernelExecutionLimit length:sizeof(kernelExecutionLimit) atIndex:OSD_KERNELLIMIT_BUFFER_INDEX];
|
||||||
[computeCommandEncoder dispatchThreadgroups:groupPerControlPoint threadsPerThreadgroup:threadsPerThreadgroup];
|
[computeCommandEncoder dispatchThreadgroups:groupPerControlPoint threadsPerThreadgroup:threadsPerThreadgroup];
|
||||||
}
|
}
|
||||||
@ -525,7 +525,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[self _rebuildModel];
|
[self _rebuildModel];
|
||||||
[self _rebuildBuffers];
|
[self _rebuildBuffers];
|
||||||
[self _rebuildPipelines];
|
[self _rebuildPipelines];
|
||||||
|
|
||||||
_needsRebuild = false;
|
_needsRebuild = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +534,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
_displacementPtexture.reset();
|
_displacementPtexture.reset();
|
||||||
_occlusionPtexture.reset();
|
_occlusionPtexture.reset();
|
||||||
_specularPtexture.reset();
|
_specularPtexture.reset();
|
||||||
|
|
||||||
_colorPtexture = [self _createPtex:_ptexColorFilename];
|
_colorPtexture = [self _createPtex:_ptexColorFilename];
|
||||||
if(_ptexDisplacementFilename) {
|
if(_ptexDisplacementFilename) {
|
||||||
_displacementPtexture = [self _createPtex:_ptexDisplacementFilename];
|
_displacementPtexture = [self _createPtex:_ptexDisplacementFilename];
|
||||||
@ -542,7 +542,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
}
|
}
|
||||||
|
|
||||||
-(std::unique_ptr<MTLPtexMipmapTexture>)_createPtex:(NSString*) filename {
|
-(std::unique_ptr<MTLPtexMipmapTexture>)_createPtex:(NSString*) filename {
|
||||||
|
|
||||||
Ptex::String ptexError;
|
Ptex::String ptexError;
|
||||||
printf("Loading ptex : %s\n", filename.UTF8String);
|
printf("Loading ptex : %s\n", filename.UTF8String);
|
||||||
#if TARGET_OS_EMBEDDED
|
#if TARGET_OS_EMBEDDED
|
||||||
@ -550,44 +550,44 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
#else
|
#else
|
||||||
const auto path = filename;
|
const auto path = filename;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define USE_PTEX_CACHE 1
|
#define USE_PTEX_CACHE 1
|
||||||
#define PTEX_CACHE_SIZE (512*1024*1024)
|
#define PTEX_CACHE_SIZE (512*1024*1024)
|
||||||
|
|
||||||
#if USE_PTEX_CACHE
|
#if USE_PTEX_CACHE
|
||||||
PtexCache *cache = PtexCache::create(1, PTEX_CACHE_SIZE);
|
PtexCache *cache = PtexCache::create(1, PTEX_CACHE_SIZE);
|
||||||
PtexTexture *ptex = cache->get(path.UTF8String, ptexError);
|
PtexTexture *ptex = cache->get(path.UTF8String, ptexError);
|
||||||
#else
|
#else
|
||||||
PtexTexture *ptex = PtexTexture::open(path.UTF8String, ptexError, true);
|
PtexTexture *ptex = PtexTexture::open(path.UTF8String, ptexError, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ptex == NULL) {
|
if (ptex == NULL) {
|
||||||
printf("Error in reading %s\n", filename.UTF8String);
|
printf("Error in reading %s\n", filename.UTF8String);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MTLPtexMipmapTexture> osdPtex(MTLPtexMipmapTexture::Create(&_context, ptex));
|
std::unique_ptr<MTLPtexMipmapTexture> osdPtex(MTLPtexMipmapTexture::Create(&_context, ptex));
|
||||||
|
|
||||||
ptex->release();
|
ptex->release();
|
||||||
|
|
||||||
#if USE_PTEX_CACHE
|
#if USE_PTEX_CACHE
|
||||||
cache->release();
|
cache->release();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return osdPtex;
|
return osdPtex;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(std::unique_ptr<Shape>)_shapeFromPtex:(Ptex::PtexTexture*) tex {
|
-(std::unique_ptr<Shape>)_shapeFromPtex:(Ptex::PtexTexture*) tex {
|
||||||
const auto meta = tex->getMetaData();
|
const auto meta = tex->getMetaData();
|
||||||
|
|
||||||
if (meta->numKeys() < 3) {
|
if (meta->numKeys() < 3) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
float const * vp;
|
float const * vp;
|
||||||
int const *vi, *vc;
|
int const *vi, *vc;
|
||||||
int nvp, nvi, nvc;
|
int nvp, nvi, nvc;
|
||||||
|
|
||||||
meta->getValue("PtexFaceVertCounts", vc, nvc);
|
meta->getValue("PtexFaceVertCounts", vc, nvc);
|
||||||
if (nvc == 0) {
|
if (nvc == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -600,26 +600,26 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
if (nvi == 0) {
|
if (nvi == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Shape> shape(new Shape);
|
std::unique_ptr<Shape> shape(new Shape);
|
||||||
|
|
||||||
shape->scheme = kCatmark;
|
shape->scheme = kCatmark;
|
||||||
|
|
||||||
shape->verts.resize(nvp);
|
shape->verts.resize(nvp);
|
||||||
for (int i=0; i<nvp; ++i) {
|
for (int i=0; i<nvp; ++i) {
|
||||||
shape->verts[i] = vp[i];
|
shape->verts[i] = vp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
shape->nvertsPerFace.resize(nvc);
|
shape->nvertsPerFace.resize(nvc);
|
||||||
for (int i=0; i<nvc; ++i) {
|
for (int i=0; i<nvc; ++i) {
|
||||||
shape->nvertsPerFace[i] = vc[i];
|
shape->nvertsPerFace[i] = vc[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
shape->faceverts.resize(nvi);
|
shape->faceverts.resize(nvi);
|
||||||
for (int i=0; i<nvi; ++i) {
|
for (int i=0; i<nvi; ++i) {
|
||||||
shape->faceverts[i] = vi[i];
|
shape->faceverts[i] = vi[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute model bounding
|
// compute model bounding
|
||||||
float min[3] = {vp[0], vp[1], vp[2]};
|
float min[3] = {vp[0], vp[1], vp[2]};
|
||||||
float max[3] = {vp[0], vp[1], vp[2]};
|
float max[3] = {vp[0], vp[1], vp[2]};
|
||||||
@ -630,23 +630,23 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
max[j] = std::max(max[j], v);
|
max[j] = std::max(max[j], v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
_meshCenter[j] = (min[j] + max[j]) * 0.5f;
|
_meshCenter[j] = (min[j] + max[j]) * 0.5f;
|
||||||
_meshSize += (max[j]-min[j])*(max[j]-min[j]);
|
_meshSize += (max[j]-min[j])*(max[j]-min[j]);
|
||||||
}
|
}
|
||||||
_meshSize = sqrtf(_meshSize);
|
_meshSize = sqrtf(_meshSize);
|
||||||
|
|
||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)_rebuildModel {
|
-(void)_rebuildModel {
|
||||||
|
|
||||||
using namespace OpenSubdiv;
|
using namespace OpenSubdiv;
|
||||||
using namespace Sdc;
|
using namespace Sdc;
|
||||||
using namespace Osd;
|
using namespace Osd;
|
||||||
using namespace Far;
|
using namespace Far;
|
||||||
|
|
||||||
Ptex::String ptexError;
|
Ptex::String ptexError;
|
||||||
#if TARGET_OS_EMBEDDED
|
#if TARGET_OS_EMBEDDED
|
||||||
const auto ptexColor = PtexTexture::open([[NSBundle mainBundle] pathForResource:_ptexColorFilename ofType:nil].UTF8String, ptexError);
|
const auto ptexColor = PtexTexture::open([[NSBundle mainBundle] pathForResource:_ptexColorFilename ofType:nil].UTF8String, ptexError);
|
||||||
@ -654,31 +654,31 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
const auto ptexColor = PtexTexture::open(_ptexColorFilename.UTF8String, ptexError);
|
const auto ptexColor = PtexTexture::open(_ptexColorFilename.UTF8String, ptexError);
|
||||||
#endif
|
#endif
|
||||||
_shape = [self _shapeFromPtex:ptexColor];
|
_shape = [self _shapeFromPtex:ptexColor];
|
||||||
|
|
||||||
// create Far mesh (topology)
|
// create Far mesh (topology)
|
||||||
Sdc::SchemeType sdctype = GetSdcType(*_shape);
|
Sdc::SchemeType sdctype = GetSdcType(*_shape);
|
||||||
Sdc::Options sdcoptions = GetSdcOptions(*_shape);
|
Sdc::Options sdcoptions = GetSdcOptions(*_shape);
|
||||||
|
|
||||||
std::unique_ptr<OpenSubdiv::Far::TopologyRefiner> refiner;
|
std::unique_ptr<OpenSubdiv::Far::TopologyRefiner> refiner;
|
||||||
refiner.reset(
|
refiner.reset(
|
||||||
Far::TopologyRefinerFactory<Shape>::Create(*_shape, Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions)));
|
Far::TopologyRefinerFactory<Shape>::Create(*_shape, Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions)));
|
||||||
|
|
||||||
// save coarse topology (used for coarse mesh drawing)
|
// save coarse topology (used for coarse mesh drawing)
|
||||||
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||||
|
|
||||||
// Adaptive refinement currently supported only for catmull-clark scheme
|
// Adaptive refinement currently supported only for catmull-clark scheme
|
||||||
_doAdaptive = (_useAdaptive);
|
_doAdaptive = (_useAdaptive);
|
||||||
bool doSingleCreasePatch = (_useSingleCrease);
|
bool doSingleCreasePatch = (_useSingleCrease);
|
||||||
|
|
||||||
Osd::MeshBitset bits;
|
Osd::MeshBitset bits;
|
||||||
bits.set(Osd::MeshAdaptive, _doAdaptive);
|
bits.set(Osd::MeshAdaptive, _doAdaptive);
|
||||||
bits.set(Osd::MeshUseSingleCreasePatch, doSingleCreasePatch);
|
bits.set(Osd::MeshUseSingleCreasePatch, doSingleCreasePatch);
|
||||||
bits.set(Osd::MeshEndCapGregoryBasis, true);
|
bits.set(Osd::MeshEndCapGregoryBasis, true);
|
||||||
|
|
||||||
int level = _refinementLevel;
|
int level = _refinementLevel;
|
||||||
_numVertexElements = 3;
|
_numVertexElements = 3;
|
||||||
int numVaryingElements = 0;
|
int numVaryingElements = 0;
|
||||||
|
|
||||||
if(_kernelType == kCPU)
|
if(_kernelType == kCPU)
|
||||||
{
|
{
|
||||||
_mesh.reset(new CPUMeshType(
|
_mesh.reset(new CPUMeshType(
|
||||||
@ -695,11 +695,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
numVaryingElements,
|
numVaryingElements,
|
||||||
level, bits, nullptr, &_context));
|
level, bits, nullptr, &_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MTLRenderPipelineDescriptor* desc = [MTLRenderPipelineDescriptor new];
|
MTLRenderPipelineDescriptor* desc = [MTLRenderPipelineDescriptor new];
|
||||||
[_delegate setupRenderPipelineState:desc for:self];
|
[_delegate setupRenderPipelineState:desc for:self];
|
||||||
|
|
||||||
const auto vertexDescriptor = desc.vertexDescriptor;
|
const auto vertexDescriptor = desc.vertexDescriptor;
|
||||||
vertexDescriptor.layouts[0].stride = sizeof(float) * _numVertexElements;
|
vertexDescriptor.layouts[0].stride = sizeof(float) * _numVertexElements;
|
||||||
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
||||||
@ -707,19 +707,19 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3;
|
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3;
|
||||||
vertexDescriptor.attributes[0].offset = 0;
|
vertexDescriptor.attributes[0].offset = 0;
|
||||||
vertexDescriptor.attributes[0].bufferIndex = 0;
|
vertexDescriptor.attributes[0].bufferIndex = 0;
|
||||||
|
|
||||||
_numVertices = refBaseLevel.GetNumVertices();
|
_numVertices = refBaseLevel.GetNumVertices();
|
||||||
|
|
||||||
_vertexData.resize(refBaseLevel.GetNumVertices() * _numVertexElements);
|
_vertexData.resize(refBaseLevel.GetNumVertices() * _numVertexElements);
|
||||||
_meshCenter = simd::float3{0,0,0};
|
_meshCenter = simd::float3{0,0,0};
|
||||||
|
|
||||||
|
|
||||||
for(int vertexIdx = 0; vertexIdx < refBaseLevel.GetNumVertices(); vertexIdx++)
|
for(int vertexIdx = 0; vertexIdx < refBaseLevel.GetNumVertices(); vertexIdx++)
|
||||||
{
|
{
|
||||||
_vertexData[vertexIdx * _numVertexElements + 0] = _shape->verts[vertexIdx * 3 + 0];
|
_vertexData[vertexIdx * _numVertexElements + 0] = _shape->verts[vertexIdx * 3 + 0];
|
||||||
_vertexData[vertexIdx * _numVertexElements + 1] = _shape->verts[vertexIdx * 3 + 1];
|
_vertexData[vertexIdx * _numVertexElements + 1] = _shape->verts[vertexIdx * 3 + 1];
|
||||||
_vertexData[vertexIdx * _numVertexElements + 2] = _shape->verts[vertexIdx * 3 + 2];
|
_vertexData[vertexIdx * _numVertexElements + 2] = _shape->verts[vertexIdx * 3 + 2];
|
||||||
|
|
||||||
_meshCenter[0] += _vertexData[vertexIdx * _numVertexElements + 0];
|
_meshCenter[0] += _vertexData[vertexIdx * _numVertexElements + 0];
|
||||||
_meshCenter[1] += _vertexData[vertexIdx * _numVertexElements + 1];
|
_meshCenter[1] += _vertexData[vertexIdx * _numVertexElements + 1];
|
||||||
_meshCenter[2] += _vertexData[vertexIdx * _numVertexElements + 2];
|
_meshCenter[2] += _vertexData[vertexIdx * _numVertexElements + 2];
|
||||||
@ -734,11 +734,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
-(void)_updateState {
|
-(void)_updateState {
|
||||||
[self _updateCamera];
|
[self _updateCamera];
|
||||||
auto pData = _frameConstantsBuffer.data();
|
auto pData = _frameConstantsBuffer.data();
|
||||||
|
|
||||||
pData->TessLevel = _tessellationLevel;
|
pData->TessLevel = _tessellationLevel;
|
||||||
pData->displacementConfig.mipmapBias = _mipmapBias;
|
pData->displacementConfig.mipmapBias = _mipmapBias;
|
||||||
pData->displacementConfig.displacementScale = _displacementScale;
|
pData->displacementConfig.displacementScale = _displacementScale;
|
||||||
|
|
||||||
{
|
{
|
||||||
for(auto& patch : _mesh->GetPatchTable()->GetPatchArrays())
|
for(auto& patch : _mesh->GetPatchTable()->GetPatchArrays())
|
||||||
{
|
{
|
||||||
@ -751,7 +751,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
drawCommand[patch.desc.GetType() - Far::PatchDescriptor::REGULAR].patchStart = 0;
|
drawCommand[patch.desc.GetType() - Far::PatchDescriptor::REGULAR].patchStart = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
_drawIndirectCommandsBuffer.markModified();
|
_drawIndirectCommandsBuffer.markModified();
|
||||||
@ -765,19 +765,19 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
auto totalPatches = 0;
|
auto totalPatches = 0;
|
||||||
auto totalVertices = 0;
|
auto totalVertices = 0;
|
||||||
auto totalPatchDataSize = 0;
|
auto totalPatchDataSize = 0;
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
_drawIndirectCommandsBuffer.alloc(_context.device, 4, @"draw patch indirect commands");
|
_drawIndirectCommandsBuffer.alloc(_context.device, 4, @"draw patch indirect commands");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
for(auto& patch : patchArray)
|
for(auto& patch : patchArray)
|
||||||
{
|
{
|
||||||
auto patchDescriptor = patch.GetDescriptor();
|
auto patchDescriptor = patch.GetDescriptor();
|
||||||
|
|
||||||
switch(patch.desc.GetType())
|
switch(patch.desc.GetType())
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::REGULAR: {
|
case Far::PatchDescriptor::REGULAR: {
|
||||||
@ -790,7 +790,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
float elementFloats = 3;
|
float elementFloats = 3;
|
||||||
if(_useSingleCrease)
|
if(_useSingleCrease)
|
||||||
elementFloats += 6;
|
elementFloats += 6;
|
||||||
|
|
||||||
totalPatchDataSize += elementFloats * sizeof(float) * patch.GetNumPatches() * patch.desc.GetNumControlVertices();
|
totalPatchDataSize += elementFloats * sizeof(float) * patch.GetNumPatches() * patch.desc.GetNumControlVertices();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -824,15 +824,15 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
// totalPatchDataSize += sizeof(float) * 4 * 2 * patch.GetNumPatches() * patch.desc.GetNumControlVertices();
|
// totalPatchDataSize += sizeof(float) * 4 * 2 * patch.GetNumPatches() * patch.desc.GetNumControlVertices();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalPatches += patch.GetNumPatches();
|
totalPatches += patch.GetNumPatches();
|
||||||
totalVertices += patch.GetDescriptor().GetNumControlVertices() * patch.GetNumPatches();
|
totalVertices += patch.GetDescriptor().GetNumControlVertices() * patch.GetNumPatches();
|
||||||
}
|
}
|
||||||
|
|
||||||
_perPatchDataBuffer.alloc(_context.device, totalPatchDataSize, @"per patch data", MTLResourceStorageModePrivate);
|
_perPatchDataBuffer.alloc(_context.device, totalPatchDataSize, @"per patch data", MTLResourceStorageModePrivate);
|
||||||
_hsDataBuffer.alloc(_context.device, 20 * sizeof(float) * totalPatches, @"hs constant data", MTLResourceStorageModePrivate);
|
_hsDataBuffer.alloc(_context.device, 20 * sizeof(float) * totalPatches, @"hs constant data", MTLResourceStorageModePrivate);
|
||||||
_tessFactorsBuffer.alloc(_context.device, totalPatches, @"tessellation factors buffer", MTLResourceStorageModePrivate);
|
_tessFactorsBuffer.alloc(_context.device, totalPatches, @"tessellation factors buffer", MTLResourceStorageModePrivate);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,7 +841,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
_computePipelines[i] = nil;
|
_computePipelines[i] = nil;
|
||||||
_renderPipelines[i] = nil;
|
_renderPipelines[i] = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
Osd::MTLPatchShaderSource shaderSource;
|
Osd::MTLPatchShaderSource shaderSource;
|
||||||
auto& patchArrays = _mesh->GetPatchTable()->GetPatchArrays();
|
auto& patchArrays = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
for(auto& patch : patchArrays)
|
for(auto& patch : patchArrays)
|
||||||
@ -851,11 +851,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
auto controlPointsPerThread = [&]() {
|
auto controlPointsPerThread = [&]() {
|
||||||
return std::max<int>(1, usefulControlPoints / threadsPerThreadgroup);
|
return std::max<int>(1, usefulControlPoints / threadsPerThreadgroup);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto type = patch.GetDescriptor().GetType();
|
auto type = patch.GetDescriptor().GetType();
|
||||||
auto compileOptions = [[MTLCompileOptions alloc] init];
|
auto compileOptions = [[MTLCompileOptions alloc] init];
|
||||||
compileOptions.fastMathEnabled = YES;
|
compileOptions.fastMathEnabled = YES;
|
||||||
|
|
||||||
auto preprocessor = [[NSMutableDictionary alloc] init];
|
auto preprocessor = [[NSMutableDictionary alloc] init];
|
||||||
#define DEFINE(x, y) preprocessor[@(#x)] = @(y)
|
#define DEFINE(x, y) preprocessor[@(#x)] = @(y)
|
||||||
bool allowsSingleCrease = true;
|
bool allowsSingleCrease = true;
|
||||||
@ -888,11 +888,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
usefulControlPoints = 4;
|
usefulControlPoints = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TARGET_OS_EMBEDDED
|
#if TARGET_OS_EMBEDDED
|
||||||
shaderBuilder << "#define OSD_UV_CORRECTION if(t > 0.5){ ti += 0.01f; } else { ti += 0.01f; }\n";
|
shaderBuilder << "#define OSD_UV_CORRECTION if(t > 0.5){ ti += 0.01f; } else { ti += 0.01f; }\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Need to define the input vertex struct so that it's available everywhere.
|
//Need to define the input vertex struct so that it's available everywhere.
|
||||||
shaderBuilder << R"(
|
shaderBuilder << R"(
|
||||||
#include <metal_stdlib>
|
#include <metal_stdlib>
|
||||||
@ -900,14 +900,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
metal::packed_float3 position;
|
metal::packed_float3 position;
|
||||||
};
|
};
|
||||||
)";
|
)";
|
||||||
|
|
||||||
auto fvarType = Far::PatchDescriptor::REGULAR;
|
auto fvarType = Far::PatchDescriptor::REGULAR;
|
||||||
shaderBuilder << shaderSource.GetHullShaderSource(type, fvarType);
|
shaderBuilder << shaderSource.GetHullShaderSource(type, fvarType);
|
||||||
shaderBuilder << MTLPtexMipmapTexture::GetShaderSource();
|
shaderBuilder << MTLPtexMipmapTexture::GetShaderSource();
|
||||||
shaderBuilder << _osdShaderSource.UTF8String;
|
shaderBuilder << _osdShaderSource.UTF8String;
|
||||||
|
|
||||||
const auto str = shaderBuilder.str();
|
const auto str = shaderBuilder.str();
|
||||||
|
|
||||||
DEFINE(CONFIG_BUFFER_INDEX,CONFIG_BUFFER_INDEX);
|
DEFINE(CONFIG_BUFFER_INDEX,CONFIG_BUFFER_INDEX);
|
||||||
DEFINE(VERTEX_BUFFER_INDEX,VERTEX_BUFFER_INDEX);
|
DEFINE(VERTEX_BUFFER_INDEX,VERTEX_BUFFER_INDEX);
|
||||||
DEFINE(PATCH_INDICES_BUFFER_INDEX,PATCH_INDICES_BUFFER_INDEX);
|
DEFINE(PATCH_INDICES_BUFFER_INDEX,PATCH_INDICES_BUFFER_INDEX);
|
||||||
@ -933,7 +933,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
DEFINE(SPECULAR_BUFFER_INDEX,SPECULAR_BUFFER_INDEX);
|
DEFINE(SPECULAR_BUFFER_INDEX,SPECULAR_BUFFER_INDEX);
|
||||||
DEFINE(OSD_KERNELLIMIT_BUFFER_INDEX,OSD_KERNELLIMIT_BUFFER_INDEX);
|
DEFINE(OSD_KERNELLIMIT_BUFFER_INDEX,OSD_KERNELLIMIT_BUFFER_INDEX);
|
||||||
DEFINE(OSD_PATCH_ENABLE_SINGLE_CREASE, allowsSingleCrease && _useSingleCrease);
|
DEFINE(OSD_PATCH_ENABLE_SINGLE_CREASE, allowsSingleCrease && _useSingleCrease);
|
||||||
|
|
||||||
DEFINE(COLOR_NORMAL, _colorMode == kColorModeNormal);
|
DEFINE(COLOR_NORMAL, _colorMode == kColorModeNormal);
|
||||||
DEFINE(COLOR_PATCHTYPE, _colorMode == kColorModePatchType);
|
DEFINE(COLOR_PATCHTYPE, _colorMode == kColorModePatchType);
|
||||||
DEFINE(COLOR_PATCHCOORD, _colorMode == kColorModePatchCoord);
|
DEFINE(COLOR_PATCHCOORD, _colorMode == kColorModePatchCoord);
|
||||||
@ -946,11 +946,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
DEFINE(NORMAL_HW_SCREENSPACE, _normalMode == kNormalModeHWScreenspace);
|
DEFINE(NORMAL_HW_SCREENSPACE, _normalMode == kNormalModeHWScreenspace);
|
||||||
DEFINE(NORMAL_BIQUADRATIC_WG, _normalMode == kNormalModeBiQuadraticWG);
|
DEFINE(NORMAL_BIQUADRATIC_WG, _normalMode == kNormalModeBiQuadraticWG);
|
||||||
DEFINE(NORMAL_BIQUADRATIC, _normalMode == kNormalModeBiQuadratic);
|
DEFINE(NORMAL_BIQUADRATIC, _normalMode == kNormalModeBiQuadratic);
|
||||||
|
|
||||||
DEFINE(DISPLACEMENT_BILINEAR, _displacementMode == kDisplacementModeBilinear);
|
DEFINE(DISPLACEMENT_BILINEAR, _displacementMode == kDisplacementModeBilinear);
|
||||||
DEFINE(DISPLACEMENT_HW_BILINEAR, _displacementMode == kDisplacementModeHWBilinear);
|
DEFINE(DISPLACEMENT_HW_BILINEAR, _displacementMode == kDisplacementModeHWBilinear);
|
||||||
DEFINE(DISPLACEMENT_BIQUADRATIC, _displacementMode == kDisplacementModeBiQuadratic);
|
DEFINE(DISPLACEMENT_BIQUADRATIC, _displacementMode == kDisplacementModeBiQuadratic);
|
||||||
|
|
||||||
DEFINE(OSD_COMPUTE_NORMAL_DERIVATIVES, _normalMode == kNormalModeBiQuadraticWG);
|
DEFINE(OSD_COMPUTE_NORMAL_DERIVATIVES, _normalMode == kNormalModeBiQuadraticWG);
|
||||||
|
|
||||||
auto partitionMode = _useScreenspaceTessellation ? MTLTessellationPartitionModeFractionalOdd : MTLTessellationPartitionModePow2;
|
auto partitionMode = _useScreenspaceTessellation ? MTLTessellationPartitionModeFractionalOdd : MTLTessellationPartitionModePow2;
|
||||||
@ -978,7 +978,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
DEFINE(OSD_ENABLE_PATCH_CULL, _usePatchClipCulling);
|
DEFINE(OSD_ENABLE_PATCH_CULL, _usePatchClipCulling);
|
||||||
|
|
||||||
compileOptions.preprocessorMacros = preprocessor;
|
compileOptions.preprocessorMacros = preprocessor;
|
||||||
|
|
||||||
NSError* err = nil;
|
NSError* err = nil;
|
||||||
auto librarySource = [NSString stringWithUTF8String:str.data()];
|
auto librarySource = [NSString stringWithUTF8String:str.data()];
|
||||||
auto library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:&err];
|
auto library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:&err];
|
||||||
@ -991,67 +991,67 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
assert(vertexFunction && fragmentFunction);
|
assert(vertexFunction && fragmentFunction);
|
||||||
if(vertexFunction && fragmentFunction)
|
if(vertexFunction && fragmentFunction)
|
||||||
{
|
{
|
||||||
|
|
||||||
MTLRenderPipelineDescriptor* pipelineDesc = [[MTLRenderPipelineDescriptor alloc] init];
|
MTLRenderPipelineDescriptor* pipelineDesc = [[MTLRenderPipelineDescriptor alloc] init];
|
||||||
pipelineDesc.tessellationFactorFormat = MTLTessellationFactorFormatHalf;
|
pipelineDesc.tessellationFactorFormat = MTLTessellationFactorFormatHalf;
|
||||||
pipelineDesc.tessellationPartitionMode = partitionMode;
|
pipelineDesc.tessellationPartitionMode = partitionMode;
|
||||||
pipelineDesc.tessellationFactorScaleEnabled = false;
|
pipelineDesc.tessellationFactorScaleEnabled = false;
|
||||||
pipelineDesc.tessellationFactorStepFunction = MTLTessellationFactorStepFunctionPerPatch;
|
pipelineDesc.tessellationFactorStepFunction = MTLTessellationFactorStepFunctionPerPatch;
|
||||||
|
|
||||||
if(type == Far::PatchDescriptor::GREGORY_BASIS)
|
if(type == Far::PatchDescriptor::GREGORY_BASIS)
|
||||||
pipelineDesc.tessellationControlPointIndexType = MTLTessellationControlPointIndexTypeUInt32;
|
pipelineDesc.tessellationControlPointIndexType = MTLTessellationControlPointIndexTypeUInt32;
|
||||||
|
|
||||||
[_delegate setupRenderPipelineState:pipelineDesc for:self];
|
[_delegate setupRenderPipelineState:pipelineDesc for:self];
|
||||||
|
|
||||||
pipelineDesc.fragmentFunction = fragmentFunction;
|
pipelineDesc.fragmentFunction = fragmentFunction;
|
||||||
pipelineDesc.vertexFunction = vertexFunction;
|
pipelineDesc.vertexFunction = vertexFunction;
|
||||||
|
|
||||||
auto vertexDesc = pipelineDesc.vertexDescriptor;
|
auto vertexDesc = pipelineDesc.vertexDescriptor;
|
||||||
[vertexDesc reset];
|
[vertexDesc reset];
|
||||||
|
|
||||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
||||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stride = sizeof(int) * 3;
|
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stride = sizeof(int) * 3;
|
||||||
|
|
||||||
|
|
||||||
vertexDesc.attributes[10].bufferIndex = OSD_PATCHPARAM_BUFFER_INDEX;
|
vertexDesc.attributes[10].bufferIndex = OSD_PATCHPARAM_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[10].format = MTLVertexFormatInt3;
|
vertexDesc.attributes[10].format = MTLVertexFormatInt3;
|
||||||
vertexDesc.attributes[10].offset = 0;
|
vertexDesc.attributes[10].offset = 0;
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::REGULAR:
|
case Far::PatchDescriptor::REGULAR:
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride = sizeof(float) * 3;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride = sizeof(float) * 3;
|
||||||
|
|
||||||
vertexDesc.attributes[0].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
vertexDesc.attributes[0].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
||||||
vertexDesc.attributes[0].offset = 0;
|
vertexDesc.attributes[0].offset = 0;
|
||||||
|
|
||||||
if(_useSingleCrease)
|
if(_useSingleCrease)
|
||||||
{
|
{
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride += sizeof(float) * 6;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride += sizeof(float) * 6;
|
||||||
|
|
||||||
vertexDesc.attributes[1].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
vertexDesc.attributes[1].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[1].format = MTLVertexFormatFloat3;
|
vertexDesc.attributes[1].format = MTLVertexFormatFloat3;
|
||||||
vertexDesc.attributes[1].offset = sizeof(float) * 3;
|
vertexDesc.attributes[1].offset = sizeof(float) * 3;
|
||||||
|
|
||||||
vertexDesc.attributes[2].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
vertexDesc.attributes[2].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[2].format = MTLVertexFormatFloat3;
|
vertexDesc.attributes[2].format = MTLVertexFormatFloat3;
|
||||||
vertexDesc.attributes[2].offset = sizeof(float) * 6;
|
vertexDesc.attributes[2].offset = sizeof(float) * 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_useScreenspaceTessellation)
|
if(_useScreenspaceTessellation)
|
||||||
{
|
{
|
||||||
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
||||||
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stride = sizeof(float) * 8;
|
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stride = sizeof(float) * 8;
|
||||||
|
|
||||||
vertexDesc.attributes[5].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
vertexDesc.attributes[5].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[5].format = MTLVertexFormatFloat4;
|
vertexDesc.attributes[5].format = MTLVertexFormatFloat4;
|
||||||
vertexDesc.attributes[5].offset = 0;
|
vertexDesc.attributes[5].offset = 0;
|
||||||
|
|
||||||
vertexDesc.attributes[6].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
vertexDesc.attributes[6].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[6].format = MTLVertexFormatFloat4;
|
vertexDesc.attributes[6].format = MTLVertexFormatFloat4;
|
||||||
vertexDesc.attributes[6].offset = sizeof(float) * 4;
|
vertexDesc.attributes[6].offset = sizeof(float) * 4;
|
||||||
@ -1059,11 +1059,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
break;
|
break;
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
||||||
case Far::PatchDescriptor::GREGORY:
|
case Far::PatchDescriptor::GREGORY:
|
||||||
|
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stride = sizeof(float) * 3 * 5;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stride = sizeof(float) * 3 * 5;
|
||||||
|
|
||||||
for(int i = 0; i < 5; i++)
|
for(int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
vertexDesc.attributes[i].bufferIndex = OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX;
|
vertexDesc.attributes[i].bufferIndex = OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX;
|
||||||
@ -1075,7 +1075,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
||||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stride = sizeof(float) * 3;
|
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stride = sizeof(float) * 3;
|
||||||
|
|
||||||
vertexDesc.attributes[0].bufferIndex = VERTEX_BUFFER_INDEX;
|
vertexDesc.attributes[0].bufferIndex = VERTEX_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
||||||
vertexDesc.attributes[0].offset = 0;
|
vertexDesc.attributes[0].offset = 0;
|
||||||
@ -1085,15 +1085,15 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[vertexDesc reset];
|
[vertexDesc reset];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_renderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
|
_renderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
|
||||||
if(!_renderPipelines[type] && err)
|
if(!_renderPipelines[type] && err)
|
||||||
{
|
{
|
||||||
NSLog(@"%s", [[err localizedDescription] UTF8String]);
|
NSLog(@"%s", [[err localizedDescription] UTF8String]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto computeFunction = [library newFunctionWithName:@"compute_main"];
|
auto computeFunction = [library newFunctionWithName:@"compute_main"];
|
||||||
if(computeFunction)
|
if(computeFunction)
|
||||||
{
|
{
|
||||||
@ -1104,51 +1104,51 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
|
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
|
||||||
#endif
|
#endif
|
||||||
computeDesc.computeFunction = computeFunction;
|
computeDesc.computeFunction = computeFunction;
|
||||||
|
|
||||||
|
|
||||||
NSError* err;
|
NSError* err;
|
||||||
|
|
||||||
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
||||||
|
|
||||||
if(err && _computePipelines[type] == nil)
|
if(err && _computePipelines[type] == nil)
|
||||||
{
|
{
|
||||||
NSLog(@"%s", [[err description] UTF8String]);
|
NSLog(@"%s", [[err description] UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
|
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
|
||||||
{
|
{
|
||||||
preprocessor[@"THREADS_PER_THREADGROUP"] = @(_computePipelines[type].threadExecutionWidth);
|
preprocessor[@"THREADS_PER_THREADGROUP"] = @(_computePipelines[type].threadExecutionWidth);
|
||||||
preprocessor[@"CONTROL_POINTS_PER_THREAD"] = @(std::max<int>(1, usefulControlPoints / _computePipelines[type].threadExecutionWidth));
|
preprocessor[@"CONTROL_POINTS_PER_THREAD"] = @(std::max<int>(1, usefulControlPoints / _computePipelines[type].threadExecutionWidth));
|
||||||
compileOptions.preprocessorMacros = preprocessor;
|
compileOptions.preprocessorMacros = preprocessor;
|
||||||
|
|
||||||
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
|
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
|
||||||
assert(library);
|
assert(library);
|
||||||
|
|
||||||
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = true;
|
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = true;
|
||||||
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
|
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
|
||||||
|
|
||||||
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
|
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
|
||||||
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
||||||
assert(_computePipelines[type].threadExecutionWidth == threadsPerThreadgroup);
|
assert(_computePipelines[type].threadExecutionWidth == threadsPerThreadgroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init];
|
MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init];
|
||||||
depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess;
|
depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess;
|
||||||
|
|
||||||
[_delegate setupDepthStencilState:depthStencilDesc for:self];
|
[_delegate setupDepthStencilState:depthStencilDesc for:self];
|
||||||
|
|
||||||
depthStencilDesc.depthWriteEnabled = YES;
|
depthStencilDesc.depthWriteEnabled = YES;
|
||||||
_readWriteDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
_readWriteDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
||||||
|
|
||||||
depthStencilDesc.depthWriteEnabled = NO;
|
depthStencilDesc.depthWriteEnabled = NO;
|
||||||
_readOnlyDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
_readOnlyDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)_updateCamera {
|
-(void)_updateCamera {
|
||||||
auto pData = _frameConstantsBuffer.data();
|
auto pData = _frameConstantsBuffer.data();
|
||||||
|
|
||||||
identity(pData->ModelViewMatrix);
|
identity(pData->ModelViewMatrix);
|
||||||
translate(pData->ModelViewMatrix, 0, 0, -_cameraData.dollyDistance);
|
translate(pData->ModelViewMatrix, 0, 0, -_cameraData.dollyDistance);
|
||||||
rotate(pData->ModelViewMatrix, _cameraData.rotationY, 1, 0, 0);
|
rotate(pData->ModelViewMatrix, _cameraData.rotationY, 1, 0, 0);
|
||||||
@ -1156,11 +1156,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
translate(pData->ModelViewMatrix, -_meshCenter[0], -_meshCenter[2], _meshCenter[1]); // z-up model
|
translate(pData->ModelViewMatrix, -_meshCenter[0], -_meshCenter[2], _meshCenter[1]); // z-up model
|
||||||
rotate(pData->ModelViewMatrix, -90, 1, 0, 0); // z-up model
|
rotate(pData->ModelViewMatrix, -90, 1, 0, 0); // z-up model
|
||||||
inverseMatrix(pData->ModelViewInverseMatrix, pData->ModelViewMatrix);
|
inverseMatrix(pData->ModelViewInverseMatrix, pData->ModelViewMatrix);
|
||||||
|
|
||||||
identity(pData->ProjectionMatrix);
|
identity(pData->ProjectionMatrix);
|
||||||
perspective(pData->ProjectionMatrix, 45.0, _cameraData.aspectRatio, 0.01f, 500.0);
|
perspective(pData->ProjectionMatrix, 45.0, _cameraData.aspectRatio, 0.01f, 500.0);
|
||||||
multMatrix(pData->ModelViewProjectionMatrix, pData->ModelViewMatrix, pData->ProjectionMatrix);
|
multMatrix(pData->ModelViewProjectionMatrix, pData->ModelViewMatrix, pData->ProjectionMatrix);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1184,14 +1184,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
{ 0.7f, 0.7f, 0.7f, 1.0f },
|
{ 0.7f, 0.7f, 0.7f, 1.0f },
|
||||||
{ 0.8f, 0.8f, 0.8f, 1.0f },
|
{ 0.8f, 0.8f, 0.8f, 1.0f },
|
||||||
};
|
};
|
||||||
|
|
||||||
_lightsBuffer[1] = {
|
_lightsBuffer[1] = {
|
||||||
simd::normalize(simd::float4{ -0.8f, 0.4f, -1.0f, 0.0f }),
|
simd::normalize(simd::float4{ -0.8f, 0.4f, -1.0f, 0.0f }),
|
||||||
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
||||||
{ 0.5f, 0.5f, 0.5f, 1.0f },
|
{ 0.5f, 0.5f, 0.5f, 1.0f },
|
||||||
{ 0.8f, 0.8f, 0.8f, 1.0f }
|
{ 0.8f, 0.8f, 0.8f, 1.0f }
|
||||||
};
|
};
|
||||||
|
|
||||||
_lightsBuffer.markModified();
|
_lightsBuffer.markModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ struct OutputVertex {
|
|||||||
float4 positionOut [[position]];
|
float4 positionOut [[position]];
|
||||||
float3 position;
|
float3 position;
|
||||||
float3 normal;
|
float3 normal;
|
||||||
|
|
||||||
#if SHADING_TYPE == SHADING_TYPE_PATCH || SHADING_TYPE == SHADING_TYPE_PATCH_COORD || SHADING_TYPE_FACE_VARYING
|
#if SHADING_TYPE == SHADING_TYPE_PATCH || SHADING_TYPE == SHADING_TYPE_PATCH_COORD || SHADING_TYPE_FACE_VARYING
|
||||||
float3 patchColor;
|
float3 patchColor;
|
||||||
#endif
|
#endif
|
||||||
@ -53,15 +53,15 @@ struct OutputVertex {
|
|||||||
|
|
||||||
struct SolidColorVertex {
|
struct SolidColorVertex {
|
||||||
float4 positionOut [[position]];
|
float4 positionOut [[position]];
|
||||||
|
|
||||||
half4 getColor() const {
|
half4 getColor() const {
|
||||||
return unpack_unorm4x8_to_half(_color);
|
return unpack_unorm4x8_to_half(_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setColor(half4 color) {
|
void setColor(half4 color) {
|
||||||
_color = pack_half_to_unorm4x8(color);
|
_color = pack_half_to_unorm4x8(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint _color [[flat, user(color)]];
|
uint _color [[flat, user(color)]];
|
||||||
};
|
};
|
||||||
@ -69,7 +69,7 @@ private:
|
|||||||
struct PackedInputVertex {
|
struct PackedInputVertex {
|
||||||
packed_float3 position;
|
packed_float3 position;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
float3 Position;
|
float3 Position;
|
||||||
float3 ambient;
|
float3 ambient;
|
||||||
@ -79,7 +79,7 @@ struct Light {
|
|||||||
|
|
||||||
float3 lighting(float3 diffuseColor, const constant Light* lightData, float3 eyePos, float3 eyeN)
|
float3 lighting(float3 diffuseColor, const constant Light* lightData, float3 eyePos, float3 eyeN)
|
||||||
{
|
{
|
||||||
|
|
||||||
float3 color(0);
|
float3 color(0);
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
@ -87,12 +87,12 @@ float3 lighting(float3 diffuseColor, const constant Light* lightData, float3 eye
|
|||||||
const auto h = normalize(l + float3(0,0,1));
|
const auto h = normalize(l + float3(0,0,1));
|
||||||
const auto d = max(0.0, dot(eyeN, l));
|
const auto d = max(0.0, dot(eyeN, l));
|
||||||
const auto s = powr(max(0.0, dot(eyeN, h)), 500.0f);
|
const auto s = powr(max(0.0, dot(eyeN, h)), 500.0f);
|
||||||
|
|
||||||
color += lightData[i].ambient
|
color += lightData[i].ambient
|
||||||
+ d * lightData[i].diffuse * diffuseColor
|
+ d * lightData[i].diffuse * diffuseColor
|
||||||
+ s * lightData[i].specular;
|
+ s * lightData[i].specular;
|
||||||
}
|
}
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,42 +104,42 @@ const constant float4 patchColors[] = {
|
|||||||
float4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
float4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
||||||
float4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
|
float4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
|
||||||
float4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
|
float4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
|
||||||
|
|
||||||
float4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
|
float4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
|
||||||
float4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
|
float4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
|
||||||
float4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
|
float4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
|
||||||
float4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
|
float4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
|
||||||
float4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
|
float4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
|
||||||
float4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
|
float4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
|
||||||
|
|
||||||
float4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
|
float4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
|
||||||
float4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
|
float4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
|
||||||
float4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
|
float4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
|
||||||
float4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
|
float4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
|
||||||
float4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
|
float4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
|
||||||
float4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
|
float4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
|
||||||
|
|
||||||
float4(0.0f, 1.0f, 0.0f, 1.0f), // corner
|
float4(0.0f, 1.0f, 0.0f, 1.0f), // corner
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
|
||||||
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
|
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
|
||||||
|
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
|
||||||
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
@ -156,10 +156,10 @@ getAdaptivePatchColor(int3 patchParam
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int patchType = 0;
|
int patchType = 0;
|
||||||
|
|
||||||
int edgeCount = popcount(OsdGetPatchBoundaryMask(patchParam));
|
int edgeCount = popcount(OsdGetPatchBoundaryMask(patchParam));
|
||||||
if (edgeCount == 1) {
|
if (edgeCount == 1) {
|
||||||
patchType = 2; // BOUNDARY
|
patchType = 2; // BOUNDARY
|
||||||
@ -167,7 +167,7 @@ getAdaptivePatchColor(int3 patchParam
|
|||||||
if (edgeCount == 2) {
|
if (edgeCount == 2) {
|
||||||
patchType = 3; // CORNER
|
patchType = 3; // CORNER
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||||
// check this after boundary/corner since single crease patch also has edgeCount.
|
// check this after boundary/corner since single crease patch also has edgeCount.
|
||||||
if (vSegments.y > 0) {
|
if (vSegments.y > 0) {
|
||||||
@ -180,9 +180,9 @@ getAdaptivePatchColor(int3 patchParam
|
|||||||
#elif OSD_PATCH_GREGORY_BASIS
|
#elif OSD_PATCH_GREGORY_BASIS
|
||||||
patchType = 6;
|
patchType = 6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int pattern = popcount(OsdGetPatchTransitionMask(patchParam));
|
int pattern = popcount(OsdGetPatchTransitionMask(patchParam));
|
||||||
|
|
||||||
return patchColors[6*patchType + pattern];
|
return patchColors[6*patchType + pattern];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ kernel void compute_main(
|
|||||||
if(validThread)
|
if(validThread)
|
||||||
{
|
{
|
||||||
patchParam[subthreadgroup_in_threadgroup] = OsdGetPatchParam(real_threadgroup, osdBuffers.patchParamBuffer);
|
patchParam[subthreadgroup_in_threadgroup] = OsdGetPatchParam(real_threadgroup, osdBuffers.patchParamBuffer);
|
||||||
|
|
||||||
for(unsigned threadOffset = 0; threadOffset < CONTROL_POINTS_PER_THREAD; threadOffset++)
|
for(unsigned threadOffset = 0; threadOffset < CONTROL_POINTS_PER_THREAD; threadOffset++)
|
||||||
{
|
{
|
||||||
const auto vertexId = osdBuffers.indexBuffer[(thread_position_in_grid * CONTROL_POINTS_PER_THREAD + threadOffset) * IndexLookupStride];
|
const auto vertexId = osdBuffers.indexBuffer[(thread_position_in_grid * CONTROL_POINTS_PER_THREAD + threadOffset) * IndexLookupStride];
|
||||||
@ -365,7 +365,7 @@ kernel void compute_main(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// OSD Tessellation Factors
|
// OSD Tessellation Factors
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
if(validThread && real_thread_in_threadgroup == 0)
|
if(validThread && real_thread_in_threadgroup == 0)
|
||||||
{
|
{
|
||||||
@ -406,22 +406,22 @@ vertex OutputVertex vertex_main(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
OutputVertex out;
|
OutputVertex out;
|
||||||
|
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
int3 patchParam = patchInput.patchParam;
|
int3 patchParam = patchInput.patchParam;
|
||||||
#else
|
#else
|
||||||
int3 patchParam = patchInput.patchParamBuffer[patch_id];
|
int3 patchParam = patchInput.patchParamBuffer[patch_id];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int refinementLevel = OsdGetPatchRefinementLevel(patchParam);
|
int refinementLevel = OsdGetPatchRefinementLevel(patchParam);
|
||||||
float tessLevel = min(frameConsts.TessLevel, (float)OSD_MAX_TESS_LEVEL) /
|
float tessLevel = min(frameConsts.TessLevel, (float)OSD_MAX_TESS_LEVEL) /
|
||||||
exp2((float)refinementLevel - 1);
|
exp2((float)refinementLevel - 1);
|
||||||
|
|
||||||
auto patchVertex = OsdComputePatch(tessLevel, position_in_patch, patch_id, patchInput);
|
auto patchVertex = OsdComputePatch(tessLevel, position_in_patch, patch_id, patchInput);
|
||||||
|
|
||||||
out.position = (frameConsts.ModelViewMatrix * float4(patchVertex.position, 1.0f)).xyz;
|
out.position = (frameConsts.ModelViewMatrix * float4(patchVertex.position, 1.0f)).xyz;
|
||||||
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(patchVertex.position, 1.0f);
|
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(patchVertex.position, 1.0f);
|
||||||
|
|
||||||
out.normal = mul(frameConsts.ModelViewMatrix, patchVertex.normal);
|
out.normal = mul(frameConsts.ModelViewMatrix, patchVertex.normal);
|
||||||
#if SHADING_TYPE == SHADING_TYPE_PATCH
|
#if SHADING_TYPE == SHADING_TYPE_PATCH
|
||||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||||
@ -479,7 +479,7 @@ vertex OutputVertex vertex_main(
|
|||||||
|
|
||||||
out.patchColor.rg = fvarUV;
|
out.patchColor.rg = fvarUV;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -498,25 +498,25 @@ const constant unsigned BSplineControlLineIndices[] = {
|
|||||||
12, 8,
|
12, 8,
|
||||||
8, 4,
|
8, 4,
|
||||||
4, 0,
|
4, 0,
|
||||||
|
|
||||||
//Inner lines
|
//Inner lines
|
||||||
5, 6,
|
5, 6,
|
||||||
6, 10,
|
6, 10,
|
||||||
10, 9,
|
10, 9,
|
||||||
9, 5,
|
9, 5,
|
||||||
|
|
||||||
//TL edge lines
|
//TL edge lines
|
||||||
1, 5,
|
1, 5,
|
||||||
4, 5,
|
4, 5,
|
||||||
|
|
||||||
//TR edge lines
|
//TR edge lines
|
||||||
2, 6,
|
2, 6,
|
||||||
6, 7,
|
6, 7,
|
||||||
|
|
||||||
//BL edge lines
|
//BL edge lines
|
||||||
8, 9,
|
8, 9,
|
||||||
9, 13,
|
9, 13,
|
||||||
|
|
||||||
//BR edge lines
|
//BR edge lines
|
||||||
10, 14,
|
10, 14,
|
||||||
10, 11
|
10, 11
|
||||||
@ -539,7 +539,7 @@ vertex SolidColorVertex vertex_lines(
|
|||||||
|
|
||||||
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(in.P, 1.0);
|
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(in.P, 1.0);
|
||||||
out.positionOut.z -= 0.001;
|
out.positionOut.z -= 0.001;
|
||||||
|
|
||||||
if(idx > 22) {
|
if(idx > 22) {
|
||||||
out.setColor(half4(0,1,0,1));
|
out.setColor(half4(0,1,0,1));
|
||||||
}
|
}
|
||||||
@ -555,18 +555,18 @@ vertex SolidColorVertex vertex_lines(
|
|||||||
#if OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_BOUNDARY || OSD_PATCH_GREGORY
|
#if OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_BOUNDARY || OSD_PATCH_GREGORY
|
||||||
const constant uint GregoryBasisControlLineIndices[] = {
|
const constant uint GregoryBasisControlLineIndices[] = {
|
||||||
//Outer Edge
|
//Outer Edge
|
||||||
0, 2,
|
0, 2,
|
||||||
2, 16,
|
2, 16,
|
||||||
16, 15,
|
16, 15,
|
||||||
15, 17,
|
15, 17,
|
||||||
17, 11,
|
17, 11,
|
||||||
11, 10,
|
11, 10,
|
||||||
10, 12,
|
10, 12,
|
||||||
12, 6,
|
12, 6,
|
||||||
6, 5,
|
6, 5,
|
||||||
5, 7,
|
5, 7,
|
||||||
7, 1,
|
7, 1,
|
||||||
1, 0,
|
1, 0,
|
||||||
|
|
||||||
//Outside-Inside Edges
|
//Outside-Inside Edges
|
||||||
1, 3,
|
1, 3,
|
||||||
@ -581,7 +581,7 @@ const constant uint GregoryBasisControlLineIndices[] = {
|
|||||||
//Inner Edge
|
//Inner Edge
|
||||||
3, 4,
|
3, 4,
|
||||||
4, 18,
|
4, 18,
|
||||||
18, 19,
|
18, 19,
|
||||||
19, 13,
|
19, 13,
|
||||||
13, 14,
|
13, 14,
|
||||||
14, 8,
|
14, 8,
|
||||||
@ -603,7 +603,7 @@ vertex SolidColorVertex vertex_lines(
|
|||||||
{
|
{
|
||||||
const auto idx_size = sizeof(GregoryBasisControlLineIndices) / sizeof(GregoryBasisControlLineIndices[0]);
|
const auto idx_size = sizeof(GregoryBasisControlLineIndices) / sizeof(GregoryBasisControlLineIndices[0]);
|
||||||
const auto idx = vertex_id % idx_size;
|
const auto idx = vertex_id % idx_size;
|
||||||
const auto patch_id = vertex_id / idx_size;
|
const auto patch_id = vertex_id / idx_size;
|
||||||
|
|
||||||
#if OSD_PATCH_GREGORY_BASIS
|
#if OSD_PATCH_GREGORY_BASIS
|
||||||
const auto in = vertexBuffer[indicesBuffer[patch_id * VERTEX_CONTROL_POINTS_PER_PATCH + GregoryBasisControlLineIndices[idx]]];
|
const auto in = vertexBuffer[indicesBuffer[patch_id * VERTEX_CONTROL_POINTS_PER_PATCH + GregoryBasisControlLineIndices[idx]]];
|
||||||
@ -666,12 +666,12 @@ vertex OutputVertex vertex_main(
|
|||||||
|
|
||||||
float3 normal = normalize(cross(p2 - p1, p0 - p1));
|
float3 normal = normalize(cross(p2 - p1, p0 - p1));
|
||||||
|
|
||||||
|
|
||||||
OutputVertex out;
|
OutputVertex out;
|
||||||
out.position = (frameConsts.ModelViewMatrix * float4(position, 1.0)).xyz;
|
out.position = (frameConsts.ModelViewMatrix * float4(position, 1.0)).xyz;
|
||||||
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(position, 1.0);
|
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(position, 1.0);
|
||||||
out.normal = (frameConsts.ModelViewMatrix * float4(normal, 0.0)).xyz;
|
out.normal = (frameConsts.ModelViewMatrix * float4(normal, 0.0)).xyz;
|
||||||
|
|
||||||
#if SHADING_TYPE == SHADING_TYPE_PATCH || SHADING_TYPE == SHADING_TYPE_PATCH_COORD
|
#if SHADING_TYPE == SHADING_TYPE_PATCH || SHADING_TYPE == SHADING_TYPE_PATCH_COORD
|
||||||
out.patchColor = out.normal;
|
out.patchColor = out.normal;
|
||||||
#elif SHADING_TYPE == SHADING_TYPE_FACE_VARYING
|
#elif SHADING_TYPE == SHADING_TYPE_FACE_VARYING
|
||||||
@ -679,7 +679,7 @@ vertex OutputVertex vertex_main(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex SolidColorVertex vertex_lines(
|
vertex SolidColorVertex vertex_lines(
|
||||||
device unsigned* indicesBuffer [[buffer(INDICES_BUFFER_INDEX)]],
|
device unsigned* indicesBuffer [[buffer(INDICES_BUFFER_INDEX)]],
|
||||||
@ -702,9 +702,9 @@ vertex SolidColorVertex vertex_lines(
|
|||||||
|
|
||||||
SolidColorVertex out;
|
SolidColorVertex out;
|
||||||
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(position, 1.0);
|
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(position, 1.0);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fragment half4 fragment_solidcolor(SolidColorVertex in [[stage_in]])
|
fragment half4 fragment_solidcolor(SolidColorVertex in [[stage_in]])
|
||||||
@ -719,7 +719,7 @@ fragment float4 fragment_main(OutputVertex in [[stage_in]],
|
|||||||
const constant float4& shade [[buffer(2)]])
|
const constant float4& shade [[buffer(2)]])
|
||||||
{
|
{
|
||||||
float4 color;
|
float4 color;
|
||||||
|
|
||||||
#if SHADING_TYPE == SHADING_TYPE_MATERIAL
|
#if SHADING_TYPE == SHADING_TYPE_MATERIAL
|
||||||
const float3 diffuseColor = float3(0.4f, 0.4f, 0.8f);
|
const float3 diffuseColor = float3(0.4f, 0.4f, 0.8f);
|
||||||
#elif SHADING_TYPE == SHADING_TYPE_PATCH
|
#elif SHADING_TYPE == SHADING_TYPE_PATCH
|
||||||
|
@ -134,18 +134,18 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
@implementation OSDRenderer {
|
@implementation OSDRenderer {
|
||||||
|
|
||||||
MTLRingBuffer<Light, 1> _lightsBuffer;
|
MTLRingBuffer<Light, 1> _lightsBuffer;
|
||||||
|
|
||||||
PerFrameBuffer<PerFrameConstants> _frameConstantsBuffer;
|
PerFrameBuffer<PerFrameConstants> _frameConstantsBuffer;
|
||||||
PerFrameBuffer<MTLQuadTessellationFactorsHalf> _tessFactorsBuffer;
|
PerFrameBuffer<MTLQuadTessellationFactorsHalf> _tessFactorsBuffer;
|
||||||
PerFrameBuffer<unsigned> _patchIndexBuffers[4];
|
PerFrameBuffer<unsigned> _patchIndexBuffers[4];
|
||||||
PerFrameBuffer<uint8_t> _perPatchDataBuffer;
|
PerFrameBuffer<uint8_t> _perPatchDataBuffer;
|
||||||
PerFrameBuffer<uint8_t> _hsDataBuffer;
|
PerFrameBuffer<uint8_t> _hsDataBuffer;
|
||||||
PerFrameBuffer<MTLDrawPatchIndirectArguments> _drawIndirectCommandsBuffer;
|
PerFrameBuffer<MTLDrawPatchIndirectArguments> _drawIndirectCommandsBuffer;
|
||||||
|
|
||||||
unsigned _tessFactorOffsets[4];
|
unsigned _tessFactorOffsets[4];
|
||||||
unsigned _perPatchDataOffsets[4];
|
unsigned _perPatchDataOffsets[4];
|
||||||
unsigned _threadgroupSizes[10];
|
unsigned _threadgroupSizes[10];
|
||||||
|
|
||||||
id<MTLComputePipelineState> _computePipelines[10];
|
id<MTLComputePipelineState> _computePipelines[10];
|
||||||
id<MTLRenderPipelineState> _renderPipelines[10];
|
id<MTLRenderPipelineState> _renderPipelines[10];
|
||||||
id<MTLRenderPipelineState> _controlLineRenderPipelines[10];
|
id<MTLRenderPipelineState> _controlLineRenderPipelines[10];
|
||||||
@ -157,11 +157,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
id<MTLBuffer> _faceVaryingIndicesBuffer;
|
id<MTLBuffer> _faceVaryingIndicesBuffer;
|
||||||
id<MTLBuffer> _faceVaryingPatchParamBuffer;
|
id<MTLBuffer> _faceVaryingPatchParamBuffer;
|
||||||
|
|
||||||
|
|
||||||
Camera _cameraData;
|
Camera _cameraData;
|
||||||
Osd::MTLContext _context;
|
Osd::MTLContext _context;
|
||||||
|
|
||||||
|
|
||||||
int _numVertexElements;
|
int _numVertexElements;
|
||||||
int _numVaryingElements;
|
int _numVaryingElements;
|
||||||
int _numFaceVaryingElements;
|
int _numFaceVaryingElements;
|
||||||
@ -173,7 +173,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
std::unique_ptr<MTLControlMeshDisplay> _controlMesh;
|
std::unique_ptr<MTLControlMeshDisplay> _controlMesh;
|
||||||
std::unique_ptr<Osd::MTLLegacyGregoryPatchTable> _legacyGregoryPatchTable;
|
std::unique_ptr<Osd::MTLLegacyGregoryPatchTable> _legacyGregoryPatchTable;
|
||||||
std::unique_ptr<Shape> _shape;
|
std::unique_ptr<Shape> _shape;
|
||||||
|
|
||||||
bool _needsRebuild;
|
bool _needsRebuild;
|
||||||
NSString* _osdShaderSource;
|
NSString* _osdShaderSource;
|
||||||
simd::float3 _meshCenter;
|
simd::float3 _meshCenter;
|
||||||
@ -206,17 +206,17 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
self.tessellationLevel = 8;
|
self.tessellationLevel = 8;
|
||||||
self.shadingMode = kShadingMaterial;
|
self.shadingMode = kShadingMaterial;
|
||||||
self.displayStyle = kDisplayStyleShaded;
|
self.displayStyle = kDisplayStyleShaded;
|
||||||
|
|
||||||
_frameCount = 0;
|
_frameCount = 0;
|
||||||
_animationFrames = 0;
|
_animationFrames = 0;
|
||||||
_delegate = delegate;
|
_delegate = delegate;
|
||||||
_context.device = [delegate deviceFor:self];
|
_context.device = [delegate deviceFor:self];
|
||||||
_context.commandQueue = [delegate commandQueueFor:self];
|
_context.commandQueue = [delegate commandQueueFor:self];
|
||||||
|
|
||||||
_osdShaderSource = @(shaderSource);
|
_osdShaderSource = @(shaderSource);
|
||||||
|
|
||||||
_needsRebuild = true;
|
_needsRebuild = true;
|
||||||
|
|
||||||
[self _initializeBuffers];
|
[self _initializeBuffers];
|
||||||
[self _initializeCamera];
|
[self _initializeCamera];
|
||||||
[self _initializeLights];
|
[self _initializeLights];
|
||||||
@ -235,7 +235,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
_animatedVertices.resize(_vertexData.size());
|
_animatedVertices.resize(_vertexData.size());
|
||||||
auto p = _vertexData.data();
|
auto p = _vertexData.data();
|
||||||
auto n = _animatedVertices.data();
|
auto n = _animatedVertices.data();
|
||||||
|
|
||||||
int numElements = _numVertexElements + _numVaryingElements;
|
int numElements = _numVertexElements + _numVaryingElements;
|
||||||
|
|
||||||
float r = sin(_animationFrames*0.01f) * _animateVertices;
|
float r = sin(_animationFrames*0.01f) * _animateVertices;
|
||||||
@ -246,7 +246,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
n[0] = p[0]*ct + p[1]*st;
|
n[0] = p[0]*ct + p[1]*st;
|
||||||
n[1] = -p[0]*st + p[1]*ct;
|
n[1] = -p[0]*st + p[1]*ct;
|
||||||
n[2] = p[2];
|
n[2] = p[2];
|
||||||
|
|
||||||
for (int j = 0; j < _numVaryingElements; ++j) {
|
for (int j = 0; j < _numVaryingElements; ++j) {
|
||||||
n[3 + j] = p[3 + j];
|
n[3 + j] = p[3 + j];
|
||||||
}
|
}
|
||||||
@ -254,30 +254,30 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
p += numElements;
|
p += numElements;
|
||||||
n += numElements;
|
n += numElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mesh->UpdateVertexBuffer(_animatedVertices.data(), 0, _numVertices);
|
_mesh->UpdateVertexBuffer(_animatedVertices.data(), 0, _numVertices);
|
||||||
_animationFrames++;
|
_animationFrames++;
|
||||||
}
|
}
|
||||||
_mesh->Refine();
|
_mesh->Refine();
|
||||||
_mesh->Synchronize();
|
_mesh->Synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _updateState];
|
[self _updateState];
|
||||||
|
|
||||||
if(_doAdaptive) {
|
if(_doAdaptive) {
|
||||||
auto computeEncoder = [commandBuffer computeCommandEncoder];
|
auto computeEncoder = [commandBuffer computeCommandEncoder];
|
||||||
[self _computeTessFactors:computeEncoder];
|
[self _computeTessFactors:computeEncoder];
|
||||||
[computeEncoder endEncoding];
|
[computeEncoder endEncoding];
|
||||||
}
|
}
|
||||||
|
|
||||||
auto renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:[_delegate renderPassDescriptorFor: self]];
|
auto renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:[_delegate renderPassDescriptorFor: self]];
|
||||||
|
|
||||||
if(_usePrimitiveBackfaceCulling) {
|
if(_usePrimitiveBackfaceCulling) {
|
||||||
[renderEncoder setCullMode:MTLCullModeBack];
|
[renderEncoder setCullMode:MTLCullModeBack];
|
||||||
} else {
|
} else {
|
||||||
[renderEncoder setCullMode:MTLCullModeNone];
|
[renderEncoder setCullMode:MTLCullModeNone];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _renderMesh:renderEncoder];
|
[self _renderMesh:renderEncoder];
|
||||||
|
|
||||||
_frameConstantsBuffer.next();
|
_frameConstantsBuffer.next();
|
||||||
@ -290,20 +290,20 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
_perPatchDataBuffer.next();
|
_perPatchDataBuffer.next();
|
||||||
_hsDataBuffer.next();
|
_hsDataBuffer.next();
|
||||||
_drawIndirectCommandsBuffer.next();
|
_drawIndirectCommandsBuffer.next();
|
||||||
|
|
||||||
_frameCount++;
|
_frameCount++;
|
||||||
|
|
||||||
return renderEncoder;
|
return renderEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)_renderMesh:(id<MTLRenderCommandEncoder>)renderCommandEncoder {
|
-(void)_renderMesh:(id<MTLRenderCommandEncoder>)renderCommandEncoder {
|
||||||
auto buffer = _mesh->BindVertexBuffer();
|
auto buffer = _mesh->BindVertexBuffer();
|
||||||
assert(buffer);
|
assert(buffer);
|
||||||
|
|
||||||
auto pav = _mesh->GetPatchTable()->GetPatchArrays();
|
auto pav = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
auto pib = _mesh->GetPatchTable()->GetPatchIndexBuffer();
|
auto pib = _mesh->GetPatchTable()->GetPatchIndexBuffer();
|
||||||
auto pfvarav = _mesh->GetPatchTable()->GetFVarPatchArrays();
|
auto pfvarav = _mesh->GetPatchTable()->GetFVarPatchArrays();
|
||||||
|
|
||||||
[renderCommandEncoder setVertexBuffer:buffer offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:buffer offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:pib offset:0 atIndex:INDICES_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:pib offset:0 atIndex:INDICES_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
||||||
@ -314,7 +314,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:0 atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:0 atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
|
||||||
#endif
|
#endif
|
||||||
[renderCommandEncoder setVertexBuffer:_faceVaryingIndicesBuffer offset:0 atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_faceVaryingIndicesBuffer offset:0 atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setVertexBuffer:_hsDataBuffer offset:0 atIndex:OSD_PERPATCHTESSFACTORS_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_hsDataBuffer offset:0 atIndex:OSD_PERPATCHTESSFACTORS_BUFFER_INDEX];
|
||||||
@ -323,31 +323,31 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder setVertexBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:_faceVaryingPatchParamBuffer offset:0 atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_faceVaryingPatchParamBuffer offset:0 atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_endCapMode == kEndCapLegacyGregory)
|
if(_endCapMode == kEndCapLegacyGregory)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setVertexBuffer:_legacyGregoryPatchTable->GetQuadOffsetsBuffer() offset:0 atIndex:OSD_QUADOFFSET_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_legacyGregoryPatchTable->GetQuadOffsetsBuffer() offset:0 atIndex:OSD_QUADOFFSET_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBuffer:_legacyGregoryPatchTable->GetVertexValenceBuffer() offset:0 atIndex:OSD_VALENCE_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBuffer:_legacyGregoryPatchTable->GetVertexValenceBuffer() offset:0 atIndex:OSD_VALENCE_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
[renderCommandEncoder setFragmentBuffer:_lightsBuffer offset:0 atIndex:0];
|
[renderCommandEncoder setFragmentBuffer:_lightsBuffer offset:0 atIndex:0];
|
||||||
|
|
||||||
if(_displayStyle == kDisplayStyleWire)
|
if(_displayStyle == kDisplayStyleWire)
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
||||||
else
|
else
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||||
|
|
||||||
std::fill_n(_patchCounts, 12, 0);
|
std::fill_n(_patchCounts, 12, 0);
|
||||||
|
|
||||||
for(int i = 0; i < pav.size(); i++)
|
for(int i = 0; i < pav.size(); i++)
|
||||||
{
|
{
|
||||||
auto& patch = pav[i];
|
auto& patch = pav[i];
|
||||||
auto d = patch.GetDescriptor();
|
auto d = patch.GetDescriptor();
|
||||||
auto patchType = d.GetType();
|
auto patchType = d.GetType();
|
||||||
auto offset = patchType - Far::PatchDescriptor::REGULAR;
|
auto offset = patchType - Far::PatchDescriptor::REGULAR;
|
||||||
|
|
||||||
_patchCounts[patchType] = patch.GetNumPatches();
|
_patchCounts[patchType] = patch.GetNumPatches();
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setVertexBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
||||||
@ -358,15 +358,15 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.primitiveIdBase+patch.primitiveIdBase) * sizeof(int) * 3 atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.primitiveIdBase+patch.primitiveIdBase) * sizeof(int) * 3 atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
|
||||||
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.indexBase+(patch.primitiveIdBase*fvarPatch.desc.GetNumControlVertices())) * sizeof(unsigned) atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.indexBase+(patch.primitiveIdBase*fvarPatch.desc.GetNumControlVertices())) * sizeof(unsigned) atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
[renderCommandEncoder setVertexBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
[renderCommandEncoder setVertexBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
||||||
|
|
||||||
simd::float4 shade{.0f,0.0f,0.0f,1.0f};
|
simd::float4 shade{.0f,0.0f,0.0f,1.0f};
|
||||||
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
||||||
[renderCommandEncoder setDepthBias:0 slopeScale:1.0 clamp:0];
|
[renderCommandEncoder setDepthBias:0 slopeScale:1.0 clamp:0];
|
||||||
[renderCommandEncoder setDepthStencilState:_readWriteDepthStencilState];
|
[renderCommandEncoder setDepthStencilState:_readWriteDepthStencilState];
|
||||||
[renderCommandEncoder setRenderPipelineState:_renderPipelines[patchType]];
|
[renderCommandEncoder setRenderPipelineState:_renderPipelines[patchType]];
|
||||||
|
|
||||||
switch(patchType)
|
switch(patchType)
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
||||||
@ -378,7 +378,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(patchType)
|
switch(patchType)
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::GREGORY_BASIS:
|
case Far::PatchDescriptor::GREGORY_BASIS:
|
||||||
@ -405,7 +405,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
||||||
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder drawIndexedPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
[renderCommandEncoder drawIndexedPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
||||||
@ -420,7 +420,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
controlPointIndexBuffer:pib controlPointIndexBufferOffset:patch.indexBase * sizeof(unsigned)
|
controlPointIndexBuffer:pib controlPointIndexBufferOffset:patch.indexBase * sizeof(unsigned)
|
||||||
instanceCount:1 baseInstance:0];
|
instanceCount:1 baseInstance:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -442,14 +442,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
||||||
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
|
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_displayStyle == kDisplayStyleWireOnShaded)
|
if(_displayStyle == kDisplayStyleWireOnShaded)
|
||||||
{
|
{
|
||||||
simd::float4 shade = {1, 1,1,1};
|
simd::float4 shade = {1, 1,1,1};
|
||||||
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
|
||||||
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
|
||||||
|
|
||||||
#if !TARGET_OS_EMBEDDED
|
#if !TARGET_OS_EMBEDDED
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
@ -463,13 +463,13 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
|
||||||
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
|
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case Far::PatchDescriptor::QUADS:
|
case Far::PatchDescriptor::QUADS:
|
||||||
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:patch.GetNumPatches() * 6];
|
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:patch.GetNumPatches() * 6];
|
||||||
if(_displayStyle == kDisplayStyleWireOnShaded)
|
if(_displayStyle == kDisplayStyleWireOnShaded)
|
||||||
@ -498,13 +498,13 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
default:
|
default:
|
||||||
assert("Unsupported patch type" && 0); break;
|
assert("Unsupported patch type" && 0); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_displayControlMeshEdges)
|
if(_displayControlMeshEdges)
|
||||||
{
|
{
|
||||||
if(_displayControlMeshEdges && _controlLineRenderPipelines[patchType])
|
if(_displayControlMeshEdges && _controlLineRenderPipelines[patchType])
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setRenderPipelineState:_controlLineRenderPipelines[patchType]];
|
[renderCommandEncoder setRenderPipelineState:_controlLineRenderPipelines[patchType]];
|
||||||
|
|
||||||
unsigned primPerPatch = 0;
|
unsigned primPerPatch = 0;
|
||||||
switch(patchType)
|
switch(patchType)
|
||||||
{
|
{
|
||||||
@ -517,12 +517,12 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
primPerPatch = 56;
|
primPerPatch = 56;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:patch.GetNumPatches() * primPerPatch];
|
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:patch.GetNumPatches() * primPerPatch];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_displayControlMeshEdges)
|
if(_displayControlMeshEdges)
|
||||||
{
|
{
|
||||||
[renderCommandEncoder setDepthStencilState:_readOnlyDepthStencilState];
|
[renderCommandEncoder setDepthStencilState:_readOnlyDepthStencilState];
|
||||||
@ -532,7 +532,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
|
|
||||||
-(void)_computeTessFactors:(id<MTLComputeCommandEncoder>)computeCommandEncoder {
|
-(void)_computeTessFactors:(id<MTLComputeCommandEncoder>)computeCommandEncoder {
|
||||||
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
|
|
||||||
[computeCommandEncoder setBuffer:_mesh->BindVertexBuffer() offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_mesh->BindVertexBuffer() offset:0 atIndex:VERTEX_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchIndexBuffer() offset:0 atIndex:CONTROL_INDICES_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchIndexBuffer() offset:0 atIndex:CONTROL_INDICES_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchParamBuffer() offset:0 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_mesh->GetPatchTable()->GetPatchParamBuffer() offset:0 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
||||||
@ -541,46 +541,46 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[computeCommandEncoder setBuffer:_tessFactorsBuffer offset:0 atIndex:QUAD_TESSFACTORS_INDEX];
|
[computeCommandEncoder setBuffer:_tessFactorsBuffer offset:0 atIndex:QUAD_TESSFACTORS_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
|
||||||
|
|
||||||
if(_legacyGregoryPatchTable)
|
if(_legacyGregoryPatchTable)
|
||||||
{
|
{
|
||||||
[computeCommandEncoder setBuffer:_legacyGregoryPatchTable->GetQuadOffsetsBuffer() offset:0 atIndex:OSD_QUADOFFSET_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_legacyGregoryPatchTable->GetQuadOffsetsBuffer() offset:0 atIndex:OSD_QUADOFFSET_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_legacyGregoryPatchTable->GetVertexValenceBuffer() offset:0 atIndex:OSD_VALENCE_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_legacyGregoryPatchTable->GetVertexValenceBuffer() offset:0 atIndex:OSD_VALENCE_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& patch : patchArray)
|
for(auto& patch : patchArray)
|
||||||
{
|
{
|
||||||
auto usefulControlPoints = patch.GetDescriptor().GetNumControlVertices();
|
auto usefulControlPoints = patch.GetDescriptor().GetNumControlVertices();
|
||||||
if(patch.GetDescriptor().GetType() == Far::PatchDescriptor::GREGORY_BASIS)
|
if(patch.GetDescriptor().GetType() == Far::PatchDescriptor::GREGORY_BASIS)
|
||||||
usefulControlPoints = 4;
|
usefulControlPoints = 4;
|
||||||
|
|
||||||
auto threadsPerThreadgroup = MTLSizeMake(_threadgroupSizes[patch.desc.GetType()], 1, 1);
|
auto threadsPerThreadgroup = MTLSizeMake(_threadgroupSizes[patch.desc.GetType()], 1, 1);
|
||||||
auto threadsPerControlPoint = std::max<int>(1, usefulControlPoints / threadsPerThreadgroup.width);
|
auto threadsPerControlPoint = std::max<int>(1, usefulControlPoints / threadsPerThreadgroup.width);
|
||||||
|
|
||||||
auto groupPerControlPoint = MTLSizeMake(patch.GetNumPatches() * usefulControlPoints, 1, 1);
|
auto groupPerControlPoint = MTLSizeMake(patch.GetNumPatches() * usefulControlPoints, 1, 1);
|
||||||
|
|
||||||
groupPerControlPoint.width /= threadsPerControlPoint;
|
groupPerControlPoint.width /= threadsPerControlPoint;
|
||||||
|
|
||||||
groupPerControlPoint.width = (groupPerControlPoint.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
groupPerControlPoint.width = (groupPerControlPoint.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
||||||
groupPerControlPoint.width = groupPerControlPoint.width / threadsPerThreadgroup.width;
|
groupPerControlPoint.width = groupPerControlPoint.width / threadsPerThreadgroup.width;
|
||||||
|
|
||||||
|
|
||||||
auto groupPerPatch = MTLSizeMake(patch.GetNumPatches(), 1, 1);
|
auto groupPerPatch = MTLSizeMake(patch.GetNumPatches(), 1, 1);
|
||||||
groupPerPatch.width = (groupPerPatch.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
groupPerPatch.width = (groupPerPatch.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
|
||||||
groupPerPatch.width = groupPerPatch.width / threadsPerThreadgroup.width;
|
groupPerPatch.width = groupPerPatch.width / threadsPerThreadgroup.width;
|
||||||
|
|
||||||
[computeCommandEncoder setBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
[computeCommandEncoder setBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
[computeCommandEncoder setBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
|
||||||
|
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
[computeCommandEncoder setBuffer:_patchIndexBuffers[patch.desc.GetType() - Far::PatchDescriptor::REGULAR] offset:0 atIndex:OSD_PATCH_INDEX_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_patchIndexBuffers[patch.desc.GetType() - Far::PatchDescriptor::REGULAR] offset:0 atIndex:OSD_PATCH_INDEX_BUFFER_INDEX];
|
||||||
[computeCommandEncoder setBuffer:_drawIndirectCommandsBuffer offset:sizeof(MTLDrawPatchIndirectArguments) * (patch.desc.GetType() - Far::PatchDescriptor::REGULAR) atIndex:OSD_DRAWINDIRECT_BUFFER_INDEX];
|
[computeCommandEncoder setBuffer:_drawIndirectCommandsBuffer offset:sizeof(MTLDrawPatchIndirectArguments) * (patch.desc.GetType() - Far::PatchDescriptor::REGULAR) atIndex:OSD_DRAWINDIRECT_BUFFER_INDEX];
|
||||||
}
|
}
|
||||||
|
|
||||||
[computeCommandEncoder setComputePipelineState:_computePipelines[patch.desc.GetType()]];
|
[computeCommandEncoder setComputePipelineState:_computePipelines[patch.desc.GetType()]];
|
||||||
|
|
||||||
unsigned kernelExecutionLimit;
|
unsigned kernelExecutionLimit;
|
||||||
switch(patch.desc.GetType())
|
switch(patch.desc.GetType())
|
||||||
{
|
{
|
||||||
@ -608,7 +608,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
break;
|
break;
|
||||||
default: assert("Unsupported patch type" && 0); break;
|
default: assert("Unsupported patch type" && 0); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[computeCommandEncoder setBytes:&kernelExecutionLimit length:sizeof(kernelExecutionLimit) atIndex:OSD_KERNELLIMIT_BUFFER_INDEX];
|
[computeCommandEncoder setBytes:&kernelExecutionLimit length:sizeof(kernelExecutionLimit) atIndex:OSD_KERNELLIMIT_BUFFER_INDEX];
|
||||||
[computeCommandEncoder dispatchThreadgroups:groupPerControlPoint threadsPerThreadgroup:threadsPerThreadgroup];
|
[computeCommandEncoder dispatchThreadgroups:groupPerControlPoint threadsPerThreadgroup:threadsPerThreadgroup];
|
||||||
}
|
}
|
||||||
@ -618,12 +618,12 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[self _rebuildModel];
|
[self _rebuildModel];
|
||||||
[self _rebuildBuffers];
|
[self _rebuildBuffers];
|
||||||
[self _rebuildPipelines];
|
[self _rebuildPipelines];
|
||||||
|
|
||||||
_needsRebuild = false;
|
_needsRebuild = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)_rebuildModel {
|
-(void)_rebuildModel {
|
||||||
|
|
||||||
using namespace OpenSubdiv;
|
using namespace OpenSubdiv;
|
||||||
using namespace Sdc;
|
using namespace Sdc;
|
||||||
using namespace Osd;
|
using namespace Osd;
|
||||||
@ -631,7 +631,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
auto shapeDesc = &g_defaultShapes[[_loadedModels indexOfObject:_currentModel]];
|
auto shapeDesc = &g_defaultShapes[[_loadedModels indexOfObject:_currentModel]];
|
||||||
_shape.reset(Shape::parseObj(shapeDesc->data.c_str(), shapeDesc->scheme));
|
_shape.reset(Shape::parseObj(shapeDesc->data.c_str(), shapeDesc->scheme));
|
||||||
const auto scheme = shapeDesc->scheme;
|
const auto scheme = shapeDesc->scheme;
|
||||||
|
|
||||||
// create Far mesh (topology)
|
// create Far mesh (topology)
|
||||||
Sdc::SchemeType sdctype = GetSdcType(*_shape);
|
Sdc::SchemeType sdctype = GetSdcType(*_shape);
|
||||||
Sdc::Options sdcoptions = GetSdcOptions(*_shape);
|
Sdc::Options sdcoptions = GetSdcOptions(*_shape);
|
||||||
@ -640,17 +640,17 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
|
|
||||||
std::unique_ptr<OpenSubdiv::Far::TopologyRefiner> refiner;
|
std::unique_ptr<OpenSubdiv::Far::TopologyRefiner> refiner;
|
||||||
refiner.reset(Far::TopologyRefinerFactory<Shape>::Create(*_shape, Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions)));
|
refiner.reset(Far::TopologyRefinerFactory<Shape>::Create(*_shape, Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions)));
|
||||||
|
|
||||||
// save coarse topology (used for coarse mesh drawing)
|
// save coarse topology (used for coarse mesh drawing)
|
||||||
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||||
_numVertices = refBaseLevel.GetNumVertices();
|
_numVertices = refBaseLevel.GetNumVertices();
|
||||||
|
|
||||||
|
|
||||||
// Adaptive refinement currently supported only for catmull-clark scheme
|
// Adaptive refinement currently supported only for catmull-clark scheme
|
||||||
_doAdaptive = (_useAdaptive && scheme == kCatmark);
|
_doAdaptive = (_useAdaptive && scheme == kCatmark);
|
||||||
bool doSingleCreasePatch = (_useSingleCrease && scheme == kCatmark);
|
bool doSingleCreasePatch = (_useSingleCrease && scheme == kCatmark);
|
||||||
bool doInfSharpPatch = (_useInfinitelySharpPatch && scheme == kCatmark);
|
bool doInfSharpPatch = (_useInfinitelySharpPatch && scheme == kCatmark);
|
||||||
|
|
||||||
Osd::MeshBitset bits;
|
Osd::MeshBitset bits;
|
||||||
bits.set(Osd::MeshAdaptive, _doAdaptive);
|
bits.set(Osd::MeshAdaptive, _doAdaptive);
|
||||||
bits.set(Osd::MeshUseSingleCreasePatch, doSingleCreasePatch);
|
bits.set(Osd::MeshUseSingleCreasePatch, doSingleCreasePatch);
|
||||||
@ -658,7 +658,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
bits.set(Osd::MeshEndCapBSplineBasis, _endCapMode == kEndCapBSplineBasis);
|
bits.set(Osd::MeshEndCapBSplineBasis, _endCapMode == kEndCapBSplineBasis);
|
||||||
bits.set(Osd::MeshEndCapGregoryBasis, _endCapMode == kEndCapGregoryBasis);
|
bits.set(Osd::MeshEndCapGregoryBasis, _endCapMode == kEndCapGregoryBasis);
|
||||||
bits.set(Osd::MeshEndCapLegacyGregory, _endCapMode == kEndCapLegacyGregory);
|
bits.set(Osd::MeshEndCapLegacyGregory, _endCapMode == kEndCapLegacyGregory);
|
||||||
|
|
||||||
int level = _refinementLevel;
|
int level = _refinementLevel;
|
||||||
_numVertexElements = 3;
|
_numVertexElements = 3;
|
||||||
|
|
||||||
@ -675,7 +675,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
bits.set(OpenSubdiv::Osd::MeshFVarAdaptive, _doAdaptive);
|
bits.set(OpenSubdiv::Osd::MeshFVarAdaptive, _doAdaptive);
|
||||||
|
|
||||||
int numElements = _numVertexElements + _numVaryingElements;
|
int numElements = _numVertexElements + _numVaryingElements;
|
||||||
|
|
||||||
if(_kernelType == kCPU)
|
if(_kernelType == kCPU)
|
||||||
{
|
{
|
||||||
_mesh.reset(new CPUMeshType(refiner.get(),
|
_mesh.reset(new CPUMeshType(refiner.get(),
|
||||||
@ -690,11 +690,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
_numVaryingElements,
|
_numVaryingElements,
|
||||||
level, bits, nullptr, &_context));
|
level, bits, nullptr, &_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MTLRenderPipelineDescriptor* desc = [MTLRenderPipelineDescriptor new];
|
MTLRenderPipelineDescriptor* desc = [MTLRenderPipelineDescriptor new];
|
||||||
[_delegate setupRenderPipelineState:desc for:self];
|
[_delegate setupRenderPipelineState:desc for:self];
|
||||||
|
|
||||||
const auto vertexDescriptor = desc.vertexDescriptor;
|
const auto vertexDescriptor = desc.vertexDescriptor;
|
||||||
vertexDescriptor.layouts[0].stride = sizeof(float) * numElements;
|
vertexDescriptor.layouts[0].stride = sizeof(float) * numElements;
|
||||||
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
||||||
@ -702,36 +702,36 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3;
|
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3;
|
||||||
vertexDescriptor.attributes[0].offset = 0;
|
vertexDescriptor.attributes[0].offset = 0;
|
||||||
vertexDescriptor.attributes[0].bufferIndex = 0;
|
vertexDescriptor.attributes[0].bufferIndex = 0;
|
||||||
|
|
||||||
_controlMesh.reset(new MTLControlMeshDisplay(_context.device, desc));
|
_controlMesh.reset(new MTLControlMeshDisplay(_context.device, desc));
|
||||||
_controlMesh->SetTopology(refBaseLevel);
|
_controlMesh->SetTopology(refBaseLevel);
|
||||||
_controlMesh->SetEdgesDisplay(true);
|
_controlMesh->SetEdgesDisplay(true);
|
||||||
_controlMesh->SetVerticesDisplay(false);
|
_controlMesh->SetVerticesDisplay(false);
|
||||||
|
|
||||||
_legacyGregoryPatchTable.reset();
|
_legacyGregoryPatchTable.reset();
|
||||||
if(_endCapMode == kEndCapLegacyGregory)
|
if(_endCapMode == kEndCapLegacyGregory)
|
||||||
{
|
{
|
||||||
_legacyGregoryPatchTable.reset(Osd::MTLLegacyGregoryPatchTable::Create(_mesh->GetFarPatchTable(),
|
_legacyGregoryPatchTable.reset(Osd::MTLLegacyGregoryPatchTable::Create(_mesh->GetFarPatchTable(),
|
||||||
&_context));
|
&_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
_vertexData.resize(refBaseLevel.GetNumVertices() * numElements);
|
_vertexData.resize(refBaseLevel.GetNumVertices() * numElements);
|
||||||
_meshCenter = simd::float3{0,0,0};
|
_meshCenter = simd::float3{0,0,0};
|
||||||
|
|
||||||
for(int i = 0; i < refBaseLevel.GetNumVertices(); i++)
|
for(int i = 0; i < refBaseLevel.GetNumVertices(); i++)
|
||||||
{
|
{
|
||||||
_vertexData[i * numElements + 0] = _shape->verts[i * 3 + 0];
|
_vertexData[i * numElements + 0] = _shape->verts[i * 3 + 0];
|
||||||
_vertexData[i * numElements + 1] = _shape->verts[i * 3 + 1];
|
_vertexData[i * numElements + 1] = _shape->verts[i * 3 + 1];
|
||||||
_vertexData[i * numElements + 2] = _shape->verts[i * 3 + 2];
|
_vertexData[i * numElements + 2] = _shape->verts[i * 3 + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto vertexIdx = 0; vertexIdx < refBaseLevel.GetNumVertices(); vertexIdx++)
|
for(auto vertexIdx = 0; vertexIdx < refBaseLevel.GetNumVertices(); vertexIdx++)
|
||||||
{
|
{
|
||||||
_meshCenter[0] += _vertexData[vertexIdx * numElements + 0];
|
_meshCenter[0] += _vertexData[vertexIdx * numElements + 0];
|
||||||
_meshCenter[1] += _vertexData[vertexIdx * numElements + 1];
|
_meshCenter[1] += _vertexData[vertexIdx * numElements + 1];
|
||||||
_meshCenter[2] += _vertexData[vertexIdx * numElements + 2];
|
_meshCenter[2] += _vertexData[vertexIdx * numElements + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
_meshCenter /= (_shape->verts.size() / 3);
|
_meshCenter /= (_shape->verts.size() / 3);
|
||||||
_mesh->UpdateVertexBuffer(_vertexData.data(), 0, refBaseLevel.GetNumVertices());
|
_mesh->UpdateVertexBuffer(_vertexData.data(), 0, refBaseLevel.GetNumVertices());
|
||||||
_mesh->Refine();
|
_mesh->Refine();
|
||||||
@ -825,9 +825,9 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
-(void)_updateState {
|
-(void)_updateState {
|
||||||
[self _updateCamera];
|
[self _updateCamera];
|
||||||
auto pData = _frameConstantsBuffer.data();
|
auto pData = _frameConstantsBuffer.data();
|
||||||
|
|
||||||
pData->TessLevel = _tessellationLevel;
|
pData->TessLevel = _tessellationLevel;
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
for(auto& patch : _mesh->GetPatchTable()->GetPatchArrays())
|
for(auto& patch : _mesh->GetPatchTable()->GetPatchArrays())
|
||||||
@ -841,7 +841,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
drawCommand[patch.desc.GetType() - Far::PatchDescriptor::REGULAR].patchStart = 0;
|
drawCommand[patch.desc.GetType() - Far::PatchDescriptor::REGULAR].patchStart = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
_drawIndirectCommandsBuffer.markModified();
|
_drawIndirectCommandsBuffer.markModified();
|
||||||
@ -855,19 +855,19 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
auto totalPatches = 0;
|
auto totalPatches = 0;
|
||||||
auto totalVertices = 0;
|
auto totalVertices = 0;
|
||||||
auto totalPatchDataSize = 0;
|
auto totalPatchDataSize = 0;
|
||||||
|
|
||||||
if(_usePatchIndexBuffer)
|
if(_usePatchIndexBuffer)
|
||||||
{
|
{
|
||||||
_drawIndirectCommandsBuffer.alloc(_context.device, 4, @"draw patch indirect commands");
|
_drawIndirectCommandsBuffer.alloc(_context.device, 4, @"draw patch indirect commands");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
for(auto& patch : patchArray)
|
for(auto& patch : patchArray)
|
||||||
{
|
{
|
||||||
auto patchDescriptor = patch.GetDescriptor();
|
auto patchDescriptor = patch.GetDescriptor();
|
||||||
|
|
||||||
switch(patch.desc.GetType())
|
switch(patch.desc.GetType())
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::REGULAR: {
|
case Far::PatchDescriptor::REGULAR: {
|
||||||
@ -881,7 +881,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
float elementFloats = 3;
|
float elementFloats = 3;
|
||||||
if(_useSingleCrease)
|
if(_useSingleCrease)
|
||||||
elementFloats += 6;
|
elementFloats += 6;
|
||||||
|
|
||||||
totalPatchDataSize += elementFloats * sizeof(float) * patch.GetNumPatches() * patch.desc.GetNumControlVertices(); // OsdPerPatchVertexBezier
|
totalPatchDataSize += elementFloats * sizeof(float) * patch.GetNumPatches() * patch.desc.GetNumControlVertices(); // OsdPerPatchVertexBezier
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -918,15 +918,15 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalPatches += patch.GetNumPatches();
|
totalPatches += patch.GetNumPatches();
|
||||||
totalVertices += patch.GetDescriptor().GetNumControlVertices() * patch.GetNumPatches();
|
totalVertices += patch.GetDescriptor().GetNumControlVertices() * patch.GetNumPatches();
|
||||||
}
|
}
|
||||||
|
|
||||||
_perPatchDataBuffer.alloc(_context.device, totalPatchDataSize, @"per patch data", MTLResourceStorageModePrivate);
|
_perPatchDataBuffer.alloc(_context.device, totalPatchDataSize, @"per patch data", MTLResourceStorageModePrivate);
|
||||||
_hsDataBuffer.alloc(_context.device, 20 * sizeof(float) * totalPatches, @"hs constant data", MTLResourceStorageModePrivate);
|
_hsDataBuffer.alloc(_context.device, 20 * sizeof(float) * totalPatches, @"hs constant data", MTLResourceStorageModePrivate);
|
||||||
_tessFactorsBuffer.alloc(_context.device, totalPatches, @"tessellation factors buffer", MTLResourceStorageModePrivate);
|
_tessFactorsBuffer.alloc(_context.device, totalPatches, @"tessellation factors buffer", MTLResourceStorageModePrivate);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,7 +936,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
_renderPipelines[i] = nil;
|
_renderPipelines[i] = nil;
|
||||||
_renderControlEdgesPipeline = nil;
|
_renderControlEdgesPipeline = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
Osd::MTLPatchShaderSource shaderSource;
|
Osd::MTLPatchShaderSource shaderSource;
|
||||||
auto patchArrays = _mesh->GetPatchTable()->GetPatchArrays();
|
auto patchArrays = _mesh->GetPatchTable()->GetPatchArrays();
|
||||||
auto pFVarArray = _mesh->GetPatchTable()->GetFVarPatchArrays();
|
auto pFVarArray = _mesh->GetPatchTable()->GetFVarPatchArrays();
|
||||||
@ -947,7 +947,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
auto& threadsPerThreadgroup = _threadgroupSizes[type];
|
auto& threadsPerThreadgroup = _threadgroupSizes[type];
|
||||||
threadsPerThreadgroup = 32; //Initial guess of 32
|
threadsPerThreadgroup = 32; //Initial guess of 32
|
||||||
int usefulControlPoints = patchArrays[i].GetDescriptor().GetNumControlVertices();
|
int usefulControlPoints = patchArrays[i].GetDescriptor().GetNumControlVertices();
|
||||||
|
|
||||||
auto compileOptions = [[MTLCompileOptions alloc] init];
|
auto compileOptions = [[MTLCompileOptions alloc] init];
|
||||||
auto preprocessor = [[NSMutableDictionary alloc] init];
|
auto preprocessor = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
@ -981,11 +981,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
usefulControlPoints = 4;
|
usefulControlPoints = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TARGET_OS_EMBEDDED
|
#if TARGET_OS_EMBEDDED
|
||||||
shaderBuilder << "#define OSD_UV_CORRECTION if(t > 0.5){ ti += 0.01f; } else { ti += 0.01f; }\n";
|
shaderBuilder << "#define OSD_UV_CORRECTION if(t > 0.5){ ti += 0.01f; } else { ti += 0.01f; }\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Need to define the input vertex struct so that it's available everywhere.
|
//Need to define the input vertex struct so that it's available everywhere.
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -998,14 +998,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
};
|
};
|
||||||
)";
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderBuilder << shaderSource.GetHullShaderSource(type, fvarType);
|
shaderBuilder << shaderSource.GetHullShaderSource(type, fvarType);
|
||||||
if(_numFaceVaryingElements > 0)
|
if(_numFaceVaryingElements > 0)
|
||||||
shaderBuilder << shaderSource.GetPatchBasisShaderSource();
|
shaderBuilder << shaderSource.GetPatchBasisShaderSource();
|
||||||
shaderBuilder << _osdShaderSource.UTF8String;
|
shaderBuilder << _osdShaderSource.UTF8String;
|
||||||
|
|
||||||
const auto str = shaderBuilder.str();
|
const auto str = shaderBuilder.str();
|
||||||
|
|
||||||
int numElements = _numVertexElements + _numVaryingElements;
|
int numElements = _numVertexElements + _numVaryingElements;
|
||||||
|
|
||||||
DEFINE(VERTEX_BUFFER_INDEX,VERTEX_BUFFER_INDEX);
|
DEFINE(VERTEX_BUFFER_INDEX,VERTEX_BUFFER_INDEX);
|
||||||
@ -1026,7 +1026,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
DEFINE(OSD_PATCH_ENABLE_SINGLE_CREASE, allowsSingleCrease && _useSingleCrease);
|
DEFINE(OSD_PATCH_ENABLE_SINGLE_CREASE, allowsSingleCrease && _useSingleCrease);
|
||||||
auto partitionMode = _useFractionalTessellation ? MTLTessellationPartitionModeFractionalOdd : MTLTessellationPartitionModePow2;
|
auto partitionMode = _useFractionalTessellation ? MTLTessellationPartitionModeFractionalOdd : MTLTessellationPartitionModePow2;
|
||||||
DEFINE(OSD_FRACTIONAL_EVEN_SPACING, partitionMode == MTLTessellationPartitionModeFractionalEven);
|
DEFINE(OSD_FRACTIONAL_EVEN_SPACING, partitionMode == MTLTessellationPartitionModeFractionalEven);
|
||||||
DEFINE(OSD_FRACTIONAL_ODD_SPACING, partitionMode == MTLTessellationPartitionModeFractionalOdd);
|
DEFINE(OSD_FRACTIONAL_ODD_SPACING, partitionMode == MTLTessellationPartitionModeFractionalOdd);
|
||||||
#if TARGET_OS_EMBEDDED
|
#if TARGET_OS_EMBEDDED
|
||||||
DEFINE(OSD_MAX_TESS_LEVEL, 16);
|
DEFINE(OSD_MAX_TESS_LEVEL, 16);
|
||||||
#else
|
#else
|
||||||
@ -1050,7 +1050,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
DEFINE(OSD_FVAR_PATCHPARAM_BUFFER_INDEX, OSD_FVAR_PATCHPARAM_BUFFER_INDEX);
|
DEFINE(OSD_FVAR_PATCHPARAM_BUFFER_INDEX, OSD_FVAR_PATCHPARAM_BUFFER_INDEX);
|
||||||
|
|
||||||
compileOptions.preprocessorMacros = preprocessor;
|
compileOptions.preprocessorMacros = preprocessor;
|
||||||
|
|
||||||
NSError* err = nil;
|
NSError* err = nil;
|
||||||
auto librarySource = [NSString stringWithUTF8String:str.data()];
|
auto librarySource = [NSString stringWithUTF8String:str.data()];
|
||||||
auto library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:&err];
|
auto library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:&err];
|
||||||
@ -1062,71 +1062,71 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
auto fragmentFunction = [library newFunctionWithName:@"fragment_main"];
|
auto fragmentFunction = [library newFunctionWithName:@"fragment_main"];
|
||||||
if(vertexFunction && fragmentFunction)
|
if(vertexFunction && fragmentFunction)
|
||||||
{
|
{
|
||||||
|
|
||||||
MTLRenderPipelineDescriptor* pipelineDesc = [[MTLRenderPipelineDescriptor alloc] init];
|
MTLRenderPipelineDescriptor* pipelineDesc = [[MTLRenderPipelineDescriptor alloc] init];
|
||||||
pipelineDesc.tessellationFactorFormat = MTLTessellationFactorFormatHalf;
|
pipelineDesc.tessellationFactorFormat = MTLTessellationFactorFormatHalf;
|
||||||
pipelineDesc.tessellationPartitionMode = partitionMode;
|
pipelineDesc.tessellationPartitionMode = partitionMode;
|
||||||
pipelineDesc.tessellationFactorScaleEnabled = false;
|
pipelineDesc.tessellationFactorScaleEnabled = false;
|
||||||
pipelineDesc.tessellationFactorStepFunction = MTLTessellationFactorStepFunctionPerPatch;
|
pipelineDesc.tessellationFactorStepFunction = MTLTessellationFactorStepFunctionPerPatch;
|
||||||
|
|
||||||
if(type == Far::PatchDescriptor::GREGORY_BASIS && _useStageIn)
|
if(type == Far::PatchDescriptor::GREGORY_BASIS && _useStageIn)
|
||||||
pipelineDesc.tessellationControlPointIndexType = MTLTessellationControlPointIndexTypeUInt32;
|
pipelineDesc.tessellationControlPointIndexType = MTLTessellationControlPointIndexTypeUInt32;
|
||||||
|
|
||||||
[_delegate setupRenderPipelineState:pipelineDesc for:self];
|
[_delegate setupRenderPipelineState:pipelineDesc for:self];
|
||||||
|
|
||||||
{
|
{
|
||||||
pipelineDesc.fragmentFunction = [library newFunctionWithName:@"fragment_solidcolor"];
|
pipelineDesc.fragmentFunction = [library newFunctionWithName:@"fragment_solidcolor"];
|
||||||
pipelineDesc.vertexFunction = [library newFunctionWithName:@"vertex_lines"];
|
pipelineDesc.vertexFunction = [library newFunctionWithName:@"vertex_lines"];
|
||||||
|
|
||||||
if(pipelineDesc.vertexFunction)
|
if(pipelineDesc.vertexFunction)
|
||||||
_controlLineRenderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
|
_controlLineRenderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
|
||||||
else
|
else
|
||||||
_controlLineRenderPipelines[type] = nil;
|
_controlLineRenderPipelines[type] = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelineDesc.fragmentFunction = fragmentFunction;
|
pipelineDesc.fragmentFunction = fragmentFunction;
|
||||||
pipelineDesc.vertexFunction = vertexFunction;
|
pipelineDesc.vertexFunction = vertexFunction;
|
||||||
|
|
||||||
if(_useStageIn)
|
if(_useStageIn)
|
||||||
{
|
{
|
||||||
auto vertexDesc = pipelineDesc.vertexDescriptor;
|
auto vertexDesc = pipelineDesc.vertexDescriptor;
|
||||||
[vertexDesc reset];
|
[vertexDesc reset];
|
||||||
|
|
||||||
if(_doAdaptive)
|
if(_doAdaptive)
|
||||||
{
|
{
|
||||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
||||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stride = sizeof(int) * 3;
|
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stride = sizeof(int) * 3;
|
||||||
|
|
||||||
// PatchInput :: int3 patchParam [[attribute(10)]];
|
// PatchInput :: int3 patchParam [[attribute(10)]];
|
||||||
vertexDesc.attributes[10].bufferIndex = OSD_PATCHPARAM_BUFFER_INDEX;
|
vertexDesc.attributes[10].bufferIndex = OSD_PATCHPARAM_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[10].format = MTLVertexFormatInt3;
|
vertexDesc.attributes[10].format = MTLVertexFormatInt3;
|
||||||
vertexDesc.attributes[10].offset = 0;
|
vertexDesc.attributes[10].offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case Far::PatchDescriptor::REGULAR:
|
case Far::PatchDescriptor::REGULAR:
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride = sizeof(float) * 3;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride = sizeof(float) * 3;
|
||||||
|
|
||||||
// ControlPoint :: float3 P [[attribute(0)]];
|
// ControlPoint :: float3 P [[attribute(0)]];
|
||||||
// OsdPerPatchVertexBezier :: packed_float3 P
|
// OsdPerPatchVertexBezier :: packed_float3 P
|
||||||
vertexDesc.attributes[0].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
vertexDesc.attributes[0].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
||||||
vertexDesc.attributes[0].offset = 0;
|
vertexDesc.attributes[0].offset = 0;
|
||||||
|
|
||||||
if(_useSingleCrease)
|
if(_useSingleCrease)
|
||||||
{
|
{
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride += sizeof(float) * 3 * 2;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride += sizeof(float) * 3 * 2;
|
||||||
|
|
||||||
// ControlPoint :: float3 P1 [[attribute(1)]];
|
// ControlPoint :: float3 P1 [[attribute(1)]];
|
||||||
// OsdPerPatchVertexBezier :: packed_float3 P1
|
// OsdPerPatchVertexBezier :: packed_float3 P1
|
||||||
vertexDesc.attributes[1].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
vertexDesc.attributes[1].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[1].format = MTLVertexFormatFloat3;
|
vertexDesc.attributes[1].format = MTLVertexFormatFloat3;
|
||||||
vertexDesc.attributes[1].offset = sizeof(float) * 3;
|
vertexDesc.attributes[1].offset = sizeof(float) * 3;
|
||||||
|
|
||||||
// ControlPoint :: float3 P2 [[attribute(2)]];
|
// ControlPoint :: float3 P2 [[attribute(2)]];
|
||||||
// OsdPerPatchVertexBezier :: packed_float3 P2
|
// OsdPerPatchVertexBezier :: packed_float3 P2
|
||||||
vertexDesc.attributes[2].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
vertexDesc.attributes[2].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
|
||||||
@ -1135,19 +1135,19 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
|
|
||||||
// USE_PTVS_SHARPNESS is true and so OsdPerPatchVertexBezier :: float2 vSegments is not used
|
// USE_PTVS_SHARPNESS is true and so OsdPerPatchVertexBezier :: float2 vSegments is not used
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_useScreenspaceTessellation)
|
if(_useScreenspaceTessellation)
|
||||||
{
|
{
|
||||||
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
||||||
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stride = sizeof(float) * 4 * 2;
|
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stride = sizeof(float) * 4 * 2;
|
||||||
|
|
||||||
// PatchInput :: float4 tessOuterLo [[attribute(5)]];
|
// PatchInput :: float4 tessOuterLo [[attribute(5)]];
|
||||||
// OsdPerPatchTessFactors :: float4 tessOuterLo;
|
// OsdPerPatchTessFactors :: float4 tessOuterLo;
|
||||||
vertexDesc.attributes[5].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
vertexDesc.attributes[5].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[5].format = MTLVertexFormatFloat4;
|
vertexDesc.attributes[5].format = MTLVertexFormatFloat4;
|
||||||
vertexDesc.attributes[5].offset = 0;
|
vertexDesc.attributes[5].offset = 0;
|
||||||
|
|
||||||
// PatchInput :: float4 tessOuterHi [[attribute(6)]];
|
// PatchInput :: float4 tessOuterHi [[attribute(6)]];
|
||||||
// OsdPerPatchTessFactors :: float4 tessOuterHi;
|
// OsdPerPatchTessFactors :: float4 tessOuterHi;
|
||||||
vertexDesc.attributes[6].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
vertexDesc.attributes[6].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
|
||||||
@ -1157,11 +1157,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
break;
|
break;
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
||||||
case Far::PatchDescriptor::GREGORY:
|
case Far::PatchDescriptor::GREGORY:
|
||||||
|
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stride = sizeof(float) * 3 * 5;
|
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stride = sizeof(float) * 3 * 5;
|
||||||
|
|
||||||
// ControlPoint :: float3 P [[attribute(0)]];
|
// ControlPoint :: float3 P [[attribute(0)]];
|
||||||
// ControlPoint :: float3 Ep [[attribute(1)]];
|
// ControlPoint :: float3 Ep [[attribute(1)]];
|
||||||
// ControlPoint :: float3 Em [[attribute(2)]];
|
// ControlPoint :: float3 Em [[attribute(2)]];
|
||||||
@ -1178,7 +1178,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
||||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepRate = 1;
|
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepRate = 1;
|
||||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stride = sizeof(float) * 3;
|
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stride = sizeof(float) * 3;
|
||||||
|
|
||||||
// ControlPoint :: float3 position [[attribute(0)]];
|
// ControlPoint :: float3 position [[attribute(0)]];
|
||||||
vertexDesc.attributes[0].bufferIndex = VERTEX_BUFFER_INDEX;
|
vertexDesc.attributes[0].bufferIndex = VERTEX_BUFFER_INDEX;
|
||||||
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
|
||||||
@ -1192,16 +1192,16 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
[vertexDesc reset];
|
[vertexDesc reset];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
|
_renderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
|
||||||
if(!_renderPipelines[type] && err)
|
if(!_renderPipelines[type] && err)
|
||||||
{
|
{
|
||||||
NSLog(@"%s", [[err localizedDescription] UTF8String]);
|
NSLog(@"%s", [[err localizedDescription] UTF8String]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto computeFunction = [library newFunctionWithName:@"compute_main"];
|
auto computeFunction = [library newFunctionWithName:@"compute_main"];
|
||||||
if(computeFunction)
|
if(computeFunction)
|
||||||
{
|
{
|
||||||
@ -1212,69 +1212,69 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
|
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
|
||||||
#endif
|
#endif
|
||||||
computeDesc.computeFunction = computeFunction;
|
computeDesc.computeFunction = computeFunction;
|
||||||
|
|
||||||
|
|
||||||
NSError* err;
|
NSError* err;
|
||||||
|
|
||||||
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
||||||
|
|
||||||
if(err && _computePipelines[type] == nil)
|
if(err && _computePipelines[type] == nil)
|
||||||
{
|
{
|
||||||
NSLog(@"%s", [[err description] UTF8String]);
|
NSLog(@"%s", [[err description] UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
|
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
|
||||||
{
|
{
|
||||||
DEFINE(THREADS_PER_THREADGROUP, _computePipelines[type].threadExecutionWidth);
|
DEFINE(THREADS_PER_THREADGROUP, _computePipelines[type].threadExecutionWidth);
|
||||||
DEFINE(CONTROL_POINTS_PER_THREAD, std::max<int>(1, usefulControlPoints / _computePipelines[type].threadExecutionWidth));
|
DEFINE(CONTROL_POINTS_PER_THREAD, std::max<int>(1, usefulControlPoints / _computePipelines[type].threadExecutionWidth));
|
||||||
|
|
||||||
compileOptions.preprocessorMacros = preprocessor;
|
compileOptions.preprocessorMacros = preprocessor;
|
||||||
|
|
||||||
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
|
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
|
||||||
assert(library);
|
assert(library);
|
||||||
|
|
||||||
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = true;
|
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = true;
|
||||||
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
|
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
|
||||||
|
|
||||||
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
|
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
|
||||||
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
||||||
|
|
||||||
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
|
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
|
||||||
{
|
{
|
||||||
DEFINE(THREADS_PER_THREADGROUP, threadsPerThreadgroup);
|
DEFINE(THREADS_PER_THREADGROUP, threadsPerThreadgroup);
|
||||||
DEFINE(CONTROL_POINTS_PER_THREAD, std::max<int>(1, usefulControlPoints / threadsPerThreadgroup));
|
DEFINE(CONTROL_POINTS_PER_THREAD, std::max<int>(1, usefulControlPoints / threadsPerThreadgroup));
|
||||||
DEFINE(NEEDS_BARRIER, 1);
|
DEFINE(NEEDS_BARRIER, 1);
|
||||||
|
|
||||||
compileOptions.preprocessorMacros = preprocessor;
|
compileOptions.preprocessorMacros = preprocessor;
|
||||||
|
|
||||||
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
|
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
|
||||||
assert(library);
|
assert(library);
|
||||||
|
|
||||||
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
|
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
|
||||||
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
|
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
|
||||||
|
|
||||||
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
|
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
|
||||||
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init];
|
MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init];
|
||||||
depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess;
|
depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess;
|
||||||
|
|
||||||
[_delegate setupDepthStencilState:depthStencilDesc for:self];
|
[_delegate setupDepthStencilState:depthStencilDesc for:self];
|
||||||
|
|
||||||
depthStencilDesc.depthWriteEnabled = YES;
|
depthStencilDesc.depthWriteEnabled = YES;
|
||||||
_readWriteDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
_readWriteDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
||||||
|
|
||||||
depthStencilDesc.depthWriteEnabled = NO;
|
depthStencilDesc.depthWriteEnabled = NO;
|
||||||
_readOnlyDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
_readOnlyDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)_updateCamera {
|
-(void)_updateCamera {
|
||||||
auto pData = _frameConstantsBuffer.data();
|
auto pData = _frameConstantsBuffer.data();
|
||||||
|
|
||||||
identity(pData->ModelViewMatrix);
|
identity(pData->ModelViewMatrix);
|
||||||
translate(pData->ModelViewMatrix, 0, 0, -_cameraData.dollyDistance);
|
translate(pData->ModelViewMatrix, 0, 0, -_cameraData.dollyDistance);
|
||||||
rotate(pData->ModelViewMatrix, _cameraData.rotationY, 1, 0, 0);
|
rotate(pData->ModelViewMatrix, _cameraData.rotationY, 1, 0, 0);
|
||||||
@ -1282,11 +1282,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
translate(pData->ModelViewMatrix, -_meshCenter[0], -_meshCenter[2], _meshCenter[1]); // z-up model
|
translate(pData->ModelViewMatrix, -_meshCenter[0], -_meshCenter[2], _meshCenter[1]); // z-up model
|
||||||
rotate(pData->ModelViewMatrix, -90, 1, 0, 0); // z-up model
|
rotate(pData->ModelViewMatrix, -90, 1, 0, 0); // z-up model
|
||||||
inverseMatrix(pData->ModelViewInverseMatrix, pData->ModelViewMatrix);
|
inverseMatrix(pData->ModelViewInverseMatrix, pData->ModelViewMatrix);
|
||||||
|
|
||||||
identity(pData->ProjectionMatrix);
|
identity(pData->ProjectionMatrix);
|
||||||
perspective(pData->ProjectionMatrix, 45.0, _cameraData.aspectRatio, 0.01f, 500.0);
|
perspective(pData->ProjectionMatrix, 45.0, _cameraData.aspectRatio, 0.01f, 500.0);
|
||||||
multMatrix(pData->ModelViewProjectionMatrix, pData->ModelViewMatrix, pData->ProjectionMatrix);
|
multMatrix(pData->ModelViewProjectionMatrix, pData->ModelViewMatrix, pData->ProjectionMatrix);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1310,14 +1310,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
|||||||
{ 0.7f, 0.7f, 0.7f, 1.0f },
|
{ 0.7f, 0.7f, 0.7f, 1.0f },
|
||||||
{ 0.8f, 0.8f, 0.8f, 1.0f },
|
{ 0.8f, 0.8f, 0.8f, 1.0f },
|
||||||
};
|
};
|
||||||
|
|
||||||
_lightsBuffer[1] = {
|
_lightsBuffer[1] = {
|
||||||
simd::normalize(simd::float4{ -0.8f, 0.4f, -1.0f, 0.0f }),
|
simd::normalize(simd::float4{ -0.8f, 0.4f, -1.0f, 0.0f }),
|
||||||
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
||||||
{ 0.5f, 0.5f, 0.5f, 1.0f },
|
{ 0.5f, 0.5f, 0.5f, 1.0f },
|
||||||
{ 0.8f, 0.8f, 0.8f, 1.0f }
|
{ 0.8f, 0.8f, 0.8f, 1.0f }
|
||||||
};
|
};
|
||||||
|
|
||||||
_lightsBuffer.markModified();
|
_lightsBuffer.markModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,21 +32,22 @@
|
|||||||
@protocol MTLDevice;
|
@protocol MTLDevice;
|
||||||
@protocol MTLCommandQueue;
|
@protocol MTLCommandQueue;
|
||||||
|
|
||||||
namespace OpenSubdiv
|
namespace OpenSubdiv {
|
||||||
{
|
namespace OPENSUBDIV_VERSION {
|
||||||
namespace OPENSUBDIV_VERSION
|
|
||||||
{
|
namespace Osd {
|
||||||
namespace Osd
|
|
||||||
{
|
class MTLContext {
|
||||||
class MTLContext
|
public:
|
||||||
{
|
id<MTLDevice> device = nullptr;
|
||||||
public:
|
id<MTLCommandQueue> commandQueue = nullptr;
|
||||||
id<MTLDevice> device = nullptr;
|
};
|
||||||
id<MTLCommandQueue> commandQueue = nullptr;
|
|
||||||
};
|
} // end namespace Osd
|
||||||
}
|
|
||||||
}
|
} // end namespace OPENSUBDIV_VERSION
|
||||||
using namespace OPENSUBDIV_VERSION;
|
using namespace OPENSUBDIV_VERSION;
|
||||||
}
|
|
||||||
|
} // end namespace OpenSubdiv
|
||||||
|
|
||||||
#endif //OPENSUBDIV3_OSD_MTL_COMMON_H
|
#endif //OPENSUBDIV3_OSD_MTL_COMMON_H
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,8 +34,6 @@
|
|||||||
#include "../far/stencilTable.h"
|
#include "../far/stencilTable.h"
|
||||||
#include "../far/error.h"
|
#include "../far/error.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define PARAMETER_BUFFER_INDEX 0
|
#define PARAMETER_BUFFER_INDEX 0
|
||||||
#define SIZES_BUFFER_INDEX 1
|
#define SIZES_BUFFER_INDEX 1
|
||||||
#define OFFSETS_BUFFER_INDEX 2
|
#define OFFSETS_BUFFER_INDEX 2
|
||||||
@ -141,73 +139,73 @@ using namespace Osd;
|
|||||||
MTLStencilTable::MTLStencilTable(Far::StencilTable const *stencilTable,
|
MTLStencilTable::MTLStencilTable(Far::StencilTable const *stencilTable,
|
||||||
MTLContext* context)
|
MTLContext* context)
|
||||||
{
|
{
|
||||||
assert(context != nil);
|
assert(context != nil);
|
||||||
assert(context->device != nil && context->commandQueue != nil);
|
assert(context->device != nil && context->commandQueue != nil);
|
||||||
|
|
||||||
_numStencils = stencilTable->GetNumStencils();
|
_numStencils = stencilTable->GetNumStencils();
|
||||||
if (_numStencils > 0)
|
if (_numStencils > 0)
|
||||||
{
|
{
|
||||||
auto sizes = stencilTable->GetSizes();
|
auto sizes = stencilTable->GetSizes();
|
||||||
|
|
||||||
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
|
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
|
||||||
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
|
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
|
||||||
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
|
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
|
||||||
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
|
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
|
||||||
|
|
||||||
_sizesBuffer.label = @"StencilTable Sizes";
|
_sizesBuffer.label = @"StencilTable Sizes";
|
||||||
_offsetsBuffer.label = @"StencilTable Offsets";
|
_offsetsBuffer.label = @"StencilTable Offsets";
|
||||||
_indicesBuffer.label = @"StencilTable Indices";
|
_indicesBuffer.label = @"StencilTable Indices";
|
||||||
_weightsBuffer.label = @"StencilTable Weights";
|
_weightsBuffer.label = @"StencilTable Weights";
|
||||||
}
|
}
|
||||||
|
|
||||||
_duWeightsBuffer = nil;
|
_duWeightsBuffer = nil;
|
||||||
_dvWeightsBuffer = nil;
|
_dvWeightsBuffer = nil;
|
||||||
_duuWeightsBuffer = nil;
|
_duuWeightsBuffer = nil;
|
||||||
_duvWeightsBuffer = nil;
|
_duvWeightsBuffer = nil;
|
||||||
_dvvWeightsBuffer = nil;
|
_dvvWeightsBuffer = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLStencilTable::MTLStencilTable(Far::LimitStencilTable const *stencilTable,
|
MTLStencilTable::MTLStencilTable(Far::LimitStencilTable const *stencilTable,
|
||||||
MTLContext* context)
|
MTLContext* context)
|
||||||
{
|
{
|
||||||
assert(context != nil);
|
assert(context != nil);
|
||||||
assert(context->device != nil && context->commandQueue != nil);
|
assert(context->device != nil && context->commandQueue != nil);
|
||||||
|
|
||||||
_numStencils = stencilTable->GetNumStencils();
|
|
||||||
if (_numStencils > 0)
|
|
||||||
{
|
|
||||||
auto sizes = stencilTable->GetSizes();
|
|
||||||
|
|
||||||
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
|
_numStencils = stencilTable->GetNumStencils();
|
||||||
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
|
if (_numStencils > 0)
|
||||||
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
|
{
|
||||||
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
|
auto sizes = stencilTable->GetSizes();
|
||||||
_duWeightsBuffer = createBuffer(stencilTable->GetDuWeights(), context);
|
|
||||||
_dvWeightsBuffer = createBuffer(stencilTable->GetDvWeights(), context);
|
|
||||||
_duuWeightsBuffer = createBuffer(stencilTable->GetDuuWeights(), context);
|
|
||||||
_duvWeightsBuffer = createBuffer(stencilTable->GetDuvWeights(), context);
|
|
||||||
_dvvWeightsBuffer = createBuffer(stencilTable->GetDvvWeights(), context);
|
|
||||||
|
|
||||||
_sizesBuffer.label = @"StencilTable Sizes";
|
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
|
||||||
_offsetsBuffer.label = @"StencilTable Offsets";
|
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
|
||||||
_indicesBuffer.label = @"StencilTable Indices";
|
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
|
||||||
_weightsBuffer.label = @"StencilTable Weights";
|
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
|
||||||
if (_duWeightsBuffer) {
|
_duWeightsBuffer = createBuffer(stencilTable->GetDuWeights(), context);
|
||||||
_duWeightsBuffer.label = @"StencilTable duWeights";
|
_dvWeightsBuffer = createBuffer(stencilTable->GetDvWeights(), context);
|
||||||
|
_duuWeightsBuffer = createBuffer(stencilTable->GetDuuWeights(), context);
|
||||||
|
_duvWeightsBuffer = createBuffer(stencilTable->GetDuvWeights(), context);
|
||||||
|
_dvvWeightsBuffer = createBuffer(stencilTable->GetDvvWeights(), context);
|
||||||
|
|
||||||
|
_sizesBuffer.label = @"StencilTable Sizes";
|
||||||
|
_offsetsBuffer.label = @"StencilTable Offsets";
|
||||||
|
_indicesBuffer.label = @"StencilTable Indices";
|
||||||
|
_weightsBuffer.label = @"StencilTable Weights";
|
||||||
|
if (_duWeightsBuffer) {
|
||||||
|
_duWeightsBuffer.label = @"StencilTable duWeights";
|
||||||
|
}
|
||||||
|
if (_dvWeightsBuffer) {
|
||||||
|
_dvWeightsBuffer.label = @"StencilTable dvWeights";
|
||||||
|
}
|
||||||
|
if (_duuWeightsBuffer) {
|
||||||
|
_duuWeightsBuffer.label = @"StencilTable duuWeights";
|
||||||
|
}
|
||||||
|
if (_duvWeightsBuffer) {
|
||||||
|
_duvWeightsBuffer.label = @"StencilTable duvWeights";
|
||||||
|
}
|
||||||
|
if (_dvvWeightsBuffer) {
|
||||||
|
_dvvWeightsBuffer.label = @"StencilTable dvvWeights";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_dvWeightsBuffer) {
|
|
||||||
_dvWeightsBuffer.label = @"StencilTable dvWeights";
|
|
||||||
}
|
|
||||||
if (_duuWeightsBuffer) {
|
|
||||||
_duuWeightsBuffer.label = @"StencilTable duuWeights";
|
|
||||||
}
|
|
||||||
if (_duvWeightsBuffer) {
|
|
||||||
_duvWeightsBuffer.label = @"StencilTable duvWeights";
|
|
||||||
}
|
|
||||||
if (_dvvWeightsBuffer) {
|
|
||||||
_dvvWeightsBuffer.label = @"StencilTable dvvWeights";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLStencilTable::~MTLStencilTable() {}
|
MTLStencilTable::~MTLStencilTable() {}
|
||||||
@ -217,20 +215,20 @@ MTLComputeEvaluator *MTLComputeEvaluator::Create(
|
|||||||
BufferDescriptor const &duDesc, BufferDescriptor const &dvDesc,
|
BufferDescriptor const &duDesc, BufferDescriptor const &dvDesc,
|
||||||
MTLContext* context)
|
MTLContext* context)
|
||||||
{
|
{
|
||||||
assert(context != nil);
|
assert(context != nil);
|
||||||
assert(context->device != nil && context->commandQueue != nil);
|
assert(context->device != nil && context->commandQueue != nil);
|
||||||
|
|
||||||
auto instance = new MTLComputeEvaluator();
|
auto instance = new MTLComputeEvaluator();
|
||||||
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
|
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
|
||||||
BufferDescriptor(),
|
BufferDescriptor(),
|
||||||
BufferDescriptor(),
|
BufferDescriptor(),
|
||||||
BufferDescriptor(),
|
BufferDescriptor(),
|
||||||
context))
|
context))
|
||||||
return instance;
|
return instance;
|
||||||
|
|
||||||
delete instance;
|
delete instance;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLComputeEvaluator *MTLComputeEvaluator::Create(
|
MTLComputeEvaluator *MTLComputeEvaluator::Create(
|
||||||
@ -239,17 +237,18 @@ MTLComputeEvaluator *MTLComputeEvaluator::Create(
|
|||||||
BufferDescriptor const &duuDesc, BufferDescriptor const &duvDesc, BufferDescriptor const &dvvDesc,
|
BufferDescriptor const &duuDesc, BufferDescriptor const &duvDesc, BufferDescriptor const &dvvDesc,
|
||||||
MTLContext* context)
|
MTLContext* context)
|
||||||
{
|
{
|
||||||
assert(context != nil);
|
assert(context != nil);
|
||||||
assert(context->device != nil && context->commandQueue != nil);
|
assert(context->device != nil && context->commandQueue != nil);
|
||||||
|
|
||||||
auto instance = new MTLComputeEvaluator();
|
auto instance = new MTLComputeEvaluator();
|
||||||
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
|
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
|
||||||
duuDesc, duvDesc, dvvDesc, context))
|
duuDesc, duvDesc, dvvDesc, context)) {
|
||||||
return instance;
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
delete instance;
|
delete instance;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MTLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
|
bool MTLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
|
||||||
@ -321,7 +320,7 @@ bool MTLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
|
|||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
[compileOptions release];
|
[compileOptions release];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!_computeLibrary)
|
if (!_computeLibrary)
|
||||||
{
|
{
|
||||||
Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling MTL Shader: %s\n",
|
Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling MTL Shader: %s\n",
|
||||||
@ -332,13 +331,12 @@ bool MTLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
|
|||||||
auto evalStencilsFunction = [_computeLibrary newFunctionWithName:@"eval_stencils"];
|
auto evalStencilsFunction = [_computeLibrary newFunctionWithName:@"eval_stencils"];
|
||||||
_evalStencils =
|
_evalStencils =
|
||||||
[context->device newComputePipelineStateWithFunction:evalStencilsFunction
|
[context->device newComputePipelineStateWithFunction:evalStencilsFunction
|
||||||
|
|
||||||
error:&err];
|
error:&err];
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
[evalStencilsFunction release];
|
[evalStencilsFunction release];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!_evalStencils)
|
if (!_evalStencils)
|
||||||
{
|
{
|
||||||
Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling MTL Pipeline eval_stencils: %s\n",
|
Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling MTL Pipeline eval_stencils: %s\n",
|
||||||
@ -350,11 +348,11 @@ bool MTLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
|
|||||||
_evalPatches =
|
_evalPatches =
|
||||||
[context->device newComputePipelineStateWithFunction:evalPatchesFunction
|
[context->device newComputePipelineStateWithFunction:evalPatchesFunction
|
||||||
error:&err];
|
error:&err];
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
[evalPatchesFunction release];
|
[evalPatchesFunction release];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!_evalPatches)
|
if (!_evalPatches)
|
||||||
{
|
{
|
||||||
Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling MTL Pipeline eval_patches: %s\n",
|
Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling MTL Pipeline eval_patches: %s\n",
|
||||||
@ -444,7 +442,7 @@ bool MTLComputeEvaluator::EvalStencils(
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
assert(context != nullptr);
|
assert(context != nullptr);
|
||||||
|
|
||||||
auto device = context->device;
|
auto device = context->device;
|
||||||
auto commandQueue = context->commandQueue;
|
auto commandQueue = context->commandQueue;
|
||||||
|
|
||||||
@ -556,7 +554,7 @@ MTLComputeEvaluator::EvalPatches(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert(context != nullptr);
|
assert(context != nullptr);
|
||||||
|
|
||||||
auto device = context->device;
|
auto device = context->device;
|
||||||
auto commandQueue = context->commandQueue;
|
auto commandQueue = context->commandQueue;
|
||||||
|
|
||||||
@ -609,5 +607,6 @@ MTLComputeEvaluator::EvalPatches(
|
|||||||
}
|
}
|
||||||
|
|
||||||
} //end namespace Osd
|
} //end namespace Osd
|
||||||
|
|
||||||
} //end namespace OPENSUBDIV_VERSION
|
} //end namespace OPENSUBDIV_VERSION
|
||||||
} //end namespace OpenSubdiv
|
} //end namespace OpenSubdiv
|
||||||
|
@ -315,6 +315,4 @@ kernel void eval_patches(
|
|||||||
if(args.dvvDesc.y > 0)
|
if(args.dvvDesc.y > 0)
|
||||||
writeDvv(current, dvv, dvvDerivativeBuffer, args);
|
writeDvv(current, dvv, dvvDerivativeBuffer, args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,58 +33,60 @@
|
|||||||
@protocol MTLDevice;
|
@protocol MTLDevice;
|
||||||
@protocol MTLBuffer;
|
@protocol MTLBuffer;
|
||||||
|
|
||||||
namespace OpenSubdiv
|
namespace OpenSubdiv {
|
||||||
|
namespace OPENSUBDIV_VERSION {
|
||||||
|
|
||||||
|
namespace Osd {
|
||||||
|
|
||||||
|
class MTLLegacyGregoryPatchTable
|
||||||
|
: private NonCopyable<MTLLegacyGregoryPatchTable>
|
||||||
{
|
{
|
||||||
namespace OPENSUBDIV_VERSION
|
public:
|
||||||
|
~MTLLegacyGregoryPatchTable();
|
||||||
|
|
||||||
|
template<typename DEVICE_CONTEXT>
|
||||||
|
static MTLLegacyGregoryPatchTable* Create(Far::PatchTable const* farPatchTable, DEVICE_CONTEXT context) {
|
||||||
|
return Create(farPatchTable, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MTLLegacyGregoryPatchTable* Create(Far::PatchTable const* farPatchTable, MTLContext* context);
|
||||||
|
|
||||||
|
void UpdateVertexBuffer(id<MTLBuffer> vbo, int numVertices, int numVertexElements, MTLContext* context);
|
||||||
|
|
||||||
|
id<MTLBuffer> GetVertexBuffer() const
|
||||||
{
|
{
|
||||||
namespace Osd
|
return _vertexBuffer;
|
||||||
{
|
}
|
||||||
class MTLLegacyGregoryPatchTable
|
|
||||||
: private NonCopyable<MTLLegacyGregoryPatchTable>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~MTLLegacyGregoryPatchTable();
|
|
||||||
|
|
||||||
template<typename DEVICE_CONTEXT>
|
id<MTLBuffer> GetVertexValenceBuffer() const
|
||||||
static MTLLegacyGregoryPatchTable* Create(Far::PatchTable const* farPatchTable, DEVICE_CONTEXT context) {
|
{
|
||||||
return Create(farPatchTable, context);
|
return _vertexValenceBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MTLLegacyGregoryPatchTable* Create(Far::PatchTable const* farPatchTable, MTLContext* context);
|
id<MTLBuffer> GetQuadOffsetsBuffer() const
|
||||||
|
{
|
||||||
|
return _quadOffsetsBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateVertexBuffer(id<MTLBuffer> vbo, int numVertices, int numVertexElements, MTLContext* context);
|
int GetQuadOffsetsBase(Far::PatchDescriptor::Type type)
|
||||||
|
{
|
||||||
|
if(type == Far::PatchDescriptor::GREGORY_BOUNDARY)
|
||||||
|
return _quadOffsetsBase[1];
|
||||||
|
return _quadOffsetsBase[0];
|
||||||
|
}
|
||||||
|
|
||||||
id<MTLBuffer> GetVertexBuffer() const
|
private:
|
||||||
{
|
id<MTLBuffer> _vertexBuffer;
|
||||||
return _vertexBuffer;
|
id<MTLBuffer> _vertexValenceBuffer;
|
||||||
}
|
id<MTLBuffer> _quadOffsetsBuffer;
|
||||||
|
int _quadOffsetsBase[2];
|
||||||
|
};
|
||||||
|
|
||||||
id<MTLBuffer> GetVertexValenceBuffer() const
|
} //end namespace Osd
|
||||||
{
|
|
||||||
return _vertexValenceBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
id<MTLBuffer> GetQuadOffsetsBuffer() const
|
} //end namespace OPENSUBDIV_VERSION
|
||||||
{
|
using namespace OPENSUBDIV_VERSION;
|
||||||
return _quadOffsetsBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetQuadOffsetsBase(Far::PatchDescriptor::Type type)
|
|
||||||
{
|
|
||||||
if(type == Far::PatchDescriptor::GREGORY_BOUNDARY)
|
|
||||||
return _quadOffsetsBase[1];
|
|
||||||
return _quadOffsetsBase[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
id<MTLBuffer> _vertexBuffer;
|
|
||||||
id<MTLBuffer> _vertexValenceBuffer;
|
|
||||||
id<MTLBuffer> _quadOffsetsBuffer;
|
|
||||||
int _quadOffsetsBase[2];
|
|
||||||
};
|
|
||||||
} //end namespace Osd
|
|
||||||
} //end namespace OPENSUBDIV_VERSION
|
|
||||||
using namespace OPENSUBDIV_VERSION;
|
|
||||||
} //end namespace OpenSuddiv
|
} //end namespace OpenSuddiv
|
||||||
|
|
||||||
#endif // OPENSUBDIV3_OSD_MTL_LEGACY_GREGORY_PATCH_TABLE_H
|
#endif // OPENSUBDIV3_OSD_MTL_LEGACY_GREGORY_PATCH_TABLE_H
|
||||||
|
@ -96,5 +96,6 @@ void MTLLegacyGregoryPatchTable::UpdateVertexBuffer(id<MTLBuffer> vbo, int numVe
|
|||||||
}
|
}
|
||||||
|
|
||||||
} //end namespace Osd
|
} //end namespace Osd
|
||||||
|
|
||||||
} //end namespace OPENSUBDIV_VERSION
|
} //end namespace OPENSUBDIV_VERSION
|
||||||
} //end namespace OpenSubdiv
|
} //end namespace OpenSubdiv
|
||||||
|
@ -30,17 +30,18 @@
|
|||||||
#include "../osd/mtlPatchTable.h"
|
#include "../osd/mtlPatchTable.h"
|
||||||
|
|
||||||
|
|
||||||
namespace OpenSubdiv
|
namespace OpenSubdiv {
|
||||||
{
|
namespace OPENSUBDIV_VERSION {
|
||||||
namespace OPENSUBDIV_VERSION
|
|
||||||
{
|
namespace Osd {
|
||||||
namespace Osd
|
|
||||||
{
|
typedef MeshInterface<MTLPatchTable> MTLMeshInterface;
|
||||||
typedef MeshInterface<MTLPatchTable> MTLMeshInterface;
|
|
||||||
} // end namespace Osd
|
} // end namespace Osd
|
||||||
} // end namespace OPENSUBDIV_VERSION
|
|
||||||
|
} // end namespace OPENSUBDIV_VERSION
|
||||||
|
using namespace OPENSUBDIV_VERSION;
|
||||||
|
|
||||||
using namespace OPENSUBDIV_VERSION;
|
|
||||||
} // end namespace OpenSubdiv
|
} // end namespace OpenSubdiv
|
||||||
|
|
||||||
#endif // OPENSUBDIV3_OSD_MTL_MESH_H
|
#endif // OPENSUBDIV3_OSD_MTL_MESH_H
|
||||||
|
@ -29,23 +29,23 @@
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerVertex(
|
void OsdComputePerVertex(
|
||||||
float4 vertexPosition,
|
float4 vertexPosition,
|
||||||
threadgroup HullVertex& hullVertex,
|
threadgroup HullVertex& hullVertex,
|
||||||
int vertexId,
|
int vertexId,
|
||||||
float4x4 ModelViewProjectionMatrix,
|
float4x4 ModelViewProjectionMatrix,
|
||||||
OsdPatchParamBufferSet osdBuffers
|
OsdPatchParamBufferSet osdBuffers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
hullVertex.position = vertexPosition;
|
hullVertex.position = vertexPosition;
|
||||||
#if OSD_ENABLE_PATCH_CULL
|
#if OSD_ENABLE_PATCH_CULL
|
||||||
float4 clipPos = mul(ModelViewProjectionMatrix, vertexPosition);
|
float4 clipPos = mul(ModelViewProjectionMatrix, vertexPosition);
|
||||||
short3 clip0 = short3(clipPos.x < clipPos.w,
|
short3 clip0 = short3(clipPos.x < clipPos.w,
|
||||||
clipPos.y < clipPos.w,
|
clipPos.y < clipPos.w,
|
||||||
clipPos.z < clipPos.w);
|
clipPos.z < clipPos.w);
|
||||||
short3 clip1 = short3(clipPos.x > -clipPos.w,
|
short3 clip1 = short3(clipPos.x > -clipPos.w,
|
||||||
clipPos.y > -clipPos.w,
|
clipPos.y > -clipPos.w,
|
||||||
clipPos.z > -clipPos.w);
|
clipPos.z > -clipPos.w);
|
||||||
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
|
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,16 +54,16 @@ void OsdComputePerVertex(
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerPatchBSplineFactors(
|
void OsdComputePerPatchBSplineFactors(
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
float tessLevel,
|
float tessLevel,
|
||||||
float4x4 projectionMatrix,
|
float4x4 projectionMatrix,
|
||||||
float4x4 modelViewMatrix,
|
float4x4 modelViewMatrix,
|
||||||
device OsdPerPatchVertexBezier* patch
|
device OsdPerPatchVertexBezier* patch
|
||||||
#if !USE_PTVS_FACTORS
|
#if !USE_PTVS_FACTORS
|
||||||
,device OsdPerPatchTessFactors& patchFactors
|
,device OsdPerPatchTessFactors& patchFactors
|
||||||
#endif
|
#endif
|
||||||
,device MTLQuadTessellationFactorsHalf& quadFactors
|
,device MTLQuadTessellationFactorsHalf& quadFactors
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
float4 tessLevelOuter = float4(0,0,0,0);
|
float4 tessLevelOuter = float4(0,0,0,0);
|
||||||
float2 tessLevelInner = float2(0,0);
|
float2 tessLevelInner = float2(0,0);
|
||||||
@ -72,8 +72,8 @@ void OsdComputePerPatchBSplineFactors(
|
|||||||
|
|
||||||
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
|
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||||
OsdGetTessLevelsAdaptiveLimitPoints(
|
OsdGetTessLevelsAdaptiveLimitPoints(
|
||||||
tessLevel,
|
tessLevel,
|
||||||
projectionMatrix,
|
projectionMatrix,
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
patch,
|
patch,
|
||||||
patchParam,
|
patchParam,
|
||||||
@ -84,8 +84,8 @@ void OsdComputePerPatchBSplineFactors(
|
|||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
OsdGetTessLevelsUniform(
|
OsdGetTessLevelsUniform(
|
||||||
tessLevel,
|
tessLevel,
|
||||||
patchParam,
|
patchParam,
|
||||||
tessLevelOuter,
|
tessLevelOuter,
|
||||||
tessLevelInner,
|
tessLevelInner,
|
||||||
tessOuterLo,
|
tessOuterLo,
|
||||||
@ -106,27 +106,27 @@ void OsdComputePerPatchBSplineFactors(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OsdComputePerPatchFactors(
|
void OsdComputePerPatchFactors(
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
float tessLevel,
|
float tessLevel,
|
||||||
unsigned patchID,
|
unsigned patchID,
|
||||||
float4x4 projectionMatrix,
|
float4x4 projectionMatrix,
|
||||||
float4x4 modelViewMatrix,
|
float4x4 modelViewMatrix,
|
||||||
OsdPatchParamBufferSet osdBuffer,
|
OsdPatchParamBufferSet osdBuffer,
|
||||||
threadgroup PatchVertexType* patchVertices,
|
threadgroup PatchVertexType* patchVertices,
|
||||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
OsdComputePerPatchBSplineFactors(
|
OsdComputePerPatchBSplineFactors(
|
||||||
patchParam,
|
patchParam,
|
||||||
tessLevel,
|
tessLevel,
|
||||||
projectionMatrix,
|
projectionMatrix,
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
osdBuffer.perPatchVertexBuffer + patchID * CONTROL_POINTS_PER_PATCH,
|
osdBuffer.perPatchVertexBuffer + patchID * CONTROL_POINTS_PER_PATCH,
|
||||||
#if !USE_PTVS_FACTORS
|
#if !USE_PTVS_FACTORS
|
||||||
osdBuffer.patchTessBuffer[patchID],
|
osdBuffer.patchTessBuffer[patchID],
|
||||||
#endif
|
#endif
|
||||||
quadFactors
|
quadFactors
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@ -134,15 +134,16 @@ void OsdComputePerPatchFactors(
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerPatchVertex(
|
void OsdComputePerPatchVertex(
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
unsigned ID,
|
unsigned ID,
|
||||||
unsigned PrimitiveID,
|
unsigned PrimitiveID,
|
||||||
unsigned ControlID,
|
unsigned ControlID,
|
||||||
threadgroup PatchVertexType* patchVertices,
|
threadgroup PatchVertexType* patchVertices,
|
||||||
OsdPatchParamBufferSet osdBuffers
|
OsdPatchParamBufferSet osdBuffers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
OsdComputePerPatchVertexBSpline(patchParam, ID, patchVertices, osdBuffers.perPatchVertexBuffer[ControlID]);
|
OsdComputePerPatchVertexBSpline(patchParam, ID,
|
||||||
|
patchVertices, osdBuffers.perPatchVertexBuffer[ControlID]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@ -151,20 +152,22 @@ void OsdComputePerPatchVertex(
|
|||||||
|
|
||||||
template<typename PerPatchVertexBezier>
|
template<typename PerPatchVertexBezier>
|
||||||
OsdPatchVertex ds_regular_patches(
|
OsdPatchVertex ds_regular_patches(
|
||||||
const float TessLevel,
|
const float TessLevel,
|
||||||
#if !USE_PTVS_FACTORS
|
#if !USE_PTVS_FACTORS
|
||||||
float4 tessOuterHi,
|
float4 tessOuterHi,
|
||||||
float4 tessOuterLo,
|
float4 tessOuterLo,
|
||||||
#endif
|
#endif
|
||||||
PerPatchVertexBezier cv,
|
PerPatchVertexBezier cv,
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
float2 domainCoord)
|
float2 domainCoord
|
||||||
|
)
|
||||||
{
|
{
|
||||||
OsdPatchVertex output;
|
OsdPatchVertex output;
|
||||||
|
|
||||||
float3 P, dPu, dPv;
|
float3 P, dPu, dPv;
|
||||||
float3 N, dNu, dNv;
|
float3 N, dNu, dNv;
|
||||||
float2 vSegments;
|
float2 vSegments;
|
||||||
|
|
||||||
#if !USE_PTVS_FACTORS
|
#if !USE_PTVS_FACTORS
|
||||||
float2 UV = OsdGetTessParameterization(domainCoord,
|
float2 UV = OsdGetTessParameterization(domainCoord,
|
||||||
tessOuterLo,
|
tessOuterLo,
|
||||||
@ -183,7 +186,6 @@ OsdPatchVertex ds_regular_patches(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
OsdEvalPatchBezier(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv, vSegments);
|
OsdEvalPatchBezier(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv, vSegments);
|
||||||
|
|
||||||
output.normal = N;
|
output.normal = N;
|
||||||
output.tangent = dPu;
|
output.tangent = dPu;
|
||||||
output.bitangent = dPv;
|
output.bitangent = dPv;
|
||||||
@ -204,35 +206,35 @@ OsdPatchVertex ds_regular_patches(
|
|||||||
template<typename PerPatchVertexBezier>
|
template<typename PerPatchVertexBezier>
|
||||||
#endif
|
#endif
|
||||||
OsdPatchVertex OsdComputePatch(
|
OsdPatchVertex OsdComputePatch(
|
||||||
float tessLevel,
|
float tessLevel,
|
||||||
float2 domainCoord,
|
float2 domainCoord,
|
||||||
unsigned patchID,
|
unsigned patchID,
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
PerPatchVertexBezier osdPatch
|
PerPatchVertexBezier osdPatch
|
||||||
#else
|
#else
|
||||||
OsdVertexBufferSet osdBuffers
|
OsdVertexBufferSet osdBuffers
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ds_regular_patches(
|
return ds_regular_patches(
|
||||||
tessLevel,
|
tessLevel,
|
||||||
#if !USE_PTVS_FACTORS
|
#if !USE_PTVS_FACTORS
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
osdPatch.tessOuterHi,
|
osdPatch.tessOuterHi,
|
||||||
osdPatch.tessOuterLo,
|
osdPatch.tessOuterLo,
|
||||||
#else
|
#else
|
||||||
osdBuffers.patchTessBuffer[patchID].tessOuterHi,
|
osdBuffers.patchTessBuffer[patchID].tessOuterHi,
|
||||||
osdBuffers.patchTessBuffer[patchID].tessOuterLo,
|
osdBuffers.patchTessBuffer[patchID].tessOuterLo,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
osdPatch.cv,
|
osdPatch.cv,
|
||||||
osdPatch.patchParam,
|
osdPatch.patchParam,
|
||||||
#else
|
#else
|
||||||
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
||||||
osdBuffers.patchParamBuffer[patchID],
|
osdBuffers.patchParamBuffer[patchID],
|
||||||
#endif
|
#endif
|
||||||
domainCoord
|
domainCoord
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ static_assert(sizeof(OsdInputVertexType) > 0, "OsdInputVertexType must be define
|
|||||||
#if OSD_IS_ADAPTIVE
|
#if OSD_IS_ADAPTIVE
|
||||||
#if OSD_PATCH_GREGORY_BASIS
|
#if OSD_PATCH_GREGORY_BASIS
|
||||||
constant constexpr unsigned IndexLookupStride = 5;
|
constant constexpr unsigned IndexLookupStride = 5;
|
||||||
#else
|
#else
|
||||||
constant constexpr unsigned IndexLookupStride = 1;
|
constant constexpr unsigned IndexLookupStride = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ static_assert(OSD_ENABLE_SCREENSPACE_TESSELLATION && (OSD_FRACTIONAL_ODD_SPACING
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Adjustments to the UV reparameterization can be defined here.
|
//Adjustments to the UV reparameterization can be defined here.
|
||||||
#ifndef OSD_UV_CORRECTION
|
#ifndef OSD_UV_CORRECTION
|
||||||
#define OSD_UV_CORRECTION
|
#define OSD_UV_CORRECTION
|
||||||
#endif
|
#endif
|
||||||
@ -147,7 +147,7 @@ struct HullVertex {
|
|||||||
|
|
||||||
void SetPosition(float3 v) threadgroup
|
void SetPosition(float3 v) threadgroup
|
||||||
{
|
{
|
||||||
position.xyz = v;
|
position.xyz = v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -204,36 +204,35 @@ using PerPatchVertexType = OsdInputVertexType;
|
|||||||
//Shared buffers used by OSD that are common to all kernels
|
//Shared buffers used by OSD that are common to all kernels
|
||||||
struct OsdPatchParamBufferSet
|
struct OsdPatchParamBufferSet
|
||||||
{
|
{
|
||||||
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
||||||
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
||||||
|
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
||||||
|
|
||||||
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX)]];
|
||||||
|
|
||||||
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX)]];
|
#if !USE_PTVS_FACTORS
|
||||||
|
|
||||||
#if !USE_PTVS_FACTORS
|
|
||||||
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
#if OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||||
const device int* quadOffsetBuffer [[buffer(OSD_QUADOFFSET_BUFFER_INDEX)]];
|
const device int* quadOffsetBuffer [[buffer(OSD_QUADOFFSET_BUFFER_INDEX)]];
|
||||||
const device int* valenceBuffer [[buffer(OSD_VALENCE_BUFFER_INDEX)]];
|
const device int* valenceBuffer [[buffer(OSD_VALENCE_BUFFER_INDEX)]];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const constant unsigned& kernelExecutionLimit [[buffer(OSD_KERNELLIMIT_BUFFER_INDEX)]];
|
const constant unsigned& kernelExecutionLimit [[buffer(OSD_KERNELLIMIT_BUFFER_INDEX)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
//Shared buffers used by OSD that are common to all PTVS implementations
|
//Shared buffers used by OSD that are common to all PTVS implementations
|
||||||
struct OsdVertexBufferSet
|
struct OsdVertexBufferSet
|
||||||
{
|
{
|
||||||
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
||||||
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
||||||
|
|
||||||
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
||||||
|
|
||||||
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX)]];
|
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX)]];
|
||||||
|
|
||||||
#if !USE_PTVS_FACTORS
|
#if !USE_PTVS_FACTORS
|
||||||
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -323,11 +322,11 @@ OsdUnivar4x4(float u, thread float* B)
|
|||||||
{
|
{
|
||||||
float t = u;
|
float t = u;
|
||||||
float s = 1.0f - u;
|
float s = 1.0f - u;
|
||||||
|
|
||||||
float A0 = s * s;
|
float A0 = s * s;
|
||||||
float A1 = 2 * s * t;
|
float A1 = 2 * s * t;
|
||||||
float A2 = t * t;
|
float A2 = t * t;
|
||||||
|
|
||||||
B[0] = s * A0;
|
B[0] = s * A0;
|
||||||
B[1] = t * A0 + s * A1;
|
B[1] = t * A0 + s * A1;
|
||||||
B[2] = t * A1 + s * A2;
|
B[2] = t * A1 + s * A2;
|
||||||
@ -413,9 +412,9 @@ OsdEvalBezier(float3 cp[16], float2 uv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OsdCullPerPatchVertex(
|
bool OsdCullPerPatchVertex(
|
||||||
threadgroup PatchVertexType* patch,
|
threadgroup PatchVertexType* patch,
|
||||||
float4x4 ModelViewMatrix
|
float4x4 ModelViewMatrix
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if OSD_ENABLE_BACKPATCH_CULL && OSD_PATCH_REGULAR
|
#if OSD_ENABLE_BACKPATCH_CULL && OSD_PATCH_REGULAR
|
||||||
auto v0 = float3(ModelViewMatrix * patch[5].position);
|
auto v0 = float3(ModelViewMatrix * patch[5].position);
|
||||||
@ -529,7 +528,7 @@ template<typename VertexType>
|
|||||||
void
|
void
|
||||||
OsdComputeBSplineBoundaryPoints(threadgroup VertexType* cpt, int3 patchParam)
|
OsdComputeBSplineBoundaryPoints(threadgroup VertexType* cpt, int3 patchParam)
|
||||||
{
|
{
|
||||||
//APPL TODO - multithread this
|
//APPL TODO - multithread this
|
||||||
int boundaryMask = OsdGetPatchBoundaryMask(patchParam);
|
int boundaryMask = OsdGetPatchBoundaryMask(patchParam);
|
||||||
|
|
||||||
if ((boundaryMask & 1) != 0) {
|
if ((boundaryMask & 1) != 0) {
|
||||||
@ -806,9 +805,6 @@ OsdComputeTessLevels(thread float4& tessOuterLo, thread float4& tessOuterHi,
|
|||||||
tessLevelInner[1] = (combinedOuter[0] + combinedOuter[2]) * 0.5;
|
tessLevelInner[1] = (combinedOuter[0] + combinedOuter[2]) * 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float OsdComputeTessLevel(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix, float3 p0, float3 p1)
|
float OsdComputeTessLevel(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix, float3 p0, float3 p1)
|
||||||
{
|
{
|
||||||
// Adaptive factor can be any computation that depends only on arg values.
|
// Adaptive factor can be any computation that depends only on arg values.
|
||||||
@ -841,15 +837,6 @@ OsdGetTessLevelsUniform(const float OsdTessLevel, int3 patchParam,
|
|||||||
float tessLevel = min(OsdTessLevel, ((float)OSD_MAX_TESS_LEVEL / 2)) /
|
float tessLevel = min(OsdTessLevel, ((float)OSD_MAX_TESS_LEVEL / 2)) /
|
||||||
pow(2, refinementLevel - 1.0f);
|
pow(2, refinementLevel - 1.0f);
|
||||||
|
|
||||||
// float tessLevel = min(OsdTessLevel, (float)OSD_MAX_TESS_LEVEL);
|
|
||||||
// if(refinementLevel != 0)
|
|
||||||
// tessLevel /= (1 << (refinementLevel - 1));
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// tessLevel /= pow(2.0, (0 - 1));
|
|
||||||
// tessLevel /= pow(2.0, (refinementLevel - 1));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// tessLevels of transition edge should be clamped to 2.
|
// tessLevels of transition edge should be clamped to 2.
|
||||||
int transitionMask = OsdGetPatchTransitionMask(patchParam);
|
int transitionMask = OsdGetPatchTransitionMask(patchParam);
|
||||||
float4 tessLevelMin = float4(1)
|
float4 tessLevelMin = float4(1)
|
||||||
@ -858,22 +845,17 @@ OsdGetTessLevelsUniform(const float OsdTessLevel, int3 patchParam,
|
|||||||
((transitionMask & 2) >> 1),
|
((transitionMask & 2) >> 1),
|
||||||
((transitionMask & 4) >> 2));
|
((transitionMask & 4) >> 2));
|
||||||
|
|
||||||
// tessLevelMin = (tessLevelMin - 1.0) * 2.0f + 1.0;
|
|
||||||
// tessLevelMin = float4(OsdTessLevel);
|
|
||||||
|
|
||||||
|
|
||||||
tessOuterLo = max(float4(tessLevel,tessLevel,tessLevel,tessLevel),
|
tessOuterLo = max(float4(tessLevel,tessLevel,tessLevel,tessLevel),
|
||||||
tessLevelMin);
|
tessLevelMin);
|
||||||
tessOuterHi = float4(0,0,0,0);
|
tessOuterHi = float4(0,0,0,0);
|
||||||
|
|
||||||
// tessOuterLo.x = refinementLevel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OsdGetTessLevelsRefinedPoints(const float OsdTessLevel,
|
OsdGetTessLevelsRefinedPoints(
|
||||||
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
const float OsdTessLevel,
|
||||||
float3 cp[16], int3 patchParam,
|
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
||||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
float3 cp[16], int3 patchParam,
|
||||||
|
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||||
{
|
{
|
||||||
// Each edge of a transition patch is adjacent to one or two patches
|
// Each edge of a transition patch is adjacent to one or two patches
|
||||||
// at the next refined level of subdivision. We compute the corresponding
|
// at the next refined level of subdivision. We compute the corresponding
|
||||||
@ -985,7 +967,7 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
|
|||||||
tPt = &p12;
|
tPt = &p12;
|
||||||
}
|
}
|
||||||
tessOuterLo[0] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p0, *tPt);
|
tessOuterLo[0] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p0, *tPt);
|
||||||
|
|
||||||
if ((transitionMask & 1) != 0) { // EV01
|
if ((transitionMask & 1) != 0) { // EV01
|
||||||
ev = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 0.0));
|
ev = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 0.0));
|
||||||
|
|
||||||
@ -997,7 +979,7 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
|
|||||||
tPt = &p3;
|
tPt = &p3;
|
||||||
}
|
}
|
||||||
tessOuterLo[1] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p0, *tPt);
|
tessOuterLo[1] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p0, *tPt);
|
||||||
|
|
||||||
if ((transitionMask & 2) != 0) { // EV12
|
if ((transitionMask & 2) != 0) { // EV12
|
||||||
ev = OsdEvalBezier(cpBezier, patchParam, float2(1.0, 0.5));
|
ev = OsdEvalBezier(cpBezier, patchParam, float2(1.0, 0.5));
|
||||||
|
|
||||||
@ -1009,7 +991,7 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
|
|||||||
tPt = &p15;
|
tPt = &p15;
|
||||||
}
|
}
|
||||||
tessOuterLo[2] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p3, *tPt);
|
tessOuterLo[2] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p3, *tPt);
|
||||||
|
|
||||||
if ((transitionMask & 4) != 0) { // EV23
|
if ((transitionMask & 4) != 0) { // EV23
|
||||||
ev = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 1.0));
|
ev = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 1.0));
|
||||||
|
|
||||||
@ -1037,8 +1019,6 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
|
|||||||
float3 c12 = miniMul(OsdModelViewMatrix, cpBezier[12].P);
|
float3 c12 = miniMul(OsdModelViewMatrix, cpBezier[12].P);
|
||||||
float3 c03 = miniMul(OsdModelViewMatrix, cpBezier[3].P);
|
float3 c03 = miniMul(OsdModelViewMatrix, cpBezier[3].P);
|
||||||
float3 c15 = miniMul(OsdModelViewMatrix, cpBezier[15].P);
|
float3 c15 = miniMul(OsdModelViewMatrix, cpBezier[15].P);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ((transitionMask & 8) != 0) {
|
if ((transitionMask & 8) != 0) {
|
||||||
tessOuterLo[0] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,c00, p0);
|
tessOuterLo[0] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,c00, p0);
|
||||||
@ -1068,44 +1048,55 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OsdGetTessLevelsUniform(const float OsdTessLevel, int3 patchParam,
|
OsdGetTessLevelsUniform(
|
||||||
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
const float OsdTessLevel, int3 patchParam,
|
||||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
||||||
|
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||||
{
|
{
|
||||||
OsdGetTessLevelsUniform(OsdTessLevel, patchParam, tessOuterLo, tessOuterHi);
|
OsdGetTessLevelsUniform(OsdTessLevel, patchParam, tessOuterLo, tessOuterHi);
|
||||||
OsdComputeTessLevels(tessOuterLo, tessOuterHi, tessLevelOuter, tessLevelInner);
|
OsdComputeTessLevels(tessOuterLo, tessOuterHi, tessLevelOuter, tessLevelInner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OsdGetTessLevelsAdaptiveRefinedPoints(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
OsdGetTessLevelsAdaptiveRefinedPoints(
|
||||||
float3 cpRefined[16], int3 patchParam,
|
const float OsdTessLevel,
|
||||||
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
||||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
float3 cpRefined[16], int3 patchParam,
|
||||||
|
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
||||||
|
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||||
{
|
{
|
||||||
OsdGetTessLevelsRefinedPoints(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix, cpRefined, patchParam, tessOuterLo, tessOuterHi);
|
OsdGetTessLevelsRefinedPoints(
|
||||||
|
OsdTessLevel,
|
||||||
|
OsdProjectionMatrix, OsdModelViewMatrix,
|
||||||
|
cpRefined, patchParam, tessOuterLo, tessOuterHi);
|
||||||
|
|
||||||
OsdComputeTessLevels(tessOuterLo, tessOuterHi,
|
OsdComputeTessLevels(tessOuterLo, tessOuterHi,
|
||||||
tessLevelOuter, tessLevelInner);
|
tessLevelOuter, tessLevelInner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OsdGetTessLevelsAdaptiveLimitPoints(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
OsdGetTessLevelsAdaptiveLimitPoints(
|
||||||
device OsdPerPatchVertexBezier* cpBezier,
|
const float OsdTessLevel,
|
||||||
int3 patchParam,
|
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
||||||
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
device OsdPerPatchVertexBezier* cpBezier, int3 patchParam,
|
||||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
||||||
|
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||||
{
|
{
|
||||||
OsdGetTessLevelsLimitPoints(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix, cpBezier, patchParam, tessOuterLo, tessOuterHi);
|
OsdGetTessLevelsLimitPoints(
|
||||||
|
OsdTessLevel,
|
||||||
|
OsdProjectionMatrix, OsdModelViewMatrix,
|
||||||
|
cpBezier, patchParam, tessOuterLo, tessOuterHi);
|
||||||
|
|
||||||
OsdComputeTessLevels(tessOuterLo, tessOuterHi,
|
OsdComputeTessLevels(tessOuterLo, tessOuterHi,
|
||||||
tessLevelOuter, tessLevelInner);
|
tessLevelOuter, tessLevelInner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OsdGetTessLevels(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
OsdGetTessLevels(
|
||||||
float3 cp0, float3 cp1, float3 cp2, float3 cp3,
|
const float OsdTessLevel,
|
||||||
int3 patchParam,
|
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
|
||||||
thread float4& tessLevelOuter, thread float2& tessLevelInner)
|
float3 cp0, float3 cp1, float3 cp2, float3 cp3, int3 patchParam,
|
||||||
|
thread float4& tessLevelOuter, thread float2& tessLevelInner)
|
||||||
{
|
{
|
||||||
float4 tessOuterLo = float4(0,0,0,0);
|
float4 tessOuterLo = float4(0,0,0,0);
|
||||||
float4 tessOuterHi = float4(0,0,0,0);
|
float4 tessOuterHi = float4(0,0,0,0);
|
||||||
@ -1172,53 +1163,53 @@ float
|
|||||||
OsdGetTessTransitionSplit(float t, float lo, float hi )
|
OsdGetTessTransitionSplit(float t, float lo, float hi )
|
||||||
{
|
{
|
||||||
#if OSD_FRACTIONAL_EVEN_SPACING
|
#if OSD_FRACTIONAL_EVEN_SPACING
|
||||||
float loRoundUp = OsdRoundUpEven(lo);
|
float loRoundUp = OsdRoundUpEven(lo);
|
||||||
float hiRoundUp = OsdRoundUpEven(hi);
|
float hiRoundUp = OsdRoundUpEven(hi);
|
||||||
|
|
||||||
// Convert the parametric t into a segment index along the combined edge.
|
// Convert the parametric t into a segment index along the combined edge.
|
||||||
float ti = round(t * (loRoundUp + hiRoundUp));
|
float ti = round(t * (loRoundUp + hiRoundUp));
|
||||||
|
|
||||||
if (ti <= loRoundUp) {
|
if (ti <= loRoundUp) {
|
||||||
float t0 = ti / loRoundUp;
|
float t0 = ti / loRoundUp;
|
||||||
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
|
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
|
||||||
} else {
|
} else {
|
||||||
float t1 = (ti - loRoundUp) / hiRoundUp;
|
float t1 = (ti - loRoundUp) / hiRoundUp;
|
||||||
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
|
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif OSD_FRACTIONAL_ODD_SPACING
|
#elif OSD_FRACTIONAL_ODD_SPACING
|
||||||
float loRoundUp = OsdRoundUpOdd(lo);
|
float loRoundUp = OsdRoundUpOdd(lo);
|
||||||
float hiRoundUp = OsdRoundUpOdd(hi);
|
float hiRoundUp = OsdRoundUpOdd(hi);
|
||||||
|
|
||||||
// Convert the parametric t into a segment index along the combined edge.
|
// Convert the parametric t into a segment index along the combined edge.
|
||||||
// The +1 below is to account for the extra segment produced by the
|
// The +1 below is to account for the extra segment produced by the
|
||||||
// tessellator since the sum of two odd tess levels will be rounded
|
// tessellator since the sum of two odd tess levels will be rounded
|
||||||
// up by one to the next odd integer tess level.
|
// up by one to the next odd integer tess level.
|
||||||
float ti = (t * (loRoundUp + hiRoundUp + 1));
|
float ti = (t * (loRoundUp + hiRoundUp + 1));
|
||||||
|
|
||||||
OSD_UV_CORRECTION
|
OSD_UV_CORRECTION
|
||||||
|
|
||||||
ti = round(ti);
|
ti = round(ti);
|
||||||
|
|
||||||
if (ti <= loRoundUp) {
|
if (ti <= loRoundUp) {
|
||||||
float t0 = ti / loRoundUp;
|
float t0 = ti / loRoundUp;
|
||||||
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
|
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
|
||||||
} else if (ti > (loRoundUp+1)) {
|
} else if (ti > (loRoundUp+1)) {
|
||||||
float t1 = (ti - (loRoundUp+1)) / hiRoundUp;
|
float t1 = (ti - (loRoundUp+1)) / hiRoundUp;
|
||||||
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
|
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
|
||||||
} else {
|
} else {
|
||||||
return 0.5;
|
return 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else //OSD_FRACTIONAL_ODD_SPACING
|
#else //OSD_FRACTIONAL_ODD_SPACING
|
||||||
// Convert the parametric t into a segment index along the combined edge.
|
// Convert the parametric t into a segment index along the combined edge.
|
||||||
float ti = round(t * (lo + hi));
|
float ti = round(t * (lo + hi));
|
||||||
|
|
||||||
if (ti <= lo) {
|
if (ti <= lo) {
|
||||||
return (ti / lo) * 0.5;
|
return (ti / lo) * 0.5;
|
||||||
} else {
|
} else {
|
||||||
return ((ti - lo) / hi) * 0.5 + 0.5;
|
return ((ti - lo) / hi) * 0.5 + 0.5;
|
||||||
}
|
}
|
||||||
#endif //OSD_FRACTIONAL_ODD_SPACING
|
#endif //OSD_FRACTIONAL_ODD_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1226,28 +1217,21 @@ float2
|
|||||||
OsdGetTessParameterization(float2 uv, float4 tessOuterLo, float4 tessOuterHi)
|
OsdGetTessParameterization(float2 uv, float4 tessOuterLo, float4 tessOuterHi)
|
||||||
{
|
{
|
||||||
float2 UV = uv;
|
float2 UV = uv;
|
||||||
if (UV.x == 0 && tessOuterHi[0] > 0)
|
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||||
{
|
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
} else
|
||||||
}
|
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||||
else if (UV.y == 0 && tessOuterHi[1] > 0)
|
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||||
{
|
} else
|
||||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
if (UV.x == 1 && tessOuterHi[2] > 0) {
|
||||||
}
|
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
|
||||||
else if (UV.x == 1 && tessOuterHi[2] > 0)
|
} else
|
||||||
{
|
if (UV.y == 1 && tessOuterHi[3] > 0) {
|
||||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
|
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
|
||||||
}
|
}
|
||||||
else if (UV.y == 1 && tessOuterHi[3] > 0)
|
|
||||||
{
|
|
||||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return UV;
|
return UV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int4 OsdGetPatchCoord(int3 patchParam)
|
int4 OsdGetPatchCoord(int3 patchParam)
|
||||||
{
|
{
|
||||||
int faceId = OsdGetPatchFaceId(patchParam);
|
int faceId = OsdGetPatchFaceId(patchParam);
|
||||||
@ -1296,7 +1280,7 @@ constant float4x4 Mi(
|
|||||||
float4(0.f, 0.f, 1.f, 0.f)
|
float4(0.f, 0.f, 1.f, 0.f)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
float4x4 OsdComputeMs2(float sharpness, float factor)
|
float4x4 OsdComputeMs2(float sharpness, float factor)
|
||||||
{
|
{
|
||||||
float s = exp2(sharpness);
|
float s = exp2(sharpness);
|
||||||
@ -1308,34 +1292,31 @@ float4x4 OsdComputeMs2(float sharpness, float factor)
|
|||||||
float ssub1 = s-1;
|
float ssub1 = s-1;
|
||||||
float ssub1_2 = ssub1 * ssub1;
|
float ssub1_2 = ssub1 * ssub1;
|
||||||
float div6 = 1.0/6.0;
|
float div6 = 1.0/6.0;
|
||||||
|
|
||||||
float4x4 m(
|
float4x4 m(
|
||||||
float4(0, s + 1 + 3*s2 - s3, 7*s - 2 - 6*s2 + 2*s3, sfrac1 * ssub1_2),
|
float4(0, s + 1 + 3*s2 - s3, 7*s - 2 - 6*s2 + 2*s3, sfrac1 * ssub1_2),
|
||||||
float4(0, 1 + 2*s + s2, sx6m2 - 2*s2, ssub1_2),
|
float4(0, 1 + 2*s + s2, sx6m2 - 2*s2, ssub1_2),
|
||||||
float4(0, 1+s, sx6m2, sfrac1),
|
float4(0, 1+s, sx6m2, sfrac1),
|
||||||
float4(0, 1, sx6m2, 1));
|
float4(0, 1, sx6m2, 1));
|
||||||
|
|
||||||
m *= factor * (1/sx6);
|
m *= factor * (1/sx6);
|
||||||
|
|
||||||
m[0][0] = div6 * factor;
|
m[0][0] = div6 * factor;
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// BSpline
|
// BSpline
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
// convert BSpline cv to Bezier cv
|
// convert BSpline cv to Bezier cv
|
||||||
template<typename VertexType> //VertexType should be some type that implements float3 VertexType::GetPosition()
|
template<typename VertexType> //VertexType should be some type that implements float3 VertexType::GetPosition()
|
||||||
void OsdComputePerPatchVertexBSpline(int3 patchParam, unsigned ID, threadgroup VertexType* cv, device OsdPerPatchVertexBezier& result)
|
void OsdComputePerPatchVertexBSpline(int3 patchParam, unsigned ID, threadgroup VertexType* cv, device OsdPerPatchVertexBezier& result)
|
||||||
{
|
{
|
||||||
int i = ID%4;
|
int i = ID%4;
|
||||||
int j = ID/4;
|
int j = ID/4;
|
||||||
|
|
||||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||||
|
|
||||||
float3 P = float3(0,0,0); // 0 to 1-2^(-Sf)
|
float3 P = float3(0,0,0); // 0 to 1-2^(-Sf)
|
||||||
@ -1362,7 +1343,7 @@ void OsdComputePerPatchVertexBSpline(int3 patchParam, unsigned ID, threadgroup V
|
|||||||
float s1 = 1 - exp2(-Sc);
|
float s1 = 1 - exp2(-Sc);
|
||||||
result.vSegments = float2(s0, s1);
|
result.vSegments = float2(s0, s1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool isBoundary[2];
|
bool isBoundary[2];
|
||||||
isBoundary[0] = (((boundaryMask & 8) != 0) || ((boundaryMask & 2) != 0)) ? true : false;
|
isBoundary[0] = (((boundaryMask & 8) != 0) || ((boundaryMask & 2) != 0)) ? true : false;
|
||||||
isBoundary[1] = (((boundaryMask & 4) != 0) || ((boundaryMask & 1) != 0)) ? true : false;
|
isBoundary[1] = (((boundaryMask & 4) != 0) || ((boundaryMask & 1) != 0)) ? true : false;
|
||||||
@ -1370,7 +1351,7 @@ void OsdComputePerPatchVertexBSpline(int3 patchParam, unsigned ID, threadgroup V
|
|||||||
needsFlip[0] = (boundaryMask & 8) ? true : false;
|
needsFlip[0] = (boundaryMask & 8) ? true : false;
|
||||||
needsFlip[1] = (boundaryMask & 1) ? true : false;
|
needsFlip[1] = (boundaryMask & 1) ? true : false;
|
||||||
float3 Hi[4], Hj[4], Hs[4];
|
float3 Hi[4], Hj[4], Hs[4];
|
||||||
|
|
||||||
if (isBoundary[0])
|
if (isBoundary[0])
|
||||||
{
|
{
|
||||||
int t[4] = {0,1,2,3};
|
int t[4] = {0,1,2,3};
|
||||||
@ -1448,7 +1429,7 @@ void OsdComputePerPatchVertexBSpline(int3 patchParam, unsigned ID, threadgroup V
|
|||||||
for (int k=0; k<4; ++k) {
|
for (int k=0; k<4; ++k) {
|
||||||
P += Q[j][k]*Hi[k];
|
P += Q[j][k]*Hi[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
result.P = P;
|
result.P = P;
|
||||||
result.P1 = P;
|
result.P1 = P;
|
||||||
@ -2051,9 +2032,3 @@ OsdComputePerPatchVertexGregory(int3 patchParam, unsigned ID, unsigned primitive
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
#endif // OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,23 +29,23 @@
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerVertex(
|
void OsdComputePerVertex(
|
||||||
float4 position,
|
float4 position,
|
||||||
threadgroup OsdPerVertexGregory& hullVertex,
|
threadgroup OsdPerVertexGregory& hullVertex,
|
||||||
int vertexId,
|
int vertexId,
|
||||||
float4x4 modelViewProjectionMatrix,
|
float4x4 modelViewProjectionMatrix,
|
||||||
OsdPatchParamBufferSet osdBuffers
|
OsdPatchParamBufferSet osdBuffers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
OsdComputePerVertexGregory(vertexId, position.xyz, hullVertex, osdBuffers);
|
OsdComputePerVertexGregory(vertexId, position.xyz, hullVertex, osdBuffers);
|
||||||
|
|
||||||
#if OSD_ENABLE_PATCH_CULL
|
#if OSD_ENABLE_PATCH_CULL
|
||||||
float4 clipPos = mul(modelViewProjectionMatrix, position);
|
float4 clipPos = mul(modelViewProjectionMatrix, position);
|
||||||
short3 clip0 = short3(clipPos.x < clipPos.w,
|
short3 clip0 = short3(clipPos.x < clipPos.w,
|
||||||
clipPos.y < clipPos.w,
|
clipPos.y < clipPos.w,
|
||||||
clipPos.z < clipPos.w);
|
clipPos.z < clipPos.w);
|
||||||
short3 clip1 = short3(clipPos.x > -clipPos.w,
|
short3 clip1 = short3(clipPos.x > -clipPos.w,
|
||||||
clipPos.y > -clipPos.w,
|
clipPos.y > -clipPos.w,
|
||||||
clipPos.z > -clipPos.w);
|
clipPos.z > -clipPos.w);
|
||||||
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
|
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -55,31 +55,31 @@ void OsdComputePerVertex(
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerPatchFactors(
|
void OsdComputePerPatchFactors(
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
float tessLevel,
|
float tessLevel,
|
||||||
unsigned patchID,
|
unsigned patchID,
|
||||||
float4x4 projectionMatrix,
|
float4x4 projectionMatrix,
|
||||||
float4x4 modelViewMatrix,
|
float4x4 modelViewMatrix,
|
||||||
OsdPatchParamBufferSet osdBuffer,
|
OsdPatchParamBufferSet osdBuffer,
|
||||||
threadgroup PatchVertexType* patchVertices,
|
threadgroup PatchVertexType* patchVertices,
|
||||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
float4 tessLevelOuter = float4(0,0,0,0);
|
float4 tessLevelOuter = float4(0,0,0,0);
|
||||||
float2 tessLevelInner = float2(0,0);
|
float2 tessLevelInner = float2(0,0);
|
||||||
|
|
||||||
OsdGetTessLevels(
|
OsdGetTessLevels(
|
||||||
tessLevel,
|
tessLevel,
|
||||||
projectionMatrix,
|
projectionMatrix,
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
patchVertices[0].P,
|
patchVertices[0].P,
|
||||||
patchVertices[3].P,
|
patchVertices[3].P,
|
||||||
patchVertices[2].P,
|
patchVertices[2].P,
|
||||||
patchVertices[1].P,
|
patchVertices[1].P,
|
||||||
patchParam,
|
patchParam,
|
||||||
tessLevelOuter,
|
tessLevelOuter,
|
||||||
tessLevelInner
|
tessLevelInner
|
||||||
);
|
);
|
||||||
|
|
||||||
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
||||||
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
||||||
@ -94,21 +94,21 @@ void OsdComputePerPatchFactors(
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerPatchVertex(
|
void OsdComputePerPatchVertex(
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
unsigned ID,
|
unsigned ID,
|
||||||
unsigned PrimitiveID,
|
unsigned PrimitiveID,
|
||||||
unsigned ControlID,
|
unsigned ControlID,
|
||||||
threadgroup PatchVertexType* patchVertices,
|
threadgroup PatchVertexType* patchVertices,
|
||||||
OsdPatchParamBufferSet osdBuffers
|
OsdPatchParamBufferSet osdBuffers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
OsdComputePerPatchVertexGregory(
|
OsdComputePerPatchVertexGregory(
|
||||||
patchParam,
|
patchParam,
|
||||||
ID,
|
ID,
|
||||||
PrimitiveID,
|
PrimitiveID,
|
||||||
patchVertices,
|
patchVertices,
|
||||||
osdBuffers.perPatchVertexBuffer[ControlID],
|
osdBuffers.perPatchVertexBuffer[ControlID],
|
||||||
osdBuffers);
|
osdBuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@ -117,43 +117,43 @@ void OsdComputePerPatchVertex(
|
|||||||
|
|
||||||
template<typename PerPatchVertexGregory>
|
template<typename PerPatchVertexGregory>
|
||||||
OsdPatchVertex ds_gregory_patches(
|
OsdPatchVertex ds_gregory_patches(
|
||||||
PerPatchVertexGregory patch,
|
PerPatchVertexGregory patch,
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
float2 UV
|
float2 UV
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
OsdPatchVertex output;
|
OsdPatchVertex output;
|
||||||
|
|
||||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||||
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
||||||
|
|
||||||
float3 cv[20];
|
float3 cv[20];
|
||||||
cv[0] = patch[0].P;
|
cv[0] = patch[0].P;
|
||||||
cv[1] = patch[0].Ep;
|
cv[1] = patch[0].Ep;
|
||||||
cv[2] = patch[0].Em;
|
cv[2] = patch[0].Em;
|
||||||
cv[3] = patch[0].Fp;
|
cv[3] = patch[0].Fp;
|
||||||
cv[4] = patch[0].Fm;
|
cv[4] = patch[0].Fm;
|
||||||
|
|
||||||
cv[5] = patch[1].P;
|
cv[5] = patch[1].P;
|
||||||
cv[6] = patch[1].Ep;
|
cv[6] = patch[1].Ep;
|
||||||
cv[7] = patch[1].Em;
|
cv[7] = patch[1].Em;
|
||||||
cv[8] = patch[1].Fp;
|
cv[8] = patch[1].Fp;
|
||||||
cv[9] = patch[1].Fm;
|
cv[9] = patch[1].Fm;
|
||||||
|
|
||||||
cv[10] = patch[2].P;
|
cv[10] = patch[2].P;
|
||||||
cv[11] = patch[2].Ep;
|
cv[11] = patch[2].Ep;
|
||||||
cv[12] = patch[2].Em;
|
cv[12] = patch[2].Em;
|
||||||
cv[13] = patch[2].Fp;
|
cv[13] = patch[2].Fp;
|
||||||
cv[14] = patch[2].Fm;
|
cv[14] = patch[2].Fm;
|
||||||
|
|
||||||
cv[15] = patch[3].P;
|
cv[15] = patch[3].P;
|
||||||
cv[16] = patch[3].Ep;
|
cv[16] = patch[3].Ep;
|
||||||
cv[17] = patch[3].Em;
|
cv[17] = patch[3].Em;
|
||||||
cv[18] = patch[3].Fp;
|
cv[18] = patch[3].Fp;
|
||||||
cv[19] = patch[3].Fm;
|
cv[19] = patch[3].Fm;
|
||||||
|
|
||||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||||
|
|
||||||
// all code below here is client code
|
// all code below here is client code
|
||||||
output.position = P;
|
output.position = P;
|
||||||
output.normal = N;
|
output.normal = N;
|
||||||
@ -165,7 +165,7 @@ OsdPatchVertex ds_gregory_patches(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
output.patchCoord = OsdInterpolatePatchCoord(UV, patchParam);
|
output.patchCoord = OsdInterpolatePatchCoord(UV, patchParam);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,23 +173,23 @@ OsdPatchVertex ds_gregory_patches(
|
|||||||
template<typename PerPatchVertexGregoryBasis>
|
template<typename PerPatchVertexGregoryBasis>
|
||||||
#endif
|
#endif
|
||||||
OsdPatchVertex OsdComputePatch(
|
OsdPatchVertex OsdComputePatch(
|
||||||
float tessLevel,
|
float tessLevel,
|
||||||
float2 domainCoord,
|
float2 domainCoord,
|
||||||
unsigned patchID,
|
unsigned patchID,
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
PerPatchVertexGregoryBasis osdPatch
|
PerPatchVertexGregoryBasis osdPatch
|
||||||
#else
|
#else
|
||||||
OsdVertexBufferSet osdBuffers
|
OsdVertexBufferSet osdBuffers
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ds_gregory_patches(
|
return ds_gregory_patches(
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
osdPatch.cv,
|
osdPatch.cv,
|
||||||
osdPatch.patchParam,
|
osdPatch.patchParam,
|
||||||
#else
|
#else
|
||||||
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
||||||
osdBuffers.patchParamBuffer[patchID],
|
osdBuffers.patchParamBuffer[patchID],
|
||||||
#endif
|
#endif
|
||||||
domainCoord);
|
domainCoord);
|
||||||
}
|
}
|
||||||
|
@ -29,23 +29,23 @@
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerVertex(
|
void OsdComputePerVertex(
|
||||||
float4 position,
|
float4 position,
|
||||||
threadgroup HullVertex& hullVertex,
|
threadgroup HullVertex& hullVertex,
|
||||||
int vertexId,
|
int vertexId,
|
||||||
float4x4 modelViewProjectionMatrix,
|
float4x4 modelViewProjectionMatrix,
|
||||||
OsdPatchParamBufferSet osdBuffers
|
OsdPatchParamBufferSet osdBuffers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
hullVertex.position = position;
|
hullVertex.position = position;
|
||||||
#if OSD_ENABLE_PATCH_CULL
|
#if OSD_ENABLE_PATCH_CULL
|
||||||
float4 clipPos = mul(modelViewProjectionMatrix, position);
|
float4 clipPos = mul(modelViewProjectionMatrix, position);
|
||||||
short3 clip0 = short3(clipPos.x < clipPos.w,
|
short3 clip0 = short3(clipPos.x < clipPos.w,
|
||||||
clipPos.y < clipPos.w,
|
clipPos.y < clipPos.w,
|
||||||
clipPos.z < clipPos.w);
|
clipPos.z < clipPos.w);
|
||||||
short3 clip1 = short3(clipPos.x > -clipPos.w,
|
short3 clip1 = short3(clipPos.x > -clipPos.w,
|
||||||
clipPos.y > -clipPos.w,
|
clipPos.y > -clipPos.w,
|
||||||
clipPos.z > -clipPos.w);
|
clipPos.z > -clipPos.w);
|
||||||
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
|
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,31 +54,31 @@ void OsdComputePerVertex(
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerPatchFactors(
|
void OsdComputePerPatchFactors(
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
float tessLevel,
|
float tessLevel,
|
||||||
unsigned patchID,
|
unsigned patchID,
|
||||||
float4x4 projectionMatrix,
|
float4x4 projectionMatrix,
|
||||||
float4x4 modelViewMatrix,
|
float4x4 modelViewMatrix,
|
||||||
OsdPatchParamBufferSet osdBuffer,
|
OsdPatchParamBufferSet osdBuffer,
|
||||||
threadgroup PatchVertexType* patchVertices,
|
threadgroup PatchVertexType* patchVertices,
|
||||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
float4 tessLevelOuter = float4(0,0,0,0);
|
float4 tessLevelOuter = float4(0,0,0,0);
|
||||||
float2 tessLevelInner = float2(0,0);
|
float2 tessLevelInner = float2(0,0);
|
||||||
|
|
||||||
OsdGetTessLevels(
|
OsdGetTessLevels(
|
||||||
tessLevel,
|
tessLevel,
|
||||||
projectionMatrix,
|
projectionMatrix,
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
patchVertices[0].position.xyz,
|
patchVertices[0].position.xyz,
|
||||||
patchVertices[3].position.xyz,
|
patchVertices[3].position.xyz,
|
||||||
patchVertices[2].position.xyz,
|
patchVertices[2].position.xyz,
|
||||||
patchVertices[1].position.xyz,
|
patchVertices[1].position.xyz,
|
||||||
patchParam,
|
patchParam,
|
||||||
tessLevelOuter,
|
tessLevelOuter,
|
||||||
tessLevelInner
|
tessLevelInner
|
||||||
);
|
);
|
||||||
|
|
||||||
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
||||||
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
||||||
@ -93,15 +93,15 @@ void OsdComputePerPatchFactors(
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
void OsdComputePerPatchVertex(
|
void OsdComputePerPatchVertex(
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
unsigned ID,
|
unsigned ID,
|
||||||
unsigned PrimitiveID,
|
unsigned PrimitiveID,
|
||||||
unsigned ControlID,
|
unsigned ControlID,
|
||||||
threadgroup PatchVertexType* patchVertices,
|
threadgroup PatchVertexType* patchVertices,
|
||||||
OsdPatchParamBufferSet osdBuffers
|
OsdPatchParamBufferSet osdBuffers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//Does nothing, all transforms are in the PTVS
|
//Does nothing, all transforms are in the PTVS
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,31 +116,30 @@ void OsdComputePerPatchVertex(
|
|||||||
template<typename PerPatchVertexGregoryBasis>
|
template<typename PerPatchVertexGregoryBasis>
|
||||||
#endif
|
#endif
|
||||||
OsdPatchVertex ds_gregory_basis_patches(
|
OsdPatchVertex ds_gregory_basis_patches(
|
||||||
|
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
PerPatchVertexGregoryBasis patch,
|
PerPatchVertexGregoryBasis patch,
|
||||||
#else
|
#else
|
||||||
const device OsdInputVertexType* patch,
|
const device OsdInputVertexType* patch,
|
||||||
const device unsigned* patchIndices,
|
const device unsigned* patchIndices,
|
||||||
#endif
|
#endif
|
||||||
int3 patchParam,
|
int3 patchParam,
|
||||||
float2 UV
|
float2 UV
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
OsdPatchVertex output;
|
OsdPatchVertex output;
|
||||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||||
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
||||||
|
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
float3 cv[20];
|
float3 cv[20];
|
||||||
for(int i = 0; i < 20; i++)
|
for(int i = 0; i < 20; i++)
|
||||||
cv[i] = patch[i].position;
|
cv[i] = patch[i].position;
|
||||||
#else
|
#else
|
||||||
#if USE_128BIT_GREGORY_BASIS_INDICES_READ
|
#if USE_128BIT_GREGORY_BASIS_INDICES_READ
|
||||||
float3 cv[20];
|
float3 cv[20];
|
||||||
for(int i = 0; i < 5; i++) {
|
for(int i = 0; i < 5; i++) {
|
||||||
int4 indices = ((device int4*)patchIndices)[i];
|
int4 indices = ((device int4*)patchIndices)[i];
|
||||||
|
|
||||||
int n = i * 4;
|
int n = i * 4;
|
||||||
cv[n + 0] = (patch + indices[0])->position;
|
cv[n + 0] = (patch + indices[0])->position;
|
||||||
cv[n + 1] = (patch + indices[1])->position;
|
cv[n + 1] = (patch + indices[1])->position;
|
||||||
@ -154,9 +153,9 @@ OsdPatchVertex ds_gregory_basis_patches(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||||
|
|
||||||
output.position = P;
|
output.position = P;
|
||||||
output.normal = N;
|
output.normal = N;
|
||||||
output.tangent = dPu;
|
output.tangent = dPu;
|
||||||
@ -165,9 +164,9 @@ OsdPatchVertex ds_gregory_basis_patches(
|
|||||||
output.Nu = dNu;
|
output.Nu = dNu;
|
||||||
output.Nv = dNv;
|
output.Nv = dNv;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
output.patchCoord = OsdInterpolatePatchCoord(UV, patchParam);
|
output.patchCoord = OsdInterpolatePatchCoord(UV, patchParam);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,25 +174,25 @@ OsdPatchVertex ds_gregory_basis_patches(
|
|||||||
template<typename PerPatchVertexGregoryBasis>
|
template<typename PerPatchVertexGregoryBasis>
|
||||||
#endif
|
#endif
|
||||||
OsdPatchVertex OsdComputePatch(
|
OsdPatchVertex OsdComputePatch(
|
||||||
float tessLevel,
|
float tessLevel,
|
||||||
float2 domainCoord,
|
float2 domainCoord,
|
||||||
unsigned patchID,
|
unsigned patchID,
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
PerPatchVertexGregoryBasis osdPatch
|
PerPatchVertexGregoryBasis osdPatch
|
||||||
#else
|
#else
|
||||||
OsdVertexBufferSet osdBuffers
|
OsdVertexBufferSet osdBuffers
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ds_gregory_basis_patches(
|
return ds_gregory_basis_patches(
|
||||||
#if USE_STAGE_IN
|
#if USE_STAGE_IN
|
||||||
osdPatch.cv,
|
osdPatch.cv,
|
||||||
osdPatch.patchParam,
|
osdPatch.patchParam,
|
||||||
#else
|
#else
|
||||||
osdBuffers.vertexBuffer,
|
osdBuffers.vertexBuffer,
|
||||||
osdBuffers.indexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
osdBuffers.indexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
||||||
osdBuffers.patchParamBuffer[patchID],
|
osdBuffers.patchParamBuffer[patchID],
|
||||||
#endif
|
#endif
|
||||||
domainCoord
|
domainCoord
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -22,36 +22,39 @@
|
|||||||
// language governing permissions and limitations under the Apache License.
|
// language governing permissions and limitations under the Apache License.
|
||||||
//
|
//
|
||||||
|
|
||||||
#pragma once
|
#ifndef OPENSUBDIV3_OSD_MTL_PATCH_SHADER_SOURCE_H
|
||||||
|
#define OPENSUBDIV3_OSD_MTL_PATCH_SHADER_SOURCE_H
|
||||||
|
|
||||||
#import <string>
|
#import <string>
|
||||||
#import "../version.h"
|
#import "../version.h"
|
||||||
#import "../far/patchDescriptor.h"
|
#import "../far/patchDescriptor.h"
|
||||||
|
|
||||||
namespace OpenSubdiv {
|
namespace OpenSubdiv {
|
||||||
namespace OPENSUBDIV_VERSION {
|
namespace OPENSUBDIV_VERSION {
|
||||||
|
|
||||||
namespace Osd {
|
|
||||||
|
|
||||||
class MTLPatchShaderSource {
|
|
||||||
public:
|
|
||||||
static std::string GetCommonShaderSource();
|
|
||||||
|
|
||||||
static std::string GetPatchBasisShaderSource();
|
namespace Osd {
|
||||||
|
|
||||||
static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type,
|
class MTLPatchShaderSource {
|
||||||
Far::PatchDescriptor::Type fvarType);
|
public:
|
||||||
|
static std::string GetCommonShaderSource();
|
||||||
static std::string GetHullShaderSource(Far::PatchDescriptor::Type type,
|
|
||||||
Far::PatchDescriptor::Type fvarType);
|
static std::string GetPatchBasisShaderSource();
|
||||||
|
|
||||||
static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type,
|
static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type,
|
||||||
Far::PatchDescriptor::Type fvarType);
|
Far::PatchDescriptor::Type fvarType);
|
||||||
};
|
|
||||||
|
static std::string GetHullShaderSource(Far::PatchDescriptor::Type type,
|
||||||
} // end namespace Osd
|
Far::PatchDescriptor::Type fvarType);
|
||||||
|
|
||||||
} // end namespace OPENSUBDIV_VERSION
|
static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type,
|
||||||
using namespace OPENSUBDIV_VERSION;
|
Far::PatchDescriptor::Type fvarType);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace Osd
|
||||||
|
|
||||||
|
} // end namespace OPENSUBDIV_VERSION
|
||||||
|
using namespace OPENSUBDIV_VERSION;
|
||||||
|
|
||||||
} // end namespace OpenSubdiv
|
} // end namespace OpenSubdiv
|
||||||
|
|
||||||
|
#endif // OPENSUBDIV3_OSD_MTL_PATCH_SHADER_SOURCE
|
||||||
|
@ -30,127 +30,131 @@
|
|||||||
#include <TargetConditionals.h>
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
namespace OpenSubdiv {
|
namespace OpenSubdiv {
|
||||||
namespace OPENSUBDIV_VERSION {
|
namespace OPENSUBDIV_VERSION {
|
||||||
|
|
||||||
namespace Osd {
|
namespace Osd {
|
||||||
|
|
||||||
static std::string commonShaderSource(
|
static std::string commonShaderSource(
|
||||||
#include "mtlPatchCommon.gen.h"
|
#include "mtlPatchCommon.gen.h"
|
||||||
);
|
);
|
||||||
static std::string patchBasisTypesShaderSource(
|
static std::string patchBasisTypesShaderSource(
|
||||||
#include "patchBasisCommonTypes.gen.h"
|
#include "patchBasisCommonTypes.gen.h"
|
||||||
);
|
);
|
||||||
static std::string patchBasisShaderSource(
|
static std::string patchBasisShaderSource(
|
||||||
#include "patchBasisCommon.gen.h"
|
#include "patchBasisCommon.gen.h"
|
||||||
);
|
);
|
||||||
static std::string patchBasisEvalShaderSource(
|
static std::string patchBasisEvalShaderSource(
|
||||||
#include "patchBasisCommonEval.gen.h"
|
#include "patchBasisCommonEval.gen.h"
|
||||||
);
|
);
|
||||||
static std::string bsplineShaderSource(
|
static std::string bsplineShaderSource(
|
||||||
#include "mtlPatchBSpline.gen.h"
|
#include "mtlPatchBSpline.gen.h"
|
||||||
);
|
);
|
||||||
static std::string gregoryShaderSource(
|
static std::string gregoryShaderSource(
|
||||||
#include "mtlPatchGregory.gen.h"
|
#include "mtlPatchGregory.gen.h"
|
||||||
);
|
);
|
||||||
static std::string gregoryBasisShaderSource(
|
static std::string gregoryBasisShaderSource(
|
||||||
#include "mtlPatchGregoryBasis.gen.h"
|
#include "mtlPatchGregoryBasis.gen.h"
|
||||||
);
|
);
|
||||||
|
|
||||||
static std::string GetPatchTypeDefine(Far::PatchDescriptor::Type type,
|
static std::string
|
||||||
Far::PatchDescriptor::Type fvarType) {
|
GetPatchTypeDefine(Far::PatchDescriptor::Type type,
|
||||||
std::stringstream ss;
|
Far::PatchDescriptor::Type fvarType) {
|
||||||
switch(type) {
|
|
||||||
case Far::PatchDescriptor::LINES: ss << "#define OSD_PATCH_LINES 1\n"; break;
|
|
||||||
case Far::PatchDescriptor::TRIANGLES: ss << "#define OSD_PATCH_TRIANGLES 1\n"; break;
|
|
||||||
case Far::PatchDescriptor::QUADS: ss << "#define OSD_PATCH_QUADS 1\n"; break;
|
|
||||||
case Far::PatchDescriptor::REGULAR: ss << "#define OSD_PATCH_BSPLINE 1\n#define OSD_PATCH_REGULAR 1\n"; break;
|
|
||||||
case Far::PatchDescriptor::GREGORY: ss << "#define OSD_PATCH_GREGORY 1\n"; break;
|
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY: ss << "#define OSD_PATCH_GREGORY_BOUNDRY 1\n"; break;
|
|
||||||
case Far::PatchDescriptor::GREGORY_BASIS: ss << "#define OSD_PATCH_GREGORY_BASIS 1\n"; break;
|
|
||||||
default:
|
|
||||||
assert("Unknown Far::PatchDescriptor::Type" && 0);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
switch(fvarType) {
|
|
||||||
case Far::PatchDescriptor::REGULAR: ss << "#define OSD_FACEVARYING_PATCH_REGULAR 1\n"; break;
|
|
||||||
case Far::PatchDescriptor::GREGORY_BASIS: ss << "#define OSD_FACEVARYING_PATCH_GREGORY_BASIS 1\n"; break;
|
|
||||||
default:
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string GetPatchTypeSource(Far::PatchDescriptor::Type type) {
|
std::stringstream ss;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Far::PatchDescriptor::QUADS: return "";
|
case Far::PatchDescriptor::LINES: ss << "#define OSD_PATCH_LINES 1\n"; break;
|
||||||
case Far::PatchDescriptor::REGULAR: return bsplineShaderSource;
|
case Far::PatchDescriptor::TRIANGLES: ss << "#define OSD_PATCH_TRIANGLES 1\n"; break;
|
||||||
case Far::PatchDescriptor::GREGORY: return gregoryShaderSource;
|
case Far::PatchDescriptor::QUADS: ss << "#define OSD_PATCH_QUADS 1\n"; break;
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY: return gregoryShaderSource;
|
case Far::PatchDescriptor::REGULAR: ss << "#define OSD_PATCH_BSPLINE 1\n#define OSD_PATCH_REGULAR 1\n"; break;
|
||||||
case Far::PatchDescriptor::GREGORY_BASIS: return gregoryBasisShaderSource;
|
case Far::PatchDescriptor::GREGORY: ss << "#define OSD_PATCH_GREGORY 1\n"; break;
|
||||||
default:
|
case Far::PatchDescriptor::GREGORY_BOUNDARY: ss << "#define OSD_PATCH_GREGORY_BOUNDRY 1\n"; break;
|
||||||
assert("Unknown Far::PatchDescriptor::Type" && 0);
|
case Far::PatchDescriptor::GREGORY_BASIS: ss << "#define OSD_PATCH_GREGORY_BASIS 1\n"; break;
|
||||||
return "";
|
default:
|
||||||
}
|
assert("Unknown Far::PatchDescriptor::Type" && 0);
|
||||||
}
|
return "";
|
||||||
|
}
|
||||||
/*static*/
|
switch(fvarType) {
|
||||||
std::string
|
case Far::PatchDescriptor::REGULAR: ss << "#define OSD_FACEVARYING_PATCH_REGULAR 1\n"; break;
|
||||||
MTLPatchShaderSource::GetCommonShaderSource() {
|
case Far::PatchDescriptor::GREGORY_BASIS: ss << "#define OSD_FACEVARYING_PATCH_GREGORY_BASIS 1\n"; break;
|
||||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
default:
|
||||||
return std::string("#define OSD_METAL_IOS 1\n").append(commonShaderSource);
|
return ss.str();
|
||||||
#elif TARGET_OS_OSX
|
}
|
||||||
return std::string("#define OSD_METAL_OSX 1\n").append(commonShaderSource);
|
return ss.str();
|
||||||
#endif
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*static*/
|
static std::string
|
||||||
std::string
|
GetPatchTypeSource(Far::PatchDescriptor::Type type) {
|
||||||
MTLPatchShaderSource::GetPatchBasisShaderSource() {
|
|
||||||
std::stringstream ss;
|
switch(type) {
|
||||||
ss << "#define OSD_PATCH_BASIS_METAL 1\n";
|
case Far::PatchDescriptor::QUADS: return "";
|
||||||
#if defined(OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES)
|
case Far::PatchDescriptor::REGULAR: return bsplineShaderSource;
|
||||||
ss << "#define OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES 1\n";
|
case Far::PatchDescriptor::GREGORY: return gregoryShaderSource;
|
||||||
|
case Far::PatchDescriptor::GREGORY_BOUNDARY: return gregoryShaderSource;
|
||||||
|
case Far::PatchDescriptor::GREGORY_BASIS: return gregoryBasisShaderSource;
|
||||||
|
default:
|
||||||
|
assert("Unknown Far::PatchDescriptor::Type" && 0);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
std::string
|
||||||
|
MTLPatchShaderSource::GetCommonShaderSource() {
|
||||||
|
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||||
|
return std::string("#define OSD_METAL_IOS 1\n").append(commonShaderSource);
|
||||||
|
#elif TARGET_OS_OSX
|
||||||
|
return std::string("#define OSD_METAL_OSX 1\n").append(commonShaderSource);
|
||||||
#endif
|
#endif
|
||||||
ss << patchBasisTypesShaderSource;
|
}
|
||||||
ss << patchBasisShaderSource;
|
|
||||||
ss << patchBasisEvalShaderSource;
|
/*static*/
|
||||||
return ss.str();
|
std::string
|
||||||
}
|
MTLPatchShaderSource::GetPatchBasisShaderSource() {
|
||||||
|
std::stringstream ss;
|
||||||
/*static*/
|
ss << "#define OSD_PATCH_BASIS_METAL 1\n";
|
||||||
std::string
|
#if defined(OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES)
|
||||||
MTLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type,
|
ss << "#define OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES 1\n";
|
||||||
Far::PatchDescriptor::Type fvarType) {
|
#endif
|
||||||
std::stringstream ss;
|
ss << patchBasisTypesShaderSource;
|
||||||
ss << GetPatchTypeDefine(type, fvarType);
|
ss << patchBasisShaderSource;
|
||||||
ss << GetCommonShaderSource();
|
ss << patchBasisEvalShaderSource;
|
||||||
ss << GetPatchTypeSource(type);
|
return ss.str();
|
||||||
return ss.str();
|
}
|
||||||
}
|
|
||||||
|
/*static*/
|
||||||
/*static*/
|
std::string
|
||||||
std::string
|
MTLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type,
|
||||||
MTLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type,
|
Far::PatchDescriptor::Type fvarType) {
|
||||||
Far::PatchDescriptor::Type fvarType) {
|
std::stringstream ss;
|
||||||
std::stringstream ss;
|
ss << GetPatchTypeDefine(type, fvarType);
|
||||||
ss << GetPatchTypeDefine(type, fvarType);
|
ss << GetCommonShaderSource();
|
||||||
ss << GetCommonShaderSource();
|
ss << GetPatchTypeSource(type);
|
||||||
ss << GetPatchTypeSource(type);
|
return ss.str();
|
||||||
return ss.str();
|
}
|
||||||
}
|
|
||||||
|
/*static*/
|
||||||
/*static*/
|
std::string
|
||||||
std::string
|
MTLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type,
|
||||||
MTLPatchShaderSource::GetDomainShaderSource(Far::PatchDescriptor::Type type,
|
Far::PatchDescriptor::Type fvarType) {
|
||||||
Far::PatchDescriptor::Type fvarType) {
|
std::stringstream ss;
|
||||||
std::stringstream ss;
|
ss << GetPatchTypeDefine(type, fvarType);
|
||||||
ss << GetPatchTypeDefine(type, fvarType);
|
ss << GetCommonShaderSource();
|
||||||
ss << GetCommonShaderSource();
|
ss << GetPatchTypeSource(type);
|
||||||
ss << GetPatchTypeSource(type);
|
return ss.str();
|
||||||
return ss.str();
|
}
|
||||||
}
|
|
||||||
|
/*static*/
|
||||||
} // end namespace Osd
|
std::string
|
||||||
|
MTLPatchShaderSource::GetDomainShaderSource(Far::PatchDescriptor::Type type,
|
||||||
} // end namespace OPENSUBDIV_VERSION
|
Far::PatchDescriptor::Type fvarType) {
|
||||||
} // end namespace OpenSubdiv
|
std::stringstream ss;
|
||||||
|
ss << GetPatchTypeDefine(type, fvarType);
|
||||||
|
ss << GetCommonShaderSource();
|
||||||
|
ss << GetPatchTypeSource(type);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Osd
|
||||||
|
|
||||||
|
} // end namespace OPENSUBDIV_VERSION
|
||||||
|
} // end namespace OpenSubdiv
|
||||||
|
@ -34,65 +34,64 @@
|
|||||||
@protocol MTLDevice;
|
@protocol MTLDevice;
|
||||||
@protocol MTLBuffer;
|
@protocol MTLBuffer;
|
||||||
|
|
||||||
namespace OpenSubdiv
|
namespace OpenSubdiv {
|
||||||
{
|
namespace OPENSUBDIV_VERSION {
|
||||||
namespace OPENSUBDIV_VERSION
|
|
||||||
|
namespace Far {
|
||||||
|
class PatchTable;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Osd {
|
||||||
|
|
||||||
|
class MTLPatchTable : private NonCopyable<MTLPatchTable> {
|
||||||
|
public:
|
||||||
|
typedef id<MTLBuffer> VertexBufferBinding;
|
||||||
|
|
||||||
|
MTLPatchTable();
|
||||||
|
~MTLPatchTable();
|
||||||
|
|
||||||
|
template<typename DEVICE_CONTEXT>
|
||||||
|
static MTLPatchTable *Create(Far::PatchTable const *farPatchTable, DEVICE_CONTEXT context)
|
||||||
{
|
{
|
||||||
namespace Far
|
return Create(farPatchTable, context);
|
||||||
{
|
}
|
||||||
class PatchTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Osd
|
static MTLPatchTable *Create(Far::PatchTable const *farPatchTable, MTLContext* context);
|
||||||
{
|
|
||||||
class MTLPatchTable : private NonCopyable<MTLPatchTable>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef id<MTLBuffer> VertexBufferBinding;
|
|
||||||
|
|
||||||
MTLPatchTable();
|
PatchArrayVector const &GetPatchArrays() const { return _patchArrays; }
|
||||||
~MTLPatchTable();
|
id<MTLBuffer> GetPatchIndexBuffer() const { return _indexBuffer; }
|
||||||
|
id<MTLBuffer> GetPatchParamBuffer() const { return _patchParamBuffer; }
|
||||||
|
|
||||||
template<typename DEVICE_CONTEXT>
|
PatchArrayVector const &GetVaryingPatchArrays() const { return _varyingPatchArrays; }
|
||||||
static MTLPatchTable *Create(Far::PatchTable const *farPatchTable, DEVICE_CONTEXT context)
|
id<MTLBuffer> GetVaryingPatchIndexBuffer() const { return _varyingPatchIndexBuffer; }
|
||||||
{
|
|
||||||
return Create(farPatchTable, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static MTLPatchTable *Create(Far::PatchTable const *farPatchTable, MTLContext* context);
|
int GetNumFVarChannels() const { return (int)_fvarPatchArrays.size(); }
|
||||||
|
PatchArrayVector const &GetFVarPatchArrays(int fvarChannel = 0) const { return _fvarPatchArrays[fvarChannel]; }
|
||||||
|
id<MTLBuffer> GetFVarPatchIndexBuffer(int fvarChannel = 0) const { return _fvarIndexBuffers[fvarChannel]; }
|
||||||
|
id<MTLBuffer> GetFVarPatchParamBuffer(int fvarChannel = 0) const { return _fvarParamBuffers[fvarChannel]; }
|
||||||
|
|
||||||
PatchArrayVector const &GetPatchArrays() const { return _patchArrays; }
|
protected:
|
||||||
id<MTLBuffer> GetPatchIndexBuffer() const { return _indexBuffer; }
|
bool allocate(Far::PatchTable const *farPatchTable, MTLContext* context);
|
||||||
id<MTLBuffer> GetPatchParamBuffer() const { return _patchParamBuffer; }
|
|
||||||
|
|
||||||
PatchArrayVector const &GetVaryingPatchArrays() const { return _varyingPatchArrays; }
|
PatchArrayVector _patchArrays;
|
||||||
id<MTLBuffer> GetVaryingPatchIndexBuffer() const { return _varyingPatchIndexBuffer; }
|
|
||||||
|
|
||||||
int GetNumFVarChannels() const { return (int)_fvarPatchArrays.size(); }
|
id<MTLBuffer> _indexBuffer;
|
||||||
PatchArrayVector const &GetFVarPatchArrays(int fvarChannel = 0) const { return _fvarPatchArrays[fvarChannel]; }
|
id<MTLBuffer> _patchParamBuffer;
|
||||||
id<MTLBuffer> GetFVarPatchIndexBuffer(int fvarChannel = 0) const { return _fvarIndexBuffers[fvarChannel]; }
|
|
||||||
id<MTLBuffer> GetFVarPatchParamBuffer(int fvarChannel = 0) const { return _fvarParamBuffers[fvarChannel]; }
|
|
||||||
|
|
||||||
protected:
|
PatchArrayVector _varyingPatchArrays;
|
||||||
bool allocate(Far::PatchTable const *farPatchTable, MTLContext* context);
|
|
||||||
|
|
||||||
PatchArrayVector _patchArrays;
|
id<MTLBuffer> _varyingPatchIndexBuffer;
|
||||||
|
|
||||||
id<MTLBuffer> _indexBuffer;
|
|
||||||
id<MTLBuffer> _patchParamBuffer;
|
|
||||||
|
|
||||||
PatchArrayVector _varyingPatchArrays;
|
std::vector<PatchArrayVector> _fvarPatchArrays;
|
||||||
|
std::vector<id<MTLBuffer>> _fvarIndexBuffers;
|
||||||
|
std::vector<id<MTLBuffer>> _fvarParamBuffers;
|
||||||
|
};
|
||||||
|
|
||||||
id<MTLBuffer> _varyingPatchIndexBuffer;
|
} // end namespace Osd
|
||||||
|
|
||||||
std::vector<PatchArrayVector> _fvarPatchArrays;
|
} //end namespace OPENSUBDIV_VERSION
|
||||||
std::vector<id<MTLBuffer>> _fvarIndexBuffers;
|
using namespace OPENSUBDIV_VERSION;
|
||||||
std::vector<id<MTLBuffer>> _fvarParamBuffers;
|
|
||||||
};
|
|
||||||
} // end namespace Osd
|
|
||||||
} //end namespace OPENSUBDIV_VERSION
|
|
||||||
|
|
||||||
using namespace OPENSUBDIV_VERSION;
|
|
||||||
} //end namespace OpenSubdiv
|
} //end namespace OpenSubdiv
|
||||||
|
|
||||||
#endif //end OPENSUBDIV3_OSD_MTL_PATCH_TABLE_H
|
#endif //end OPENSUBDIV3_OSD_MTL_PATCH_TABLE_H
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
namespace OpenSubdiv {
|
namespace OpenSubdiv {
|
||||||
namespace OPENSUBDIV_VERSION {
|
namespace OPENSUBDIV_VERSION {
|
||||||
|
|
||||||
namespace Osd {
|
namespace Osd {
|
||||||
|
|
||||||
MTLPatchTable::MTLPatchTable()
|
MTLPatchTable::MTLPatchTable()
|
||||||
@ -43,7 +44,7 @@ _varyingPatchIndexBuffer(nil)
|
|||||||
|
|
||||||
MTLPatchTable::~MTLPatchTable()
|
MTLPatchTable::~MTLPatchTable()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static id<MTLBuffer> createBuffer(const void* data, const size_t length,
|
static id<MTLBuffer> createBuffer(const void* data, const size_t length,
|
||||||
@ -97,7 +98,7 @@ bool MTLPatchTable::allocate(Far::PatchTable const *farPatchTable, MTLContext* c
|
|||||||
auto patchParamSize = cpuTable.GetPatchParamSize();
|
auto patchParamSize = cpuTable.GetPatchParamSize();
|
||||||
|
|
||||||
_patchArrays.assign(cpuTable.GetPatchArrayBuffer(), cpuTable.GetPatchArrayBuffer() + numPatchArrays);
|
_patchArrays.assign(cpuTable.GetPatchArrayBuffer(), cpuTable.GetPatchArrayBuffer() + numPatchArrays);
|
||||||
|
|
||||||
_indexBuffer = createBuffer(cpuTable.GetPatchIndexBuffer(), indexSize * sizeof(unsigned), context);
|
_indexBuffer = createBuffer(cpuTable.GetPatchIndexBuffer(), indexSize * sizeof(unsigned), context);
|
||||||
if(_indexBuffer == nil)
|
if(_indexBuffer == nil)
|
||||||
return false;
|
return false;
|
||||||
@ -130,7 +131,7 @@ bool MTLPatchTable::allocate(Far::PatchTable const *farPatchTable, MTLContext* c
|
|||||||
_fvarParamBuffers[fvc] = createBuffer(cpuTable.GetFVarPatchParamBuffer(fvc), cpuTable.GetFVarPatchParamSize(fvc) * sizeof(PatchParam), context);
|
_fvarParamBuffers[fvc] = createBuffer(cpuTable.GetFVarPatchParamBuffer(fvc), cpuTable.GetFVarPatchParamSize(fvc) * sizeof(PatchParam), context);
|
||||||
if(_fvarParamBuffers[fvc] == nil)
|
if(_fvarParamBuffers[fvc] == nil)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -31,54 +31,53 @@
|
|||||||
@protocol MTLDevice;
|
@protocol MTLDevice;
|
||||||
@protocol MTLBuffer;
|
@protocol MTLBuffer;
|
||||||
|
|
||||||
namespace OpenSubdiv
|
namespace OpenSubdiv {
|
||||||
{
|
namespace OPENSUBDIV_VERSION {
|
||||||
namespace OPENSUBDIV_VERSION
|
|
||||||
{
|
namespace Osd {
|
||||||
namespace Osd
|
|
||||||
{
|
class CPUMTLVertexBuffer {
|
||||||
class CPUMTLVertexBuffer
|
public:
|
||||||
|
static CPUMTLVertexBuffer* Create(int numElements, int numVertices, MTLContext* context);
|
||||||
|
|
||||||
|
void UpdateData(const float* src, int startVertex, int numVertices, MTLContext* context);
|
||||||
|
|
||||||
|
int GetNumElements() const
|
||||||
{
|
{
|
||||||
public:
|
return _numElements;
|
||||||
static CPUMTLVertexBuffer* Create(int numElements, int numVertices, MTLContext* context);
|
}
|
||||||
|
|
||||||
void UpdateData(const float* src, int startVertex, int numVertices, MTLContext* context);
|
int GetNumVertices() const
|
||||||
|
{
|
||||||
|
return _numVertices;
|
||||||
|
}
|
||||||
|
|
||||||
int GetNumElements() const
|
float* BindCpuBuffer();
|
||||||
{
|
id<MTLBuffer> BindMTLBuffer(MTLContext* context);
|
||||||
return _numElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetNumVertices() const
|
id<MTLBuffer> BindVBO(MTLContext* context)
|
||||||
{
|
{
|
||||||
return _numVertices;
|
return BindMTLBuffer(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
float* BindCpuBuffer();
|
protected:
|
||||||
id<MTLBuffer> BindMTLBuffer(MTLContext* context);
|
|
||||||
|
|
||||||
id<MTLBuffer> BindVBO(MTLContext* context)
|
CPUMTLVertexBuffer(int numElements, int numVertices);
|
||||||
{
|
|
||||||
return BindMTLBuffer(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
bool allocate(MTLContext* context);
|
||||||
|
|
||||||
CPUMTLVertexBuffer(int numElements, int numVertices);
|
private:
|
||||||
|
int _numElements;
|
||||||
bool allocate(MTLContext* context);
|
int _numVertices;
|
||||||
|
id<MTLBuffer> _buffer;
|
||||||
private:
|
bool _dirty;
|
||||||
int _numElements;
|
};
|
||||||
int _numVertices;
|
|
||||||
id<MTLBuffer> _buffer;
|
|
||||||
bool _dirty;
|
|
||||||
};
|
|
||||||
|
|
||||||
} //end namespace Osd
|
} //end namespace Osd
|
||||||
|
|
||||||
} //end namespace OPENSUBDIV_VERSION
|
} //end namespace OPENSUBDIV_VERSION
|
||||||
using namespace OPENSUBDIV_VERSION;
|
using namespace OPENSUBDIV_VERSION;
|
||||||
|
|
||||||
} //end namespace OpenSubdiv
|
} //end namespace OpenSubdiv
|
||||||
|
|
||||||
|
|
||||||
#endif // OPENSUBDIV3_OSD_MTL_VERTEX_BUFFER_H
|
#endif // OPENSUBDIV3_OSD_MTL_VERTEX_BUFFER_H
|
||||||
|
@ -26,12 +26,11 @@
|
|||||||
#include <Metal/Metal.h>
|
#include <Metal/Metal.h>
|
||||||
#include <TargetConditionals.h>
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
namespace OpenSubdiv
|
namespace OpenSubdiv {
|
||||||
{
|
namespace OPENSUBDIV_VERSION {
|
||||||
namespace OPENSUBDIV_VERSION
|
|
||||||
{
|
namespace Osd {
|
||||||
namespace Osd
|
|
||||||
{
|
|
||||||
CPUMTLVertexBuffer::CPUMTLVertexBuffer(int numElements, int numVertices)
|
CPUMTLVertexBuffer::CPUMTLVertexBuffer(int numElements, int numVertices)
|
||||||
:
|
:
|
||||||
_numElements(numElements), _numVertices(numVertices),
|
_numElements(numElements), _numVertices(numVertices),
|
||||||
@ -83,7 +82,7 @@ float* CPUMTLVertexBuffer::BindCpuBuffer()
|
|||||||
id<MTLBuffer> CPUMTLVertexBuffer::BindMTLBuffer(MTLContext* context)
|
id<MTLBuffer> CPUMTLVertexBuffer::BindMTLBuffer(MTLContext* context)
|
||||||
{
|
{
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
if(_dirty)
|
if(_dirty)
|
||||||
[_buffer didModifyRange:NSMakeRange(0, _buffer.length)];
|
[_buffer didModifyRange:NSMakeRange(0, _buffer.length)];
|
||||||
_dirty = false;
|
_dirty = false;
|
||||||
#endif
|
#endif
|
||||||
@ -93,6 +92,6 @@ id<MTLBuffer> CPUMTLVertexBuffer::BindMTLBuffer(MTLContext* context)
|
|||||||
|
|
||||||
|
|
||||||
} //end namepsace Osd
|
} //end namepsace Osd
|
||||||
|
|
||||||
} //end namespace OPENSUBDIV_VERSION
|
} //end namespace OPENSUBDIV_VERSION
|
||||||
using namespace OPENSUBDIV_VERSION;
|
|
||||||
} //end namespace OpenSubdiv
|
} //end namespace OpenSubdiv
|
||||||
|
Loading…
Reference in New Issue
Block a user