Mtl implementation whitespace fixes

Fixed numerous whitespace inconsistencies and violations
in the core osd metal implementation and examples.
This commit is contained in:
David G Yu 2019-05-22 18:00:36 -07:00
parent 24c37eecd3
commit 291eff0bed
21 changed files with 3193 additions and 3212 deletions

View File

@ -48,42 +48,42 @@ const constant float4 patchColors[] = {
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(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.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.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.50f, 0.6f, 1.0f), // single crease pattern 4
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.2f, 0.75f, 1.0f), // boundary pattern 1
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.8f, 0.75f, 1.0f), // boundary pattern 4
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 1
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 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, 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
@ -94,10 +94,10 @@ const constant float4 patchColors[] = {
float4
getAdaptivePatchColor(int3 patchParam, float sharpness)
{
{
int pattern = popcount(OsdGetPatchTransitionMask(patchParam));
int edgeCount = popcount(OsdGetPatchBoundaryMask(patchParam));
int patchType = 0;
#if OSD_PATCH_ENABLE_SINGLE_CREASE
if (sharpness > 0) {
@ -111,7 +111,7 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
if (edgeCount == 2) {
patchType = 3; // CORNER
}
// XXX: it looks like edgeCount != 0 for some gregory boundary patches.
// there might be a bug somewhere...
#if OSD_PATCH_GREGORY
@ -121,7 +121,7 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
#elif OSD_PATCH_GREGORY_BASIS
patchType = 6;
#endif
return patchColors[6*patchType + pattern];
}
@ -149,7 +149,7 @@ float3 displacement(float3 position, float3 normal, float4 patchCoord, float mip
,device ushort* textureDisplace_Packing
#endif
)
{
{
#if DISPLACEMENT_HW_BILINEAR
float disp = PtexLookupFast(patchCoord, mipmapBias,
textureDisplace_Data,
@ -184,7 +184,7 @@ perturbNormalFromDisplacement(float3 position, float3 normal, float4 patchCoord,
{
// by Morten S. Mikkelsen
// 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 vSigmaT = dfdy(position);
float3 vN = normal;
@ -198,11 +198,11 @@ perturbNormalFromDisplacement(float3 position, float3 normal, float4 patchCoord,
#else
float2 texDx = dfdx(patchCoord.xy);
float2 texDy = dfdy(patchCoord.xy);
// limit forward differencing to the width of ptex gutter
const float resolution = 128.0;
float d = min(1.0f, (0.5/resolution)/max(length(texDx), length(texDy)));
float4 STll = patchCoord;
float4 STlr = patchCoord + d * float4(texDx.x, texDx.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 dBt = (Hul - Hll)/d;
#endif
float3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2);
return normalize(abs(fDet) * vN - vSurfGrad);
}
@ -251,7 +251,7 @@ struct FragmentInput
#if OSD_PATCH_REGULAR
struct ControlPoint
{
float3 P [[attribute(0)]];
#if OSD_PATCH_ENABLE_SINGLE_CREASE
float3 P1 [[attribute(1)]];
@ -274,7 +274,7 @@ struct PatchInput
#elif OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
struct ControlPoint
{
float3 P [[attribute(0)]];
float3 Ep [[attribute(1)]];
float3 Em [[attribute(2)]];
@ -333,7 +333,7 @@ kernel void compute_main(
if(validThread)
{
patchParam[subthreadgroup_in_threadgroup] = OsdGetPatchParam(real_threadgroup, osdBuffers.patchParamBuffer);
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];
@ -440,20 +440,20 @@ vertex FragmentInput vertex_main(
)
{
FragmentInput out;
#if USE_STAGE_IN
int3 patchParam = patchInput.patchParam;
#else
int3 patchParam = patchInput.patchParamBuffer[patch_id];
#endif
int refinementLevel = OsdGetPatchRefinementLevel(patchParam);
float tessLevel = min(frameConsts.TessLevel, (float)OSD_MAX_TESS_LEVEL) /
exp2((float)refinementLevel - 1);
auto patchVertex = OsdComputePatch(tessLevel, position_in_patch, patch_id, patchInput);
#if USE_DISPLACEMENT
float3 position = displacement(patchVertex.position,
patchVertex.normal,
@ -468,7 +468,7 @@ vertex FragmentInput vertex_main(
float3 position = patchVertex.position;
#endif
out.positionOut = mul(frameConsts.ModelViewProjectionMatrix, float4(position, 1));
out.position = mul(frameConsts.ModelViewMatrix, float4(position,1)).xyz;
out.normal = mul(frameConsts.ModelViewMatrix,float4(patchVertex.normal, 0)).xyz;
@ -500,29 +500,29 @@ struct LightSource {
float4 diffuse;
float4 specular;
};
float4
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);
float3 n = Neye;
for (int i = 0; i < NUM_LIGHTS; ++i) {
float4 Plight = lightSource[i].position;
float3 l = (Plight.w == 0.0)
? normalize(Plight.xyz) : normalize(Plight.xyz - Peye);
float3 h = normalize(l + float3(0,0,1)); // directional viewer
float d = max(0.0, dot(n, l));
float s = pow(max(0.0, dot(n, h)), 64.0f);
color += (1.0 - occ) * ((lightSource[i].ambient +
d * lightSource[i].diffuse) * texColor +
s * lightSource[i].specular);
}
color.a = 1.0;
return color;
}
@ -546,11 +546,11 @@ edgeColor(float4 Cfill, float4 edgeDistance)
#endif
float4 Cedge = float4(1.0, 1.0, 0.0, 1.0);
float p = exp2(-2 * d * d);
#if defined(GEOMETRY_OUT_WIRE)
if (p < 0.25) discard;
#endif
Cfill.rgb = lerp(Cfill.rgb, Cedge.rgb, p);
#endif
return Cfill;
@ -599,8 +599,8 @@ fragment float4 fragment_main(
,const constant float4& shade [[buffer(2)]]
)
{
const auto displacementScale = config.displacementScale;
const auto mipmapBias = config.mipmapBias;
const auto displacementScale = config.displacementScale;
const auto mipmapBias = config.mipmapBias;
float4 outColor;
// ------------ normal ---------------
#if NORMAL_HW_SCREENSPACE || NORMAL_SCREENSPACE
@ -617,25 +617,25 @@ fragment float4 fragment_main(
config.mipmapBias,
textureDisplace_Data,
textureDisplace_Packing);
disp *= displacementScale;
du *= displacementScale;
dv *= displacementScale;
float3 n = normalize(cross(input.tangent, input.bitangent));
float3 tangent = input.tangent + n * du.x;
float3 bitangent = input.bitangent + n * dv.x;
#if NORMAL_BIQUADRATIC_WG
tangent += input.Nu * disp.x;
bitangent += input.Nv * disp.x;
#endif
float3 normal = normalize(cross(tangent, bitangent));
#else
float3 normal = input.normal;
#endif
// ------------ color ---------------
#if COLOR_PTEX_NEAREST
float4 texColor = PtexLookupNearest(input.patchCoord,
@ -653,7 +653,7 @@ fragment float4 fragment_main(
float4 texColor = PtexMipmapLookupQuadratic(input.patchCoord, mipmapBias,
textureImage_Data,
textureImage_Packing);
#elif COLOR_PATCHTYPE
#elif COLOR_PATCHTYPE
float4 texColor = lighting(float4(input.patchColor), input.position.xyz, normal, 0, lightSource);
outColor = texColor;
return outColor;
@ -668,9 +668,9 @@ fragment float4 fragment_main(
#else // COLOR_NONE
float4 texColor = float4(0.5, 0.5, 0.5, 1);
#endif
// ------------ occlusion ---------------
#if USE_PTEX_OCCLUSION
float occ = PtexMipmapLookup(input.patchCoord, config.mipmapBias,
textureOcclusion_Data,
@ -678,9 +678,9 @@ fragment float4 fragment_main(
#else
float occ = 0.0;
#endif
// ------------ specular ---------------
#if USE_PTEX_SPECULAR
float specular = PtexMipmapLookup(input.patchCoord, config.mipmapBias,
textureSpecular_Data,
@ -690,7 +690,7 @@ fragment float4 fragment_main(
#endif
// ------------ lighting ---------------
float4 Cf = lighting(texColor, input.position.xyz, normal, occ, lightSource);
// ------------ wireframe ---------------
outColor = max(Cf, shade);
return outColor;

View File

@ -122,33 +122,33 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
@implementation OSDRenderer {
MTLRingBuffer<Light, 1> _lightsBuffer;
PerFrameBuffer<PerFrameConstants> _frameConstantsBuffer;
PerFrameBuffer<MTLQuadTessellationFactorsHalf> _tessFactorsBuffer;
PerFrameBuffer<unsigned> _patchIndexBuffers[4];
PerFrameBuffer<uint8_t> _perPatchDataBuffer;
PerFrameBuffer<uint8_t> _hsDataBuffer;
PerFrameBuffer<MTLDrawPatchIndirectArguments> _drawIndirectCommandsBuffer;
unsigned _tessFactorOffsets[4];
unsigned _perPatchDataOffsets[4];
id<MTLComputePipelineState> _computePipelines[10];
id<MTLRenderPipelineState> _renderPipelines[10];
id<MTLDepthStencilState> _readWriteDepthStencilState;
id<MTLDepthStencilState> _readOnlyDepthStencilState;
Camera _cameraData;
Osd::MTLContext _context;
std::unique_ptr<MTLMeshInterface> _mesh;
std::unique_ptr<Shape> _shape;
std::unique_ptr<MTLPtexMipmapTexture> _colorPtexture;
std::unique_ptr<MTLPtexMipmapTexture> _displacementPtexture;
std::unique_ptr<MTLPtexMipmapTexture> _occlusionPtexture;
std::unique_ptr<MTLPtexMipmapTexture> _specularPtexture;
bool _needsRebuild, _doAdaptive;
NSString* _osdShaderSource;
simd::float3 _meshCenter;
@ -180,27 +180,27 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
self.displacementMode = kDisplacementModeNone;
self.useAdaptive = true;
self.displayStyle = kDisplayStyleShaded;
const auto colorFilename = getenv("COLOR_FILENAME");
const auto displacementFilename = getenv("DISPLACEMENT_FILENAME");
if(colorFilename)
_ptexColorFilename = [NSString stringWithUTF8String:colorFilename];
if(displacementFilename)
_ptexDisplacementFilename = [NSString stringWithUTF8String:displacementFilename];
_delegate = delegate;
_context.device = [delegate deviceFor:self];
_context.commandQueue = [delegate commandQueueFor:self];
_osdShaderSource = @(shaderSource);
_needsRebuild = true;
_numFrames = 0;
_animationFrames = 0;
[self _initializeBuffers];
[self _initializeCamera];
[self _initializeLights];
@ -213,13 +213,13 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
if(_needsRebuild) {
[self _rebuildState];
}
if(!_freeze) {
if(_animateVertices) {
_animatedVertices.resize(_vertexData.size());
auto p = _vertexData.data();
auto n = _animatedVertices.data();
float r = sin(_animationFrames*0.01f) * _animateVertices;
for (int i = 0; i < _numVertices; ++i) {
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[1] = -p[0]*st + p[1]*ct;
n[2] = p[2];
p += _numVertexElements;
n += _numVertexElements;
}
_mesh->UpdateVertexBuffer(_animatedVertices.data(), 0, _numVertices);
_animationFrames++;
}
_mesh->Refine();
_mesh->Synchronize();
}
[self _updateState];
if(_doAdaptive) {
auto computeEncoder = [commandBuffer computeCommandEncoder];
[self _computeTessFactors:computeEncoder];
[computeEncoder endEncoding];
}
auto renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:[_delegate renderPassDescriptorFor: self]];
if(_usePrimitiveBackfaceCulling) {
[renderEncoder setCullMode:MTLCullModeBack];
} else {
[renderEncoder setCullMode:MTLCullModeNone];
}
[self _renderMesh:renderEncoder];
_frameConstantsBuffer.next();
_tessFactorsBuffer.next();
_patchIndexBuffers[0].next();
@ -268,25 +268,25 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
_perPatchDataBuffer.next();
_hsDataBuffer.next();
_drawIndirectCommandsBuffer.next();
_numFrames++;
return renderEncoder;
}
-(void)_renderMesh:(id<MTLRenderCommandEncoder>)renderCommandEncoder {
auto buffer = _mesh->BindVertexBuffer();
assert(buffer);
auto pav = _mesh->GetPatchTable()->GetPatchArrays();
auto pib = _mesh->GetPatchTable()->GetPatchIndexBuffer();
[renderCommandEncoder setVertexBuffer:buffer offset:0 atIndex:VERTEX_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:offsetof(PerFrameConstants, displacementConfig) atIndex:CONFIG_BUFFER_INDEX];
if(_doAdaptive)
{
[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:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
}
[renderCommandEncoder setFragmentBuffer:_frameConstantsBuffer offset:offsetof(PerFrameConstants, displacementConfig) atIndex:1];
[renderCommandEncoder setFragmentBuffer:_lightsBuffer offset:0 atIndex:0];
[renderCommandEncoder setFragmentTexture:_colorPtexture->GetTexelsTexture() atIndex:IMAGE_TEXTURE_INDEX];
[renderCommandEncoder setFragmentBuffer:_colorPtexture->GetLayoutBuffer() offset:0 atIndex:IMAGE_BUFFER_INDEX];
if(_displacementPtexture)
{
[renderCommandEncoder setFragmentTexture:_displacementPtexture->GetTexelsTexture() atIndex:DISPLACEMENT_TEXTURE_INDEX];
[renderCommandEncoder setFragmentBuffer:_displacementPtexture->GetLayoutBuffer() offset:0 atIndex:DISPLACEMENT_BUFFER_INDEX];
[renderCommandEncoder setVertexTexture:_displacementPtexture->GetTexelsTexture() atIndex:DISPLACEMENT_TEXTURE_INDEX];
[renderCommandEncoder setVertexBuffer:_displacementPtexture->GetLayoutBuffer() offset:0 atIndex:DISPLACEMENT_BUFFER_INDEX];
}
for(int i = 0; i < pav.size(); i++)
{
auto& patch = pav[i];
auto d = patch.GetDescriptor();
auto patchType = d.GetType();
auto offset = patchType - Far::PatchDescriptor::REGULAR;
if(_doAdaptive)
{
[renderCommandEncoder setVertexBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
}
[renderCommandEncoder setVertexBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
simd::float4 shade{.0f,0.0f,0.0f,1.0f};
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
[renderCommandEncoder setDepthBias:0 slopeScale:1.0 clamp:0];
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
[renderCommandEncoder setDepthStencilState:_readWriteDepthStencilState];
[renderCommandEncoder setRenderPipelineState:_renderPipelines[patchType]];
if(_displayStyle == kDisplayStyleWire)
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
else
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
switch(patchType)
{
case Far::PatchDescriptor::GREGORY_BASIS:
@ -347,8 +347,8 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[renderCommandEncoder setVertexBufferOffset:_perPatchDataOffsets[offset] atIndex:OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX];
break;
}
switch(patchType)
{
case Far::PatchDescriptor::POINTS:
@ -379,7 +379,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
if(_usePatchIndexBuffer)
{
[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()
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
}
if(_displayStyle == kDisplayStyleWireOnShaded)
{
simd::float4 shade = {1, 1,1,1};
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
#if !TARGET_OS_EMBEDDED
if(_usePatchIndexBuffer)
{
@ -439,8 +439,8 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
}
}
break;
case Far::PatchDescriptor::QUADS:
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:patch.GetNumPatches() * 6];
break;
@ -456,7 +456,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
-(void)_computeTessFactors:(id<MTLComputeCommandEncoder>)computeCommandEncoder {
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
[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()->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:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
[computeCommandEncoder setBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
for(auto& patch : patchArray)
{
auto usefulControlPoints = patch.GetDescriptor().GetNumControlVertices();
if(patch.GetDescriptor().GetType() == Far::PatchDescriptor::GREGORY_BASIS)
usefulControlPoints = 4;
auto threadsPerThreadgroup = MTLSizeMake([_computePipelines[patch.GetPatchType()] threadExecutionWidth], 1, 1);
auto threadsPerControlPoint = std::max<int>(1, usefulControlPoints / threadsPerThreadgroup.width);
auto groupPerControlPoint = MTLSizeMake(patch.GetNumPatches() * usefulControlPoints, 1, 1);
groupPerControlPoint.width /= threadsPerControlPoint;
groupPerControlPoint.width = (groupPerControlPoint.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
groupPerControlPoint.width = groupPerControlPoint.width / threadsPerThreadgroup.width;
auto groupPerPatch = MTLSizeMake(patch.GetNumPatches(), 1, 1);
groupPerPatch.width = (groupPerPatch.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
groupPerPatch.width = groupPerPatch.width / threadsPerThreadgroup.width;
[computeCommandEncoder setBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
[computeCommandEncoder setBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
if(_usePatchIndexBuffer)
{
[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 setComputePipelineState:_computePipelines[patch.desc.GetType()]];
unsigned kernelExecutionLimit;
switch(patch.desc.GetType())
{
@ -514,7 +514,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
break;
default: return;
}
[computeCommandEncoder setBytes:&kernelExecutionLimit length:sizeof(kernelExecutionLimit) atIndex:OSD_KERNELLIMIT_BUFFER_INDEX];
[computeCommandEncoder dispatchThreadgroups:groupPerControlPoint threadsPerThreadgroup:threadsPerThreadgroup];
}
@ -525,7 +525,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[self _rebuildModel];
[self _rebuildBuffers];
[self _rebuildPipelines];
_needsRebuild = false;
}
@ -534,7 +534,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
_displacementPtexture.reset();
_occlusionPtexture.reset();
_specularPtexture.reset();
_colorPtexture = [self _createPtex:_ptexColorFilename];
if(_ptexDisplacementFilename) {
_displacementPtexture = [self _createPtex:_ptexDisplacementFilename];
@ -542,7 +542,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
}
-(std::unique_ptr<MTLPtexMipmapTexture>)_createPtex:(NSString*) filename {
Ptex::String ptexError;
printf("Loading ptex : %s\n", filename.UTF8String);
#if TARGET_OS_EMBEDDED
@ -550,44 +550,44 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
#else
const auto path = filename;
#endif
#define USE_PTEX_CACHE 1
#define PTEX_CACHE_SIZE (512*1024*1024)
#if USE_PTEX_CACHE
PtexCache *cache = PtexCache::create(1, PTEX_CACHE_SIZE);
PtexTexture *ptex = cache->get(path.UTF8String, ptexError);
#else
PtexTexture *ptex = PtexTexture::open(path.UTF8String, ptexError, true);
#endif
if (ptex == NULL) {
printf("Error in reading %s\n", filename.UTF8String);
exit(1);
}
std::unique_ptr<MTLPtexMipmapTexture> osdPtex(MTLPtexMipmapTexture::Create(&_context, ptex));
ptex->release();
#if USE_PTEX_CACHE
cache->release();
#endif
return osdPtex;
}
-(std::unique_ptr<Shape>)_shapeFromPtex:(Ptex::PtexTexture*) tex {
const auto meta = tex->getMetaData();
if (meta->numKeys() < 3) {
return NULL;
}
float const * vp;
int const *vi, *vc;
int nvp, nvi, nvc;
meta->getValue("PtexFaceVertCounts", vc, nvc);
if (nvc == 0) {
return NULL;
@ -600,26 +600,26 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
if (nvi == 0) {
return NULL;
}
std::unique_ptr<Shape> shape(new Shape);
shape->scheme = kCatmark;
shape->verts.resize(nvp);
for (int i=0; i<nvp; ++i) {
shape->verts[i] = vp[i];
}
shape->nvertsPerFace.resize(nvc);
for (int i=0; i<nvc; ++i) {
shape->nvertsPerFace[i] = vc[i];
}
shape->faceverts.resize(nvi);
for (int i=0; i<nvi; ++i) {
shape->faceverts[i] = vi[i];
}
// compute model bounding
float min[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);
}
}
for (int j = 0; j < 3; ++j) {
_meshCenter[j] = (min[j] + max[j]) * 0.5f;
_meshSize += (max[j]-min[j])*(max[j]-min[j]);
}
_meshSize = sqrtf(_meshSize);
return shape;
}
-(void)_rebuildModel {
using namespace OpenSubdiv;
using namespace Sdc;
using namespace Osd;
using namespace Far;
Ptex::String ptexError;
#if TARGET_OS_EMBEDDED
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);
#endif
_shape = [self _shapeFromPtex:ptexColor];
// create Far mesh (topology)
Sdc::SchemeType sdctype = GetSdcType(*_shape);
Sdc::Options sdcoptions = GetSdcOptions(*_shape);
std::unique_ptr<OpenSubdiv::Far::TopologyRefiner> refiner;
refiner.reset(
Far::TopologyRefinerFactory<Shape>::Create(*_shape, Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions)));
// save coarse topology (used for coarse mesh drawing)
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
// Adaptive refinement currently supported only for catmull-clark scheme
_doAdaptive = (_useAdaptive);
bool doSingleCreasePatch = (_useSingleCrease);
Osd::MeshBitset bits;
bits.set(Osd::MeshAdaptive, _doAdaptive);
bits.set(Osd::MeshUseSingleCreasePatch, doSingleCreasePatch);
bits.set(Osd::MeshEndCapGregoryBasis, true);
int level = _refinementLevel;
_numVertexElements = 3;
int numVaryingElements = 0;
if(_kernelType == kCPU)
{
_mesh.reset(new CPUMeshType(
@ -695,11 +695,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
numVaryingElements,
level, bits, nullptr, &_context));
}
MTLRenderPipelineDescriptor* desc = [MTLRenderPipelineDescriptor new];
[_delegate setupRenderPipelineState:desc for:self];
const auto vertexDescriptor = desc.vertexDescriptor;
vertexDescriptor.layouts[0].stride = sizeof(float) * _numVertexElements;
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
@ -707,19 +707,19 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3;
vertexDescriptor.attributes[0].offset = 0;
vertexDescriptor.attributes[0].bufferIndex = 0;
_numVertices = refBaseLevel.GetNumVertices();
_vertexData.resize(refBaseLevel.GetNumVertices() * _numVertexElements);
_meshCenter = simd::float3{0,0,0};
for(int vertexIdx = 0; vertexIdx < refBaseLevel.GetNumVertices(); vertexIdx++)
{
_vertexData[vertexIdx * _numVertexElements + 0] = _shape->verts[vertexIdx * 3 + 0];
_vertexData[vertexIdx * _numVertexElements + 1] = _shape->verts[vertexIdx * 3 + 1];
_vertexData[vertexIdx * _numVertexElements + 2] = _shape->verts[vertexIdx * 3 + 2];
_meshCenter[0] += _vertexData[vertexIdx * _numVertexElements + 0];
_meshCenter[1] += _vertexData[vertexIdx * _numVertexElements + 1];
_meshCenter[2] += _vertexData[vertexIdx * _numVertexElements + 2];
@ -734,11 +734,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
-(void)_updateState {
[self _updateCamera];
auto pData = _frameConstantsBuffer.data();
pData->TessLevel = _tessellationLevel;
pData->displacementConfig.mipmapBias = _mipmapBias;
pData->displacementConfig.displacementScale = _displacementScale;
{
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;
}
}
if(_usePatchIndexBuffer)
{
_drawIndirectCommandsBuffer.markModified();
@ -765,19 +765,19 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
auto totalPatches = 0;
auto totalVertices = 0;
auto totalPatchDataSize = 0;
if(_usePatchIndexBuffer)
{
_drawIndirectCommandsBuffer.alloc(_context.device, 4, @"draw patch indirect commands");
}
if(_doAdaptive)
{
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
for(auto& patch : patchArray)
{
auto patchDescriptor = patch.GetDescriptor();
switch(patch.desc.GetType())
{
case Far::PatchDescriptor::REGULAR: {
@ -790,7 +790,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
float elementFloats = 3;
if(_useSingleCrease)
elementFloats += 6;
totalPatchDataSize += elementFloats * sizeof(float) * patch.GetNumPatches() * patch.desc.GetNumControlVertices();
}
break;
@ -824,15 +824,15 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
// totalPatchDataSize += sizeof(float) * 4 * 2 * patch.GetNumPatches() * patch.desc.GetNumControlVertices();
break;
}
totalPatches += patch.GetNumPatches();
totalVertices += patch.GetDescriptor().GetNumControlVertices() * patch.GetNumPatches();
}
_perPatchDataBuffer.alloc(_context.device, totalPatchDataSize, @"per patch data", MTLResourceStorageModePrivate);
_hsDataBuffer.alloc(_context.device, 20 * sizeof(float) * totalPatches, @"hs constant data", MTLResourceStorageModePrivate);
_tessFactorsBuffer.alloc(_context.device, totalPatches, @"tessellation factors buffer", MTLResourceStorageModePrivate);
}
}
@ -841,7 +841,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
_computePipelines[i] = nil;
_renderPipelines[i] = nil;
}
Osd::MTLPatchShaderSource shaderSource;
auto& patchArrays = _mesh->GetPatchTable()->GetPatchArrays();
for(auto& patch : patchArrays)
@ -851,11 +851,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
auto controlPointsPerThread = [&]() {
return std::max<int>(1, usefulControlPoints / threadsPerThreadgroup);
};
auto type = patch.GetDescriptor().GetType();
auto compileOptions = [[MTLCompileOptions alloc] init];
compileOptions.fastMathEnabled = YES;
auto preprocessor = [[NSMutableDictionary alloc] init];
#define DEFINE(x, y) preprocessor[@(#x)] = @(y)
bool allowsSingleCrease = true;
@ -888,11 +888,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
usefulControlPoints = 4;
break;
}
#if TARGET_OS_EMBEDDED
shaderBuilder << "#define OSD_UV_CORRECTION if(t > 0.5){ ti += 0.01f; } else { ti += 0.01f; }\n";
#endif
//Need to define the input vertex struct so that it's available everywhere.
shaderBuilder << R"(
#include <metal_stdlib>
@ -900,14 +900,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
metal::packed_float3 position;
};
)";
auto fvarType = Far::PatchDescriptor::REGULAR;
shaderBuilder << shaderSource.GetHullShaderSource(type, fvarType);
shaderBuilder << MTLPtexMipmapTexture::GetShaderSource();
shaderBuilder << _osdShaderSource.UTF8String;
const auto str = shaderBuilder.str();
DEFINE(CONFIG_BUFFER_INDEX,CONFIG_BUFFER_INDEX);
DEFINE(VERTEX_BUFFER_INDEX,VERTEX_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(OSD_KERNELLIMIT_BUFFER_INDEX,OSD_KERNELLIMIT_BUFFER_INDEX);
DEFINE(OSD_PATCH_ENABLE_SINGLE_CREASE, allowsSingleCrease && _useSingleCrease);
DEFINE(COLOR_NORMAL, _colorMode == kColorModeNormal);
DEFINE(COLOR_PATCHTYPE, _colorMode == kColorModePatchType);
DEFINE(COLOR_PATCHCOORD, _colorMode == kColorModePatchCoord);
@ -946,11 +946,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
DEFINE(NORMAL_HW_SCREENSPACE, _normalMode == kNormalModeHWScreenspace);
DEFINE(NORMAL_BIQUADRATIC_WG, _normalMode == kNormalModeBiQuadraticWG);
DEFINE(NORMAL_BIQUADRATIC, _normalMode == kNormalModeBiQuadratic);
DEFINE(DISPLACEMENT_BILINEAR, _displacementMode == kDisplacementModeBilinear);
DEFINE(DISPLACEMENT_HW_BILINEAR, _displacementMode == kDisplacementModeHWBilinear);
DEFINE(DISPLACEMENT_BIQUADRATIC, _displacementMode == kDisplacementModeBiQuadratic);
DEFINE(OSD_COMPUTE_NORMAL_DERIVATIVES, _normalMode == kNormalModeBiQuadraticWG);
auto partitionMode = _useScreenspaceTessellation ? MTLTessellationPartitionModeFractionalOdd : MTLTessellationPartitionModePow2;
@ -978,7 +978,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
DEFINE(OSD_ENABLE_PATCH_CULL, _usePatchClipCulling);
compileOptions.preprocessorMacros = preprocessor;
NSError* err = nil;
auto librarySource = [NSString stringWithUTF8String:str.data()];
auto library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:&err];
@ -991,67 +991,67 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
assert(vertexFunction && fragmentFunction);
if(vertexFunction && fragmentFunction)
{
MTLRenderPipelineDescriptor* pipelineDesc = [[MTLRenderPipelineDescriptor alloc] init];
pipelineDesc.tessellationFactorFormat = MTLTessellationFactorFormatHalf;
pipelineDesc.tessellationPartitionMode = partitionMode;
pipelineDesc.tessellationFactorScaleEnabled = false;
pipelineDesc.tessellationFactorStepFunction = MTLTessellationFactorStepFunctionPerPatch;
if(type == Far::PatchDescriptor::GREGORY_BASIS)
pipelineDesc.tessellationControlPointIndexType = MTLTessellationControlPointIndexTypeUInt32;
[_delegate setupRenderPipelineState:pipelineDesc for:self];
pipelineDesc.fragmentFunction = fragmentFunction;
pipelineDesc.vertexFunction = vertexFunction;
auto vertexDesc = pipelineDesc.vertexDescriptor;
[vertexDesc reset];
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stride = sizeof(int) * 3;
vertexDesc.attributes[10].bufferIndex = OSD_PATCHPARAM_BUFFER_INDEX;
vertexDesc.attributes[10].format = MTLVertexFormatInt3;
vertexDesc.attributes[10].offset = 0;
switch(type)
{
case Far::PatchDescriptor::REGULAR:
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride = sizeof(float) * 3;
vertexDesc.attributes[0].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
vertexDesc.attributes[0].offset = 0;
if(_useSingleCrease)
{
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride += sizeof(float) * 6;
vertexDesc.attributes[1].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
vertexDesc.attributes[1].format = MTLVertexFormatFloat3;
vertexDesc.attributes[1].offset = sizeof(float) * 3;
vertexDesc.attributes[2].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
vertexDesc.attributes[2].format = MTLVertexFormatFloat3;
vertexDesc.attributes[2].offset = sizeof(float) * 6;
}
if(_useScreenspaceTessellation)
{
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stride = sizeof(float) * 8;
vertexDesc.attributes[5].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
vertexDesc.attributes[5].format = MTLVertexFormatFloat4;
vertexDesc.attributes[5].offset = 0;
vertexDesc.attributes[6].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
vertexDesc.attributes[6].format = MTLVertexFormatFloat4;
vertexDesc.attributes[6].offset = sizeof(float) * 4;
@ -1059,11 +1059,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
break;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
case Far::PatchDescriptor::GREGORY:
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stride = sizeof(float) * 3 * 5;
for(int i = 0; i < 5; i++)
{
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].stepRate = 1;
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stride = sizeof(float) * 3;
vertexDesc.attributes[0].bufferIndex = VERTEX_BUFFER_INDEX;
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
vertexDesc.attributes[0].offset = 0;
@ -1085,15 +1085,15 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[vertexDesc reset];
break;
}
_renderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
if(!_renderPipelines[type] && err)
{
NSLog(@"%s", [[err localizedDescription] UTF8String]);
}
}
auto computeFunction = [library newFunctionWithName:@"compute_main"];
if(computeFunction)
{
@ -1104,51 +1104,51 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
#endif
computeDesc.computeFunction = computeFunction;
NSError* err;
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
if(err && _computePipelines[type] == nil)
{
NSLog(@"%s", [[err description] UTF8String]);
}
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
{
preprocessor[@"THREADS_PER_THREADGROUP"] = @(_computePipelines[type].threadExecutionWidth);
preprocessor[@"CONTROL_POINTS_PER_THREAD"] = @(std::max<int>(1, usefulControlPoints / _computePipelines[type].threadExecutionWidth));
compileOptions.preprocessorMacros = preprocessor;
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
assert(library);
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = true;
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
assert(_computePipelines[type].threadExecutionWidth == threadsPerThreadgroup);
}
}
}
MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init];
depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess;
[_delegate setupDepthStencilState:depthStencilDesc for:self];
depthStencilDesc.depthWriteEnabled = YES;
_readWriteDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
depthStencilDesc.depthWriteEnabled = NO;
_readOnlyDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
}
-(void)_updateCamera {
auto pData = _frameConstantsBuffer.data();
identity(pData->ModelViewMatrix);
translate(pData->ModelViewMatrix, 0, 0, -_cameraData.dollyDistance);
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
rotate(pData->ModelViewMatrix, -90, 1, 0, 0); // z-up model
inverseMatrix(pData->ModelViewInverseMatrix, pData->ModelViewMatrix);
identity(pData->ProjectionMatrix);
perspective(pData->ProjectionMatrix, 45.0, _cameraData.aspectRatio, 0.01f, 500.0);
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.8f, 0.8f, 0.8f, 1.0f },
};
_lightsBuffer[1] = {
simd::normalize(simd::float4{ -0.8f, 0.4f, -1.0f, 0.0f }),
{ 0.0f, 0.0f, 0.0f, 1.0f },
{ 0.5f, 0.5f, 0.5f, 1.0f },
{ 0.8f, 0.8f, 0.8f, 1.0f }
};
_lightsBuffer.markModified();
}

View File

@ -45,7 +45,7 @@ struct OutputVertex {
float4 positionOut [[position]];
float3 position;
float3 normal;
#if SHADING_TYPE == SHADING_TYPE_PATCH || SHADING_TYPE == SHADING_TYPE_PATCH_COORD || SHADING_TYPE_FACE_VARYING
float3 patchColor;
#endif
@ -53,15 +53,15 @@ struct OutputVertex {
struct SolidColorVertex {
float4 positionOut [[position]];
half4 getColor() const {
return unpack_unorm4x8_to_half(_color);
}
void setColor(half4 color) {
_color = pack_half_to_unorm4x8(color);
}
private:
uint _color [[flat, user(color)]];
};
@ -69,7 +69,7 @@ private:
struct PackedInputVertex {
packed_float3 position;
};
struct Light {
float3 Position;
float3 ambient;
@ -79,7 +79,7 @@ struct Light {
float3 lighting(float3 diffuseColor, const constant Light* lightData, float3 eyePos, float3 eyeN)
{
float3 color(0);
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 d = max(0.0, dot(eyeN, l));
const auto s = powr(max(0.0, dot(eyeN, h)), 500.0f);
color += lightData[i].ambient
+ d * lightData[i].diffuse * diffuseColor
+ s * lightData[i].specular;
}
return color;
}
@ -104,42 +104,42 @@ const constant float4 patchColors[] = {
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(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.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.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.50f, 0.6f, 1.0f), // single crease pattern 4
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.2f, 0.75f, 1.0f), // boundary pattern 1
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.8f, 0.75f, 1.0f), // boundary pattern 4
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 1
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 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, 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
@ -156,10 +156,10 @@ getAdaptivePatchColor(int3 patchParam
#endif
)
{
int patchType = 0;
int edgeCount = popcount(OsdGetPatchBoundaryMask(patchParam));
if (edgeCount == 1) {
patchType = 2; // BOUNDARY
@ -167,7 +167,7 @@ getAdaptivePatchColor(int3 patchParam
if (edgeCount == 2) {
patchType = 3; // CORNER
}
#if OSD_PATCH_ENABLE_SINGLE_CREASE
// check this after boundary/corner since single crease patch also has edgeCount.
if (vSegments.y > 0) {
@ -180,9 +180,9 @@ getAdaptivePatchColor(int3 patchParam
#elif OSD_PATCH_GREGORY_BASIS
patchType = 6;
#endif
int pattern = popcount(OsdGetPatchTransitionMask(patchParam));
return patchColors[6*patchType + pattern];
}
@ -287,7 +287,7 @@ kernel void compute_main(
if(validThread)
{
patchParam[subthreadgroup_in_threadgroup] = OsdGetPatchParam(real_threadgroup, osdBuffers.patchParamBuffer);
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];
@ -365,7 +365,7 @@ kernel void compute_main(
#endif
//----------------------------------------------------------
// OSD Tessellation Factors
// OSD Tessellation Factors
//----------------------------------------------------------
if(validThread && real_thread_in_threadgroup == 0)
{
@ -406,22 +406,22 @@ vertex OutputVertex vertex_main(
)
{
OutputVertex out;
#if USE_STAGE_IN
int3 patchParam = patchInput.patchParam;
#else
int3 patchParam = patchInput.patchParamBuffer[patch_id];
#endif
int refinementLevel = OsdGetPatchRefinementLevel(patchParam);
float tessLevel = min(frameConsts.TessLevel, (float)OSD_MAX_TESS_LEVEL) /
exp2((float)refinementLevel - 1);
auto patchVertex = OsdComputePatch(tessLevel, position_in_patch, patch_id, patchInput);
out.position = (frameConsts.ModelViewMatrix * float4(patchVertex.position, 1.0f)).xyz;
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(patchVertex.position, 1.0f);
out.normal = mul(frameConsts.ModelViewMatrix, patchVertex.normal);
#if SHADING_TYPE == SHADING_TYPE_PATCH
#if OSD_PATCH_ENABLE_SINGLE_CREASE
@ -479,7 +479,7 @@ vertex OutputVertex vertex_main(
out.patchColor.rg = fvarUV;
#endif
return out;
}
#endif
@ -498,25 +498,25 @@ const constant unsigned BSplineControlLineIndices[] = {
12, 8,
8, 4,
4, 0,
//Inner lines
5, 6,
6, 10,
10, 9,
9, 5,
//TL edge lines
1, 5,
4, 5,
//TR edge lines
2, 6,
6, 7,
//BL edge lines
8, 9,
9, 13,
//BR edge lines
10, 14,
10, 11
@ -539,7 +539,7 @@ vertex SolidColorVertex vertex_lines(
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(in.P, 1.0);
out.positionOut.z -= 0.001;
if(idx > 22) {
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
const constant uint GregoryBasisControlLineIndices[] = {
//Outer Edge
0, 2,
0, 2,
2, 16,
16, 15,
15, 17,
17, 11,
17, 11,
11, 10,
10, 12,
10, 12,
12, 6,
6, 5,
5, 7,
5, 7,
7, 1,
1, 0,
1, 0,
//Outside-Inside Edges
1, 3,
@ -581,7 +581,7 @@ const constant uint GregoryBasisControlLineIndices[] = {
//Inner Edge
3, 4,
4, 18,
18, 19,
18, 19,
19, 13,
13, 14,
14, 8,
@ -603,7 +603,7 @@ vertex SolidColorVertex vertex_lines(
{
const auto idx_size = sizeof(GregoryBasisControlLineIndices) / sizeof(GregoryBasisControlLineIndices[0]);
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
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));
OutputVertex out;
out.position = (frameConsts.ModelViewMatrix * float4(position, 1.0)).xyz;
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(position, 1.0);
out.normal = (frameConsts.ModelViewMatrix * float4(normal, 0.0)).xyz;
#if SHADING_TYPE == SHADING_TYPE_PATCH || SHADING_TYPE == SHADING_TYPE_PATCH_COORD
out.patchColor = out.normal;
#elif SHADING_TYPE == SHADING_TYPE_FACE_VARYING
@ -679,7 +679,7 @@ vertex OutputVertex vertex_main(
#endif
return out;
}
}
vertex SolidColorVertex vertex_lines(
device unsigned* indicesBuffer [[buffer(INDICES_BUFFER_INDEX)]],
@ -702,9 +702,9 @@ vertex SolidColorVertex vertex_lines(
SolidColorVertex out;
out.positionOut = frameConsts.ModelViewProjectionMatrix * float4(position, 1.0);
return out;
}
}
#endif
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)]])
{
float4 color;
#if SHADING_TYPE == SHADING_TYPE_MATERIAL
const float3 diffuseColor = float3(0.4f, 0.4f, 0.8f);
#elif SHADING_TYPE == SHADING_TYPE_PATCH

View File

@ -134,18 +134,18 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
@implementation OSDRenderer {
MTLRingBuffer<Light, 1> _lightsBuffer;
PerFrameBuffer<PerFrameConstants> _frameConstantsBuffer;
PerFrameBuffer<MTLQuadTessellationFactorsHalf> _tessFactorsBuffer;
PerFrameBuffer<unsigned> _patchIndexBuffers[4];
PerFrameBuffer<uint8_t> _perPatchDataBuffer;
PerFrameBuffer<uint8_t> _hsDataBuffer;
PerFrameBuffer<MTLDrawPatchIndirectArguments> _drawIndirectCommandsBuffer;
unsigned _tessFactorOffsets[4];
unsigned _perPatchDataOffsets[4];
unsigned _threadgroupSizes[10];
id<MTLComputePipelineState> _computePipelines[10];
id<MTLRenderPipelineState> _renderPipelines[10];
id<MTLRenderPipelineState> _controlLineRenderPipelines[10];
@ -157,11 +157,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
id<MTLBuffer> _faceVaryingIndicesBuffer;
id<MTLBuffer> _faceVaryingPatchParamBuffer;
Camera _cameraData;
Osd::MTLContext _context;
int _numVertexElements;
int _numVaryingElements;
int _numFaceVaryingElements;
@ -173,7 +173,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
std::unique_ptr<MTLControlMeshDisplay> _controlMesh;
std::unique_ptr<Osd::MTLLegacyGregoryPatchTable> _legacyGregoryPatchTable;
std::unique_ptr<Shape> _shape;
bool _needsRebuild;
NSString* _osdShaderSource;
simd::float3 _meshCenter;
@ -206,17 +206,17 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
self.tessellationLevel = 8;
self.shadingMode = kShadingMaterial;
self.displayStyle = kDisplayStyleShaded;
_frameCount = 0;
_animationFrames = 0;
_delegate = delegate;
_context.device = [delegate deviceFor:self];
_context.commandQueue = [delegate commandQueueFor:self];
_osdShaderSource = @(shaderSource);
_needsRebuild = true;
[self _initializeBuffers];
[self _initializeCamera];
[self _initializeLights];
@ -235,7 +235,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
_animatedVertices.resize(_vertexData.size());
auto p = _vertexData.data();
auto n = _animatedVertices.data();
int numElements = _numVertexElements + _numVaryingElements;
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[1] = -p[0]*st + p[1]*ct;
n[2] = p[2];
for (int j = 0; j < _numVaryingElements; ++j) {
n[3 + j] = p[3 + j];
}
@ -254,30 +254,30 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
p += numElements;
n += numElements;
}
_mesh->UpdateVertexBuffer(_animatedVertices.data(), 0, _numVertices);
_animationFrames++;
}
_mesh->Refine();
_mesh->Synchronize();
}
[self _updateState];
if(_doAdaptive) {
auto computeEncoder = [commandBuffer computeCommandEncoder];
[self _computeTessFactors:computeEncoder];
[computeEncoder endEncoding];
}
auto renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:[_delegate renderPassDescriptorFor: self]];
if(_usePrimitiveBackfaceCulling) {
[renderEncoder setCullMode:MTLCullModeBack];
} else {
[renderEncoder setCullMode:MTLCullModeNone];
}
[self _renderMesh:renderEncoder];
_frameConstantsBuffer.next();
@ -290,20 +290,20 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
_perPatchDataBuffer.next();
_hsDataBuffer.next();
_drawIndirectCommandsBuffer.next();
_frameCount++;
return renderEncoder;
}
-(void)_renderMesh:(id<MTLRenderCommandEncoder>)renderCommandEncoder {
auto buffer = _mesh->BindVertexBuffer();
assert(buffer);
auto pav = _mesh->GetPatchTable()->GetPatchArrays();
auto pib = _mesh->GetPatchTable()->GetPatchIndexBuffer();
auto pfvarav = _mesh->GetPatchTable()->GetFVarPatchArrays();
[renderCommandEncoder setVertexBuffer:buffer offset:0 atIndex:VERTEX_BUFFER_INDEX];
[renderCommandEncoder setVertexBuffer:pib offset:0 atIndex:INDICES_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];
#endif
[renderCommandEncoder setVertexBuffer:_faceVaryingIndicesBuffer offset:0 atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
if(_doAdaptive)
{
[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:_faceVaryingPatchParamBuffer offset:0 atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
}
if(_endCapMode == kEndCapLegacyGregory)
{
[renderCommandEncoder setVertexBuffer:_legacyGregoryPatchTable->GetQuadOffsetsBuffer() offset:0 atIndex:OSD_QUADOFFSET_BUFFER_INDEX];
[renderCommandEncoder setVertexBuffer:_legacyGregoryPatchTable->GetVertexValenceBuffer() offset:0 atIndex:OSD_VALENCE_BUFFER_INDEX];
}
[renderCommandEncoder setFragmentBuffer:_lightsBuffer offset:0 atIndex:0];
if(_displayStyle == kDisplayStyleWire)
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
else
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
std::fill_n(_patchCounts, 12, 0);
for(int i = 0; i < pav.size(); i++)
{
auto& patch = pav[i];
auto d = patch.GetDescriptor();
auto patchType = d.GetType();
auto offset = patchType - Far::PatchDescriptor::REGULAR;
_patchCounts[patchType] = patch.GetNumPatches();
if(_doAdaptive)
{
[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.indexBase+(patch.primitiveIdBase*fvarPatch.desc.GetNumControlVertices())) * sizeof(unsigned) atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
}
[renderCommandEncoder setVertexBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
simd::float4 shade{.0f,0.0f,0.0f,1.0f};
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
[renderCommandEncoder setDepthBias:0 slopeScale:1.0 clamp:0];
[renderCommandEncoder setDepthStencilState:_readWriteDepthStencilState];
[renderCommandEncoder setRenderPipelineState:_renderPipelines[patchType]];
switch(patchType)
{
case Far::PatchDescriptor::GREGORY_BOUNDARY:
@ -378,7 +378,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
break;
default: break;
}
switch(patchType)
{
case Far::PatchDescriptor::GREGORY_BASIS:
@ -405,7 +405,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
if(_usePatchIndexBuffer)
{
[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)
instanceCount:1 baseInstance:0];
}
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
}
break;
@ -442,14 +442,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
}
if(_displayStyle == kDisplayStyleWireOnShaded)
{
simd::float4 shade = {1, 1,1,1};
[renderCommandEncoder setFragmentBytes:&shade length:sizeof(shade) atIndex:2];
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeLines];
[renderCommandEncoder setDepthBias:-5 slopeScale:-1.0 clamp:-100.0];
#if !TARGET_OS_EMBEDDED
if(_usePatchIndexBuffer)
{
@ -463,13 +463,13 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[renderCommandEncoder drawPatches:d.GetNumControlVertices() patchStart:0 patchCount:patch.GetNumPatches()
patchIndexBuffer:nil patchIndexBufferOffset:0 instanceCount:1 baseInstance:0];
}
[renderCommandEncoder setTriangleFillMode:MTLTriangleFillModeFill];
}
}
break;
case Far::PatchDescriptor::QUADS:
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:patch.GetNumPatches() * 6];
if(_displayStyle == kDisplayStyleWireOnShaded)
@ -498,13 +498,13 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
default:
assert("Unsupported patch type" && 0); break;
}
if(_displayControlMeshEdges)
{
if(_displayControlMeshEdges && _controlLineRenderPipelines[patchType])
{
[renderCommandEncoder setRenderPipelineState:_controlLineRenderPipelines[patchType]];
unsigned primPerPatch = 0;
switch(patchType)
{
@ -517,12 +517,12 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
primPerPatch = 56;
break;
}
[renderCommandEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:patch.GetNumPatches() * primPerPatch];
}
}
}
if(_displayControlMeshEdges)
{
[renderCommandEncoder setDepthStencilState:_readOnlyDepthStencilState];
@ -532,7 +532,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
-(void)_computeTessFactors:(id<MTLComputeCommandEncoder>)computeCommandEncoder {
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
[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()->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:_frameConstantsBuffer offset:0 atIndex:FRAME_CONST_BUFFER_INDEX];
[computeCommandEncoder setBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
if(_legacyGregoryPatchTable)
{
[computeCommandEncoder setBuffer:_legacyGregoryPatchTable->GetQuadOffsetsBuffer() offset:0 atIndex:OSD_QUADOFFSET_BUFFER_INDEX];
[computeCommandEncoder setBuffer:_legacyGregoryPatchTable->GetVertexValenceBuffer() offset:0 atIndex:OSD_VALENCE_BUFFER_INDEX];
}
for(auto& patch : patchArray)
{
auto usefulControlPoints = patch.GetDescriptor().GetNumControlVertices();
if(patch.GetDescriptor().GetType() == Far::PatchDescriptor::GREGORY_BASIS)
usefulControlPoints = 4;
auto threadsPerThreadgroup = MTLSizeMake(_threadgroupSizes[patch.desc.GetType()], 1, 1);
auto threadsPerControlPoint = std::max<int>(1, usefulControlPoints / threadsPerThreadgroup.width);
auto groupPerControlPoint = MTLSizeMake(patch.GetNumPatches() * usefulControlPoints, 1, 1);
groupPerControlPoint.width /= threadsPerControlPoint;
groupPerControlPoint.width = (groupPerControlPoint.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
groupPerControlPoint.width = groupPerControlPoint.width / threadsPerThreadgroup.width;
auto groupPerPatch = MTLSizeMake(patch.GetNumPatches(), 1, 1);
groupPerPatch.width = (groupPerPatch.width + threadsPerThreadgroup.width - 1) & ~(threadsPerThreadgroup.width - 1);
groupPerPatch.width = groupPerPatch.width / threadsPerThreadgroup.width;
[computeCommandEncoder setBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
[computeCommandEncoder setBufferOffset:patch.indexBase * sizeof(unsigned) atIndex:INDICES_BUFFER_INDEX];
if(_usePatchIndexBuffer)
{
[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 setComputePipelineState:_computePipelines[patch.desc.GetType()]];
unsigned kernelExecutionLimit;
switch(patch.desc.GetType())
{
@ -608,7 +608,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
break;
default: assert("Unsupported patch type" && 0); break;
}
[computeCommandEncoder setBytes:&kernelExecutionLimit length:sizeof(kernelExecutionLimit) atIndex:OSD_KERNELLIMIT_BUFFER_INDEX];
[computeCommandEncoder dispatchThreadgroups:groupPerControlPoint threadsPerThreadgroup:threadsPerThreadgroup];
}
@ -618,12 +618,12 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[self _rebuildModel];
[self _rebuildBuffers];
[self _rebuildPipelines];
_needsRebuild = false;
}
-(void)_rebuildModel {
using namespace OpenSubdiv;
using namespace Sdc;
using namespace Osd;
@ -631,7 +631,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
auto shapeDesc = &g_defaultShapes[[_loadedModels indexOfObject:_currentModel]];
_shape.reset(Shape::parseObj(shapeDesc->data.c_str(), shapeDesc->scheme));
const auto scheme = shapeDesc->scheme;
// create Far mesh (topology)
Sdc::SchemeType sdctype = GetSdcType(*_shape);
Sdc::Options sdcoptions = GetSdcOptions(*_shape);
@ -640,17 +640,17 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
std::unique_ptr<OpenSubdiv::Far::TopologyRefiner> refiner;
refiner.reset(Far::TopologyRefinerFactory<Shape>::Create(*_shape, Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions)));
// save coarse topology (used for coarse mesh drawing)
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
_numVertices = refBaseLevel.GetNumVertices();
// Adaptive refinement currently supported only for catmull-clark scheme
_doAdaptive = (_useAdaptive && scheme == kCatmark);
bool doSingleCreasePatch = (_useSingleCrease && scheme == kCatmark);
bool doInfSharpPatch = (_useInfinitelySharpPatch && scheme == kCatmark);
Osd::MeshBitset bits;
bits.set(Osd::MeshAdaptive, _doAdaptive);
bits.set(Osd::MeshUseSingleCreasePatch, doSingleCreasePatch);
@ -658,7 +658,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
bits.set(Osd::MeshEndCapBSplineBasis, _endCapMode == kEndCapBSplineBasis);
bits.set(Osd::MeshEndCapGregoryBasis, _endCapMode == kEndCapGregoryBasis);
bits.set(Osd::MeshEndCapLegacyGregory, _endCapMode == kEndCapLegacyGregory);
int level = _refinementLevel;
_numVertexElements = 3;
@ -675,7 +675,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
bits.set(OpenSubdiv::Osd::MeshFVarAdaptive, _doAdaptive);
int numElements = _numVertexElements + _numVaryingElements;
if(_kernelType == kCPU)
{
_mesh.reset(new CPUMeshType(refiner.get(),
@ -690,11 +690,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
_numVaryingElements,
level, bits, nullptr, &_context));
}
MTLRenderPipelineDescriptor* desc = [MTLRenderPipelineDescriptor new];
[_delegate setupRenderPipelineState:desc for:self];
const auto vertexDescriptor = desc.vertexDescriptor;
vertexDescriptor.layouts[0].stride = sizeof(float) * numElements;
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
@ -702,36 +702,36 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3;
vertexDescriptor.attributes[0].offset = 0;
vertexDescriptor.attributes[0].bufferIndex = 0;
_controlMesh.reset(new MTLControlMeshDisplay(_context.device, desc));
_controlMesh->SetTopology(refBaseLevel);
_controlMesh->SetEdgesDisplay(true);
_controlMesh->SetVerticesDisplay(false);
_legacyGregoryPatchTable.reset();
if(_endCapMode == kEndCapLegacyGregory)
{
_legacyGregoryPatchTable.reset(Osd::MTLLegacyGregoryPatchTable::Create(_mesh->GetFarPatchTable(),
&_context));
}
_vertexData.resize(refBaseLevel.GetNumVertices() * numElements);
_meshCenter = simd::float3{0,0,0};
for(int i = 0; i < refBaseLevel.GetNumVertices(); i++)
{
_vertexData[i * numElements + 0] = _shape->verts[i * 3 + 0];
_vertexData[i * numElements + 1] = _shape->verts[i * 3 + 1];
_vertexData[i * numElements + 2] = _shape->verts[i * 3 + 2];
}
for(auto vertexIdx = 0; vertexIdx < refBaseLevel.GetNumVertices(); vertexIdx++)
{
_meshCenter[0] += _vertexData[vertexIdx * numElements + 0];
_meshCenter[1] += _vertexData[vertexIdx * numElements + 1];
_meshCenter[2] += _vertexData[vertexIdx * numElements + 2];
}
_meshCenter /= (_shape->verts.size() / 3);
_mesh->UpdateVertexBuffer(_vertexData.data(), 0, refBaseLevel.GetNumVertices());
_mesh->Refine();
@ -825,9 +825,9 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
-(void)_updateState {
[self _updateCamera];
auto pData = _frameConstantsBuffer.data();
pData->TessLevel = _tessellationLevel;
if(_doAdaptive)
{
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;
}
}
if(_usePatchIndexBuffer)
{
_drawIndirectCommandsBuffer.markModified();
@ -855,19 +855,19 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
auto totalPatches = 0;
auto totalVertices = 0;
auto totalPatchDataSize = 0;
if(_usePatchIndexBuffer)
{
_drawIndirectCommandsBuffer.alloc(_context.device, 4, @"draw patch indirect commands");
}
if(_doAdaptive)
{
auto& patchArray = _mesh->GetPatchTable()->GetPatchArrays();
for(auto& patch : patchArray)
{
auto patchDescriptor = patch.GetDescriptor();
switch(patch.desc.GetType())
{
case Far::PatchDescriptor::REGULAR: {
@ -881,7 +881,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
float elementFloats = 3;
if(_useSingleCrease)
elementFloats += 6;
totalPatchDataSize += elementFloats * sizeof(float) * patch.GetNumPatches() * patch.desc.GetNumControlVertices(); // OsdPerPatchVertexBezier
}
@ -918,15 +918,15 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
break;
}
totalPatches += patch.GetNumPatches();
totalVertices += patch.GetDescriptor().GetNumControlVertices() * patch.GetNumPatches();
}
_perPatchDataBuffer.alloc(_context.device, totalPatchDataSize, @"per patch data", MTLResourceStorageModePrivate);
_hsDataBuffer.alloc(_context.device, 20 * sizeof(float) * totalPatches, @"hs constant data", MTLResourceStorageModePrivate);
_tessFactorsBuffer.alloc(_context.device, totalPatches, @"tessellation factors buffer", MTLResourceStorageModePrivate);
}
}
@ -936,7 +936,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
_renderPipelines[i] = nil;
_renderControlEdgesPipeline = nil;
}
Osd::MTLPatchShaderSource shaderSource;
auto patchArrays = _mesh->GetPatchTable()->GetPatchArrays();
auto pFVarArray = _mesh->GetPatchTable()->GetFVarPatchArrays();
@ -947,7 +947,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
auto& threadsPerThreadgroup = _threadgroupSizes[type];
threadsPerThreadgroup = 32; //Initial guess of 32
int usefulControlPoints = patchArrays[i].GetDescriptor().GetNumControlVertices();
auto compileOptions = [[MTLCompileOptions alloc] init];
auto preprocessor = [[NSMutableDictionary alloc] init];
@ -981,11 +981,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
usefulControlPoints = 4;
break;
}
#if TARGET_OS_EMBEDDED
shaderBuilder << "#define OSD_UV_CORRECTION if(t > 0.5){ ti += 0.01f; } else { ti += 0.01f; }\n";
#endif
//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);
if(_numFaceVaryingElements > 0)
shaderBuilder << shaderSource.GetPatchBasisShaderSource();
shaderBuilder << _osdShaderSource.UTF8String;
const auto str = shaderBuilder.str();
int numElements = _numVertexElements + _numVaryingElements;
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);
auto partitionMode = _useFractionalTessellation ? MTLTessellationPartitionModeFractionalOdd : MTLTessellationPartitionModePow2;
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
DEFINE(OSD_MAX_TESS_LEVEL, 16);
#else
@ -1050,7 +1050,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
DEFINE(OSD_FVAR_PATCHPARAM_BUFFER_INDEX, OSD_FVAR_PATCHPARAM_BUFFER_INDEX);
compileOptions.preprocessorMacros = preprocessor;
NSError* err = nil;
auto librarySource = [NSString stringWithUTF8String:str.data()];
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"];
if(vertexFunction && fragmentFunction)
{
MTLRenderPipelineDescriptor* pipelineDesc = [[MTLRenderPipelineDescriptor alloc] init];
pipelineDesc.tessellationFactorFormat = MTLTessellationFactorFormatHalf;
pipelineDesc.tessellationPartitionMode = partitionMode;
pipelineDesc.tessellationFactorScaleEnabled = false;
pipelineDesc.tessellationFactorStepFunction = MTLTessellationFactorStepFunctionPerPatch;
if(type == Far::PatchDescriptor::GREGORY_BASIS && _useStageIn)
pipelineDesc.tessellationControlPointIndexType = MTLTessellationControlPointIndexTypeUInt32;
[_delegate setupRenderPipelineState:pipelineDesc for:self];
{
pipelineDesc.fragmentFunction = [library newFunctionWithName:@"fragment_solidcolor"];
pipelineDesc.vertexFunction = [library newFunctionWithName:@"vertex_lines"];
if(pipelineDesc.vertexFunction)
_controlLineRenderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
else
_controlLineRenderPipelines[type] = nil;
}
pipelineDesc.fragmentFunction = fragmentFunction;
pipelineDesc.vertexFunction = vertexFunction;
if(_useStageIn)
{
auto vertexDesc = pipelineDesc.vertexDescriptor;
[vertexDesc reset];
if(_doAdaptive)
{
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stride = sizeof(int) * 3;
// PatchInput :: int3 patchParam [[attribute(10)]];
vertexDesc.attributes[10].bufferIndex = OSD_PATCHPARAM_BUFFER_INDEX;
vertexDesc.attributes[10].format = MTLVertexFormatInt3;
vertexDesc.attributes[10].offset = 0;
}
switch(type)
{
case Far::PatchDescriptor::REGULAR:
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride = sizeof(float) * 3;
// ControlPoint :: float3 P [[attribute(0)]];
// OsdPerPatchVertexBezier :: packed_float3 P
vertexDesc.attributes[0].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
vertexDesc.attributes[0].offset = 0;
if(_useSingleCrease)
{
vertexDesc.layouts[OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX].stride += sizeof(float) * 3 * 2;
// ControlPoint :: float3 P1 [[attribute(1)]];
// OsdPerPatchVertexBezier :: packed_float3 P1
vertexDesc.attributes[1].bufferIndex = OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX;
vertexDesc.attributes[1].format = MTLVertexFormatFloat3;
vertexDesc.attributes[1].offset = sizeof(float) * 3;
// ControlPoint :: float3 P2 [[attribute(2)]];
// OsdPerPatchVertexBezier :: packed_float3 P2
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
}
if(_useScreenspaceTessellation)
{
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PERPATCHTESSFACTORS_BUFFER_INDEX].stride = sizeof(float) * 4 * 2;
// PatchInput :: float4 tessOuterLo [[attribute(5)]];
// OsdPerPatchTessFactors :: float4 tessOuterLo;
vertexDesc.attributes[5].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
vertexDesc.attributes[5].format = MTLVertexFormatFloat4;
vertexDesc.attributes[5].offset = 0;
// PatchInput :: float4 tessOuterHi [[attribute(6)]];
// OsdPerPatchTessFactors :: float4 tessOuterHi;
vertexDesc.attributes[6].bufferIndex = OSD_PERPATCHTESSFACTORS_BUFFER_INDEX;
@ -1157,11 +1157,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
break;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
case Far::PatchDescriptor::GREGORY:
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stepRate = 1;
vertexDesc.layouts[OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX].stride = sizeof(float) * 3 * 5;
// ControlPoint :: float3 P [[attribute(0)]];
// ControlPoint :: float3 Ep [[attribute(1)]];
// 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].stepRate = 1;
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stride = sizeof(float) * 3;
// ControlPoint :: float3 position [[attribute(0)]];
vertexDesc.attributes[0].bufferIndex = VERTEX_BUFFER_INDEX;
vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
@ -1192,16 +1192,16 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[vertexDesc reset];
break;
}
}
_renderPipelines[type] = [_context.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&err];
if(!_renderPipelines[type] && err)
{
NSLog(@"%s", [[err localizedDescription] UTF8String]);
}
}
auto computeFunction = [library newFunctionWithName:@"compute_main"];
if(computeFunction)
{
@ -1212,69 +1212,69 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
#endif
computeDesc.computeFunction = computeFunction;
NSError* err;
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
if(err && _computePipelines[type] == nil)
{
NSLog(@"%s", [[err description] UTF8String]);
}
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
{
DEFINE(THREADS_PER_THREADGROUP, _computePipelines[type].threadExecutionWidth);
DEFINE(CONTROL_POINTS_PER_THREAD, std::max<int>(1, usefulControlPoints / _computePipelines[type].threadExecutionWidth));
compileOptions.preprocessorMacros = preprocessor;
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
assert(library);
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = true;
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
if(_computePipelines[type].threadExecutionWidth != threadsPerThreadgroup)
{
DEFINE(THREADS_PER_THREADGROUP, threadsPerThreadgroup);
DEFINE(CONTROL_POINTS_PER_THREAD, std::max<int>(1, usefulControlPoints / threadsPerThreadgroup));
DEFINE(NEEDS_BARRIER, 1);
compileOptions.preprocessorMacros = preprocessor;
library = [_context.device newLibraryWithSource:librarySource options:compileOptions error:nil];
assert(library);
computeDesc.threadGroupSizeIsMultipleOfThreadExecutionWidth = false;
computeDesc.computeFunction = [library newFunctionWithName:@"compute_main"];
threadsPerThreadgroup = _computePipelines[type].threadExecutionWidth;
_computePipelines[type] = [_context.device newComputePipelineStateWithDescriptor:computeDesc options:MTLPipelineOptionNone reflection:nil error:&err];
}
}
}
}
MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init];
depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess;
[_delegate setupDepthStencilState:depthStencilDesc for:self];
depthStencilDesc.depthWriteEnabled = YES;
_readWriteDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
depthStencilDesc.depthWriteEnabled = NO;
_readOnlyDepthStencilState = [_context.device newDepthStencilStateWithDescriptor:depthStencilDesc];
}
-(void)_updateCamera {
auto pData = _frameConstantsBuffer.data();
identity(pData->ModelViewMatrix);
translate(pData->ModelViewMatrix, 0, 0, -_cameraData.dollyDistance);
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
rotate(pData->ModelViewMatrix, -90, 1, 0, 0); // z-up model
inverseMatrix(pData->ModelViewInverseMatrix, pData->ModelViewMatrix);
identity(pData->ProjectionMatrix);
perspective(pData->ProjectionMatrix, 45.0, _cameraData.aspectRatio, 0.01f, 500.0);
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.8f, 0.8f, 0.8f, 1.0f },
};
_lightsBuffer[1] = {
simd::normalize(simd::float4{ -0.8f, 0.4f, -1.0f, 0.0f }),
{ 0.0f, 0.0f, 0.0f, 1.0f },
{ 0.5f, 0.5f, 0.5f, 1.0f },
{ 0.8f, 0.8f, 0.8f, 1.0f }
};
_lightsBuffer.markModified();
}

View File

@ -32,21 +32,22 @@
@protocol MTLDevice;
@protocol MTLCommandQueue;
namespace OpenSubdiv
{
namespace OPENSUBDIV_VERSION
{
namespace Osd
{
class MTLContext
{
public:
id<MTLDevice> device = nullptr;
id<MTLCommandQueue> commandQueue = nullptr;
};
}
}
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
class MTLContext {
public:
id<MTLDevice> device = nullptr;
id<MTLCommandQueue> commandQueue = nullptr;
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
}
} // end namespace OpenSubdiv
#endif //OPENSUBDIV3_OSD_MTL_COMMON_H

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,6 @@
#include "../far/stencilTable.h"
#include "../far/error.h"
#define PARAMETER_BUFFER_INDEX 0
#define SIZES_BUFFER_INDEX 1
#define OFFSETS_BUFFER_INDEX 2
@ -141,73 +139,73 @@ using namespace Osd;
MTLStencilTable::MTLStencilTable(Far::StencilTable const *stencilTable,
MTLContext* context)
{
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
_numStencils = stencilTable->GetNumStencils();
if (_numStencils > 0)
{
auto sizes = stencilTable->GetSizes();
_numStencils = stencilTable->GetNumStencils();
if (_numStencils > 0)
{
auto sizes = stencilTable->GetSizes();
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
_sizesBuffer.label = @"StencilTable Sizes";
_offsetsBuffer.label = @"StencilTable Offsets";
_indicesBuffer.label = @"StencilTable Indices";
_weightsBuffer.label = @"StencilTable Weights";
}
_sizesBuffer.label = @"StencilTable Sizes";
_offsetsBuffer.label = @"StencilTable Offsets";
_indicesBuffer.label = @"StencilTable Indices";
_weightsBuffer.label = @"StencilTable Weights";
}
_duWeightsBuffer = nil;
_dvWeightsBuffer = nil;
_duuWeightsBuffer = nil;
_duvWeightsBuffer = nil;
_dvvWeightsBuffer = nil;
_duWeightsBuffer = nil;
_dvWeightsBuffer = nil;
_duuWeightsBuffer = nil;
_duvWeightsBuffer = nil;
_dvvWeightsBuffer = nil;
}
MTLStencilTable::MTLStencilTable(Far::LimitStencilTable const *stencilTable,
MTLContext* context)
{
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
_numStencils = stencilTable->GetNumStencils();
if (_numStencils > 0)
{
auto sizes = stencilTable->GetSizes();
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
_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);
_numStencils = stencilTable->GetNumStencils();
if (_numStencils > 0)
{
auto sizes = stencilTable->GetSizes();
_sizesBuffer.label = @"StencilTable Sizes";
_offsetsBuffer.label = @"StencilTable Offsets";
_indicesBuffer.label = @"StencilTable Indices";
_weightsBuffer.label = @"StencilTable Weights";
if (_duWeightsBuffer) {
_duWeightsBuffer.label = @"StencilTable duWeights";
_sizesBuffer = createBuffer(stencilTable->GetSizes(), context);
_offsetsBuffer = createBuffer(stencilTable->GetOffsets(), context);
_indicesBuffer = createBuffer(stencilTable->GetControlIndices(), context);
_weightsBuffer = createBuffer(stencilTable->GetWeights(), context);
_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";
_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() {}
@ -217,20 +215,20 @@ MTLComputeEvaluator *MTLComputeEvaluator::Create(
BufferDescriptor const &duDesc, BufferDescriptor const &dvDesc,
MTLContext* context)
{
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
auto instance = new MTLComputeEvaluator();
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
BufferDescriptor(),
BufferDescriptor(),
BufferDescriptor(),
context))
return instance;
auto instance = new MTLComputeEvaluator();
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
BufferDescriptor(),
BufferDescriptor(),
BufferDescriptor(),
context))
return instance;
delete instance;
delete instance;
return nullptr;
return nullptr;
}
MTLComputeEvaluator *MTLComputeEvaluator::Create(
@ -239,17 +237,18 @@ MTLComputeEvaluator *MTLComputeEvaluator::Create(
BufferDescriptor const &duuDesc, BufferDescriptor const &duvDesc, BufferDescriptor const &dvvDesc,
MTLContext* context)
{
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
assert(context != nil);
assert(context->device != nil && context->commandQueue != nil);
auto instance = new MTLComputeEvaluator();
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
duuDesc, duvDesc, dvvDesc, context))
return instance;
auto instance = new MTLComputeEvaluator();
if (instance->Compile(srcDesc, dstDesc, duDesc, dvDesc,
duuDesc, duvDesc, dvvDesc, context)) {
return instance;
}
delete instance;
delete instance;
return nullptr;
return nullptr;
}
bool MTLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
@ -321,7 +320,7 @@ bool MTLComputeEvaluator::Compile(BufferDescriptor const &srcDesc,
#if !__has_feature(objc_arc)
[compileOptions release];
#endif
if (!_computeLibrary)
{
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"];
_evalStencils =
[context->device newComputePipelineStateWithFunction:evalStencilsFunction
error:&err];
#if !__has_feature(objc_arc)
[evalStencilsFunction release];
#endif
if (!_evalStencils)
{
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 =
[context->device newComputePipelineStateWithFunction:evalPatchesFunction
error:&err];
#if !__has_feature(objc_arc)
[evalPatchesFunction release];
#endif
if (!_evalPatches)
{
Far::Error(Far::FAR_RUNTIME_ERROR, "Error compiling MTL Pipeline eval_patches: %s\n",
@ -444,7 +442,7 @@ bool MTLComputeEvaluator::EvalStencils(
return true;
assert(context != nullptr);
auto device = context->device;
auto commandQueue = context->commandQueue;
@ -556,7 +554,7 @@ MTLComputeEvaluator::EvalPatches(
return false;
assert(context != nullptr);
auto device = context->device;
auto commandQueue = context->commandQueue;
@ -609,5 +607,6 @@ MTLComputeEvaluator::EvalPatches(
}
} //end namespace Osd
} //end namespace OPENSUBDIV_VERSION
} //end namespace OpenSubdiv

View File

@ -315,6 +315,4 @@ kernel void eval_patches(
if(args.dvvDesc.y > 0)
writeDvv(current, dvv, dvvDerivativeBuffer, args);
#endif
}

View File

@ -33,58 +33,60 @@
@protocol MTLDevice;
@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
{
class MTLLegacyGregoryPatchTable
: private NonCopyable<MTLLegacyGregoryPatchTable>
{
public:
~MTLLegacyGregoryPatchTable();
return _vertexBuffer;
}
template<typename DEVICE_CONTEXT>
static MTLLegacyGregoryPatchTable* Create(Far::PatchTable const* farPatchTable, DEVICE_CONTEXT context) {
return Create(farPatchTable, context);
}
id<MTLBuffer> GetVertexValenceBuffer() const
{
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
{
return _vertexBuffer;
}
private:
id<MTLBuffer> _vertexBuffer;
id<MTLBuffer> _vertexValenceBuffer;
id<MTLBuffer> _quadOffsetsBuffer;
int _quadOffsetsBase[2];
};
id<MTLBuffer> GetVertexValenceBuffer() const
{
return _vertexValenceBuffer;
}
} //end namespace Osd
id<MTLBuffer> GetQuadOffsetsBuffer() const
{
return _quadOffsetsBuffer;
}
} //end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
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
#endif // OPENSUBDIV3_OSD_MTL_LEGACY_GREGORY_PATCH_TABLE_H

View File

@ -96,5 +96,6 @@ void MTLLegacyGregoryPatchTable::UpdateVertexBuffer(id<MTLBuffer> vbo, int numVe
}
} //end namespace Osd
} //end namespace OPENSUBDIV_VERSION
} //end namespace OpenSubdiv

View File

@ -30,17 +30,18 @@
#include "../osd/mtlPatchTable.h"
namespace OpenSubdiv
{
namespace OPENSUBDIV_VERSION
{
namespace Osd
{
typedef MeshInterface<MTLPatchTable> MTLMeshInterface;
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
typedef MeshInterface<MTLPatchTable> MTLMeshInterface;
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_MTL_MESH_H

View File

@ -29,23 +29,23 @@
//----------------------------------------------------------
void OsdComputePerVertex(
float4 vertexPosition,
threadgroup HullVertex& hullVertex,
int vertexId,
float4x4 ModelViewProjectionMatrix,
OsdPatchParamBufferSet osdBuffers
)
float4 vertexPosition,
threadgroup HullVertex& hullVertex,
int vertexId,
float4x4 ModelViewProjectionMatrix,
OsdPatchParamBufferSet osdBuffers
)
{
hullVertex.position = vertexPosition;
#if OSD_ENABLE_PATCH_CULL
float4 clipPos = mul(ModelViewProjectionMatrix, vertexPosition);
short3 clip0 = short3(clipPos.x < clipPos.w,
clipPos.y < clipPos.w,
clipPos.z < clipPos.w);
short3 clip1 = short3(clipPos.x > -clipPos.w,
clipPos.y > -clipPos.w,
clipPos.z > -clipPos.w);
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
float4 clipPos = mul(ModelViewProjectionMatrix, vertexPosition);
short3 clip0 = short3(clipPos.x < clipPos.w,
clipPos.y < clipPos.w,
clipPos.z < clipPos.w);
short3 clip1 = short3(clipPos.x > -clipPos.w,
clipPos.y > -clipPos.w,
clipPos.z > -clipPos.w);
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
#endif
}
@ -54,16 +54,16 @@ void OsdComputePerVertex(
//----------------------------------------------------------
void OsdComputePerPatchBSplineFactors(
int3 patchParam,
float tessLevel,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
device OsdPerPatchVertexBezier* patch
int3 patchParam,
float tessLevel,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
device OsdPerPatchVertexBezier* patch
#if !USE_PTVS_FACTORS
,device OsdPerPatchTessFactors& patchFactors
,device OsdPerPatchTessFactors& patchFactors
#endif
,device MTLQuadTessellationFactorsHalf& quadFactors
)
,device MTLQuadTessellationFactorsHalf& quadFactors
)
{
float4 tessLevelOuter = float4(0,0,0,0);
float2 tessLevelInner = float2(0,0);
@ -72,8 +72,8 @@ void OsdComputePerPatchBSplineFactors(
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
OsdGetTessLevelsAdaptiveLimitPoints(
tessLevel,
projectionMatrix,
tessLevel,
projectionMatrix,
modelViewMatrix,
patch,
patchParam,
@ -84,8 +84,8 @@ void OsdComputePerPatchBSplineFactors(
);
#else
OsdGetTessLevelsUniform(
tessLevel,
patchParam,
tessLevel,
patchParam,
tessLevelOuter,
tessLevelInner,
tessOuterLo,
@ -106,27 +106,27 @@ void OsdComputePerPatchBSplineFactors(
}
void OsdComputePerPatchFactors(
int3 patchParam,
float tessLevel,
unsigned patchID,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
OsdPatchParamBufferSet osdBuffer,
threadgroup PatchVertexType* patchVertices,
device MTLQuadTessellationFactorsHalf& quadFactors
)
int3 patchParam,
float tessLevel,
unsigned patchID,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
OsdPatchParamBufferSet osdBuffer,
threadgroup PatchVertexType* patchVertices,
device MTLQuadTessellationFactorsHalf& quadFactors
)
{
OsdComputePerPatchBSplineFactors(
patchParam,
tessLevel,
projectionMatrix,
modelViewMatrix,
osdBuffer.perPatchVertexBuffer + patchID * CONTROL_POINTS_PER_PATCH,
OsdComputePerPatchBSplineFactors(
patchParam,
tessLevel,
projectionMatrix,
modelViewMatrix,
osdBuffer.perPatchVertexBuffer + patchID * CONTROL_POINTS_PER_PATCH,
#if !USE_PTVS_FACTORS
osdBuffer.patchTessBuffer[patchID],
osdBuffer.patchTessBuffer[patchID],
#endif
quadFactors
);
quadFactors
);
}
//----------------------------------------------------------
@ -134,15 +134,16 @@ void OsdComputePerPatchFactors(
//----------------------------------------------------------
void OsdComputePerPatchVertex(
int3 patchParam,
unsigned ID,
unsigned PrimitiveID,
unsigned ControlID,
threadgroup PatchVertexType* patchVertices,
OsdPatchParamBufferSet osdBuffers
)
int3 patchParam,
unsigned ID,
unsigned PrimitiveID,
unsigned ControlID,
threadgroup PatchVertexType* patchVertices,
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>
OsdPatchVertex ds_regular_patches(
const float TessLevel,
const float TessLevel,
#if !USE_PTVS_FACTORS
float4 tessOuterHi,
float4 tessOuterLo,
float4 tessOuterHi,
float4 tessOuterLo,
#endif
PerPatchVertexBezier cv,
int3 patchParam,
float2 domainCoord)
PerPatchVertexBezier cv,
int3 patchParam,
float2 domainCoord
)
{
OsdPatchVertex output;
float3 P, dPu, dPv;
float3 N, dNu, dNv;
float2 vSegments;
#if !USE_PTVS_FACTORS
float2 UV = OsdGetTessParameterization(domainCoord,
tessOuterLo,
@ -183,7 +186,6 @@ OsdPatchVertex ds_regular_patches(
#endif
OsdEvalPatchBezier(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv, vSegments);
output.normal = N;
output.tangent = dPu;
output.bitangent = dPv;
@ -204,35 +206,35 @@ OsdPatchVertex ds_regular_patches(
template<typename PerPatchVertexBezier>
#endif
OsdPatchVertex OsdComputePatch(
float tessLevel,
float2 domainCoord,
unsigned patchID,
float tessLevel,
float2 domainCoord,
unsigned patchID,
#if USE_STAGE_IN
PerPatchVertexBezier osdPatch
PerPatchVertexBezier osdPatch
#else
OsdVertexBufferSet osdBuffers
OsdVertexBufferSet osdBuffers
#endif
)
)
{
return ds_regular_patches(
tessLevel,
return ds_regular_patches(
tessLevel,
#if !USE_PTVS_FACTORS
#if USE_STAGE_IN
osdPatch.tessOuterHi,
osdPatch.tessOuterLo,
osdPatch.tessOuterHi,
osdPatch.tessOuterLo,
#else
osdBuffers.patchTessBuffer[patchID].tessOuterHi,
osdBuffers.patchTessBuffer[patchID].tessOuterLo,
osdBuffers.patchTessBuffer[patchID].tessOuterHi,
osdBuffers.patchTessBuffer[patchID].tessOuterLo,
#endif
#endif
#if USE_STAGE_IN
osdPatch.cv,
osdPatch.patchParam,
osdPatch.cv,
osdPatch.patchParam,
#else
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
osdBuffers.patchParamBuffer[patchID],
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
osdBuffers.patchParamBuffer[patchID],
#endif
domainCoord
);
domainCoord
);
}

View File

@ -47,7 +47,7 @@ static_assert(sizeof(OsdInputVertexType) > 0, "OsdInputVertexType must be define
#if OSD_IS_ADAPTIVE
#if OSD_PATCH_GREGORY_BASIS
constant constexpr unsigned IndexLookupStride = 5;
#else
#else
constant constexpr unsigned IndexLookupStride = 1;
#endif
@ -61,7 +61,7 @@ static_assert(OSD_ENABLE_SCREENSPACE_TESSELLATION && (OSD_FRACTIONAL_ODD_SPACING
#endif
//Adjustments to the UV reparameterization can be defined here.
//Adjustments to the UV reparameterization can be defined here.
#ifndef OSD_UV_CORRECTION
#define OSD_UV_CORRECTION
#endif
@ -147,7 +147,7 @@ struct HullVertex {
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
struct OsdPatchParamBufferSet
{
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_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)]];
#endif
#if OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
const device int* quadOffsetBuffer [[buffer(OSD_QUADOFFSET_BUFFER_INDEX)]];
const device int* valenceBuffer [[buffer(OSD_VALENCE_BUFFER_INDEX)]];
const device int* quadOffsetBuffer [[buffer(OSD_QUADOFFSET_BUFFER_INDEX)]];
const device int* valenceBuffer [[buffer(OSD_VALENCE_BUFFER_INDEX)]];
#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
struct OsdVertexBufferSet
{
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_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)]];
#endif
};
@ -323,11 +322,11 @@ OsdUnivar4x4(float u, thread float* B)
{
float t = u;
float s = 1.0f - u;
float A0 = s * s;
float A1 = 2 * s * t;
float A2 = t * t;
B[0] = s * A0;
B[1] = t * A0 + s * A1;
B[2] = t * A1 + s * A2;
@ -413,9 +412,9 @@ OsdEvalBezier(float3 cp[16], float2 uv)
}
bool OsdCullPerPatchVertex(
threadgroup PatchVertexType* patch,
float4x4 ModelViewMatrix
)
threadgroup PatchVertexType* patch,
float4x4 ModelViewMatrix
)
{
#if OSD_ENABLE_BACKPATCH_CULL && OSD_PATCH_REGULAR
auto v0 = float3(ModelViewMatrix * patch[5].position);
@ -529,7 +528,7 @@ template<typename VertexType>
void
OsdComputeBSplineBoundaryPoints(threadgroup VertexType* cpt, int3 patchParam)
{
//APPL TODO - multithread this
//APPL TODO - multithread this
int boundaryMask = OsdGetPatchBoundaryMask(patchParam);
if ((boundaryMask & 1) != 0) {
@ -806,9 +805,6 @@ OsdComputeTessLevels(thread float4& tessOuterLo, thread float4& tessOuterHi,
tessLevelInner[1] = (combinedOuter[0] + combinedOuter[2]) * 0.5;
}
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.
@ -841,15 +837,6 @@ OsdGetTessLevelsUniform(const float OsdTessLevel, int3 patchParam,
float tessLevel = min(OsdTessLevel, ((float)OSD_MAX_TESS_LEVEL / 2)) /
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.
int transitionMask = OsdGetPatchTransitionMask(patchParam);
float4 tessLevelMin = float4(1)
@ -858,22 +845,17 @@ OsdGetTessLevelsUniform(const float OsdTessLevel, int3 patchParam,
((transitionMask & 2) >> 1),
((transitionMask & 4) >> 2));
// tessLevelMin = (tessLevelMin - 1.0) * 2.0f + 1.0;
// tessLevelMin = float4(OsdTessLevel);
tessOuterLo = max(float4(tessLevel,tessLevel,tessLevel,tessLevel),
tessLevelMin);
tessOuterHi = float4(0,0,0,0);
// tessOuterLo.x = refinementLevel;
}
void
OsdGetTessLevelsRefinedPoints(const float OsdTessLevel,
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
float3 cp[16], int3 patchParam,
thread float4& tessOuterLo, thread float4& tessOuterHi)
OsdGetTessLevelsRefinedPoints(
const float OsdTessLevel,
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
float3 cp[16], int3 patchParam,
thread float4& tessOuterLo, thread float4& tessOuterHi)
{
// Each edge of a transition patch is adjacent to one or two patches
// at the next refined level of subdivision. We compute the corresponding
@ -985,7 +967,7 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
tPt = &p12;
}
tessOuterLo[0] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p0, *tPt);
if ((transitionMask & 1) != 0) { // EV01
ev = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 0.0));
@ -997,7 +979,7 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
tPt = &p3;
}
tessOuterLo[1] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p0, *tPt);
if ((transitionMask & 2) != 0) { // EV12
ev = OsdEvalBezier(cpBezier, patchParam, float2(1.0, 0.5));
@ -1009,7 +991,7 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
tPt = &p15;
}
tessOuterLo[2] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,p3, *tPt);
if ((transitionMask & 4) != 0) { // EV23
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 c03 = miniMul(OsdModelViewMatrix, cpBezier[3].P);
float3 c15 = miniMul(OsdModelViewMatrix, cpBezier[15].P);
if ((transitionMask & 8) != 0) {
tessOuterLo[0] = OsdComputeTessLevel(OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,c00, p0);
@ -1068,44 +1048,55 @@ OsdGetTessLevelsLimitPoints(const float OsdTessLevel, const float4x4 OsdProjecti
}
void
OsdGetTessLevelsUniform(const float OsdTessLevel, int3 patchParam,
thread float4& tessLevelOuter, thread float2& tessLevelInner,
thread float4& tessOuterLo, thread float4& tessOuterHi)
OsdGetTessLevelsUniform(
const float OsdTessLevel, int3 patchParam,
thread float4& tessLevelOuter, thread float2& tessLevelInner,
thread float4& tessOuterLo, thread float4& tessOuterHi)
{
OsdGetTessLevelsUniform(OsdTessLevel, patchParam, tessOuterLo, tessOuterHi);
OsdComputeTessLevels(tessOuterLo, tessOuterHi, tessLevelOuter, tessLevelInner);
}
void
OsdGetTessLevelsAdaptiveRefinedPoints(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
float3 cpRefined[16], int3 patchParam,
thread float4& tessLevelOuter, thread float2& tessLevelInner,
thread float4& tessOuterLo, thread float4& tessOuterHi)
OsdGetTessLevelsAdaptiveRefinedPoints(
const float OsdTessLevel,
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
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,
tessLevelOuter, tessLevelInner);
}
void
OsdGetTessLevelsAdaptiveLimitPoints(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
device OsdPerPatchVertexBezier* cpBezier,
int3 patchParam,
thread float4& tessLevelOuter, thread float2& tessLevelInner,
thread float4& tessOuterLo, thread float4& tessOuterHi)
OsdGetTessLevelsAdaptiveLimitPoints(
const float OsdTessLevel,
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
device OsdPerPatchVertexBezier* cpBezier, int3 patchParam,
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,
tessLevelOuter, tessLevelInner);
}
void
OsdGetTessLevels(const float OsdTessLevel, const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
float3 cp0, float3 cp1, float3 cp2, float3 cp3,
int3 patchParam,
thread float4& tessLevelOuter, thread float2& tessLevelInner)
OsdGetTessLevels(
const float OsdTessLevel,
const float4x4 OsdProjectionMatrix, const float4x4 OsdModelViewMatrix,
float3 cp0, float3 cp1, float3 cp2, float3 cp3, int3 patchParam,
thread float4& tessLevelOuter, thread float2& tessLevelInner)
{
float4 tessOuterLo = float4(0,0,0,0);
float4 tessOuterHi = float4(0,0,0,0);
@ -1172,53 +1163,53 @@ float
OsdGetTessTransitionSplit(float t, float lo, float hi )
{
#if OSD_FRACTIONAL_EVEN_SPACING
float loRoundUp = OsdRoundUpEven(lo);
float hiRoundUp = OsdRoundUpEven(hi);
float loRoundUp = OsdRoundUpEven(lo);
float hiRoundUp = OsdRoundUpEven(hi);
// Convert the parametric t into a segment index along the combined edge.
float ti = round(t * (loRoundUp + hiRoundUp));
// Convert the parametric t into a segment index along the combined edge.
float ti = round(t * (loRoundUp + hiRoundUp));
if (ti <= loRoundUp) {
float t0 = ti / loRoundUp;
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
} else {
float t1 = (ti - loRoundUp) / hiRoundUp;
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
if (ti <= loRoundUp) {
float t0 = ti / loRoundUp;
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
} else {
float t1 = (ti - loRoundUp) / hiRoundUp;
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
}
#elif OSD_FRACTIONAL_ODD_SPACING
float loRoundUp = OsdRoundUpOdd(lo);
float hiRoundUp = OsdRoundUpOdd(hi);
float loRoundUp = OsdRoundUpOdd(lo);
float hiRoundUp = OsdRoundUpOdd(hi);
// 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
// tessellator since the sum of two odd tess levels will be rounded
// up by one to the next odd integer tess level.
float ti = (t * (loRoundUp + hiRoundUp + 1));
// 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
// tessellator since the sum of two odd tess levels will be rounded
// up by one to the next odd integer tess level.
float ti = (t * (loRoundUp + hiRoundUp + 1));
OSD_UV_CORRECTION
OSD_UV_CORRECTION
ti = round(ti);
ti = round(ti);
if (ti <= loRoundUp) {
float t0 = ti / loRoundUp;
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
} else if (ti > (loRoundUp+1)) {
float t1 = (ti - (loRoundUp+1)) / hiRoundUp;
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
} else {
return 0.5;
}
if (ti <= loRoundUp) {
float t0 = ti / loRoundUp;
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
} else if (ti > (loRoundUp+1)) {
float t1 = (ti - (loRoundUp+1)) / hiRoundUp;
return OsdGetTessFractionalSplit(t1, hi, hiRoundUp) * 0.5 + 0.5;
} else {
return 0.5;
}
#else //OSD_FRACTIONAL_ODD_SPACING
// Convert the parametric t into a segment index along the combined edge.
float ti = round(t * (lo + hi));
// Convert the parametric t into a segment index along the combined edge.
float ti = round(t * (lo + hi));
if (ti <= lo) {
return (ti / lo) * 0.5;
} else {
return ((ti - lo) / hi) * 0.5 + 0.5;
}
if (ti <= lo) {
return (ti / lo) * 0.5;
} else {
return ((ti - lo) / hi) * 0.5 + 0.5;
}
#endif //OSD_FRACTIONAL_ODD_SPACING
}
@ -1226,28 +1217,21 @@ float2
OsdGetTessParameterization(float2 uv, float4 tessOuterLo, float4 tessOuterHi)
{
float2 UV = uv;
if (UV.x == 0 && tessOuterHi[0] > 0)
{
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
}
else if (UV.y == 0 && tessOuterHi[1] > 0)
{
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
}
else if (UV.x == 1 && tessOuterHi[2] > 0)
{
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
}
else if (UV.y == 1 && tessOuterHi[3] > 0)
{
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
}
if (UV.x == 0 && tessOuterHi[0] > 0) {
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
} else
if (UV.y == 0 && tessOuterHi[1] > 0) {
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
} else
if (UV.x == 1 && tessOuterHi[2] > 0) {
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
} else
if (UV.y == 1 && tessOuterHi[3] > 0) {
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
}
return UV;
}
int4 OsdGetPatchCoord(int3 patchParam)
{
int faceId = OsdGetPatchFaceId(patchParam);
@ -1296,7 +1280,7 @@ constant float4x4 Mi(
float4(0.f, 0.f, 1.f, 0.f)
);
float4x4 OsdComputeMs2(float sharpness, float factor)
{
float s = exp2(sharpness);
@ -1308,34 +1292,31 @@ float4x4 OsdComputeMs2(float sharpness, float factor)
float ssub1 = s-1;
float ssub1_2 = ssub1 * ssub1;
float div6 = 1.0/6.0;
float4x4 m(
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+s, sx6m2, sfrac1),
float4(0, 1, sx6m2, 1));
m *= factor * (1/sx6);
m[0][0] = div6 * factor;
return m;
}
// ----------------------------------------------------------------------------
// BSpline
// ----------------------------------------------------------------------------
// convert BSpline cv to Bezier cv
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)
{
int i = ID%4;
int j = ID/4;
#if OSD_PATCH_ENABLE_SINGLE_CREASE
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);
result.vSegments = float2(s0, s1);
#endif
bool isBoundary[2];
isBoundary[0] = (((boundaryMask & 8) != 0) || ((boundaryMask & 2) != 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[1] = (boundaryMask & 1) ? true : false;
float3 Hi[4], Hj[4], Hs[4];
if (isBoundary[0])
{
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) {
P += Q[j][k]*Hi[k];
}
result.P = P;
result.P1 = P;
@ -2051,9 +2032,3 @@ OsdComputePerPatchVertexGregory(int3 patchParam, unsigned ID, unsigned primitive
}
#endif // OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY

View File

@ -29,23 +29,23 @@
//----------------------------------------------------------
void OsdComputePerVertex(
float4 position,
threadgroup OsdPerVertexGregory& hullVertex,
int vertexId,
float4x4 modelViewProjectionMatrix,
OsdPatchParamBufferSet osdBuffers
)
float4 position,
threadgroup OsdPerVertexGregory& hullVertex,
int vertexId,
float4x4 modelViewProjectionMatrix,
OsdPatchParamBufferSet osdBuffers
)
{
OsdComputePerVertexGregory(vertexId, position.xyz, hullVertex, osdBuffers);
#if OSD_ENABLE_PATCH_CULL
float4 clipPos = mul(modelViewProjectionMatrix, position);
short3 clip0 = short3(clipPos.x < clipPos.w,
clipPos.y < clipPos.w,
clipPos.z < clipPos.w);
short3 clip1 = short3(clipPos.x > -clipPos.w,
clipPos.y > -clipPos.w,
clipPos.z > -clipPos.w);
float4 clipPos = mul(modelViewProjectionMatrix, position);
short3 clip0 = short3(clipPos.x < clipPos.w,
clipPos.y < clipPos.w,
clipPos.z < clipPos.w);
short3 clip1 = short3(clipPos.x > -clipPos.w,
clipPos.y > -clipPos.w,
clipPos.z > -clipPos.w);
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
#endif
}
@ -55,31 +55,31 @@ void OsdComputePerVertex(
//----------------------------------------------------------
void OsdComputePerPatchFactors(
int3 patchParam,
float tessLevel,
unsigned patchID,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
OsdPatchParamBufferSet osdBuffer,
threadgroup PatchVertexType* patchVertices,
device MTLQuadTessellationFactorsHalf& quadFactors
)
int3 patchParam,
float tessLevel,
unsigned patchID,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
OsdPatchParamBufferSet osdBuffer,
threadgroup PatchVertexType* patchVertices,
device MTLQuadTessellationFactorsHalf& quadFactors
)
{
float4 tessLevelOuter = float4(0,0,0,0);
float2 tessLevelInner = float2(0,0);
OsdGetTessLevels(
tessLevel,
projectionMatrix,
modelViewMatrix,
patchVertices[0].P,
patchVertices[3].P,
patchVertices[2].P,
patchVertices[1].P,
patchParam,
tessLevelOuter,
tessLevelInner
);
OsdGetTessLevels(
tessLevel,
projectionMatrix,
modelViewMatrix,
patchVertices[0].P,
patchVertices[3].P,
patchVertices[2].P,
patchVertices[1].P,
patchParam,
tessLevelOuter,
tessLevelInner
);
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
@ -94,21 +94,21 @@ void OsdComputePerPatchFactors(
//----------------------------------------------------------
void OsdComputePerPatchVertex(
int3 patchParam,
unsigned ID,
unsigned PrimitiveID,
unsigned ControlID,
threadgroup PatchVertexType* patchVertices,
OsdPatchParamBufferSet osdBuffers
)
int3 patchParam,
unsigned ID,
unsigned PrimitiveID,
unsigned ControlID,
threadgroup PatchVertexType* patchVertices,
OsdPatchParamBufferSet osdBuffers
)
{
OsdComputePerPatchVertexGregory(
patchParam,
ID,
PrimitiveID,
patchVertices,
osdBuffers.perPatchVertexBuffer[ControlID],
osdBuffers);
OsdComputePerPatchVertexGregory(
patchParam,
ID,
PrimitiveID,
patchVertices,
osdBuffers.perPatchVertexBuffer[ControlID],
osdBuffers);
}
//----------------------------------------------------------
@ -117,43 +117,43 @@ void OsdComputePerPatchVertex(
template<typename PerPatchVertexGregory>
OsdPatchVertex ds_gregory_patches(
PerPatchVertexGregory patch,
int3 patchParam,
float2 UV
)
PerPatchVertexGregory patch,
int3 patchParam,
float2 UV
)
{
OsdPatchVertex output;
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 cv[20];
cv[0] = patch[0].P;
cv[1] = patch[0].Ep;
cv[2] = patch[0].Em;
cv[3] = patch[0].Fp;
cv[4] = patch[0].Fm;
cv[5] = patch[1].P;
cv[6] = patch[1].Ep;
cv[7] = patch[1].Em;
cv[8] = patch[1].Fp;
cv[9] = patch[1].Fm;
cv[10] = patch[2].P;
cv[11] = patch[2].Ep;
cv[12] = patch[2].Em;
cv[13] = patch[2].Fp;
cv[14] = patch[2].Fm;
cv[15] = patch[3].P;
cv[16] = patch[3].Ep;
cv[17] = patch[3].Em;
cv[18] = patch[3].Fp;
cv[19] = patch[3].Fm;
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
// all code below here is client code
output.position = P;
output.normal = N;
@ -165,7 +165,7 @@ OsdPatchVertex ds_gregory_patches(
#endif
output.patchCoord = OsdInterpolatePatchCoord(UV, patchParam);
return output;
}
@ -173,23 +173,23 @@ OsdPatchVertex ds_gregory_patches(
template<typename PerPatchVertexGregoryBasis>
#endif
OsdPatchVertex OsdComputePatch(
float tessLevel,
float2 domainCoord,
unsigned patchID,
float tessLevel,
float2 domainCoord,
unsigned patchID,
#if USE_STAGE_IN
PerPatchVertexGregoryBasis osdPatch
PerPatchVertexGregoryBasis osdPatch
#else
OsdVertexBufferSet osdBuffers
OsdVertexBufferSet osdBuffers
#endif
)
)
{
return ds_gregory_patches(
return ds_gregory_patches(
#if USE_STAGE_IN
osdPatch.cv,
osdPatch.patchParam,
osdPatch.cv,
osdPatch.patchParam,
#else
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
osdBuffers.patchParamBuffer[patchID],
osdBuffers.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
osdBuffers.patchParamBuffer[patchID],
#endif
domainCoord);
}
domainCoord);
}

View File

@ -29,23 +29,23 @@
//----------------------------------------------------------
void OsdComputePerVertex(
float4 position,
threadgroup HullVertex& hullVertex,
int vertexId,
float4x4 modelViewProjectionMatrix,
OsdPatchParamBufferSet osdBuffers
)
float4 position,
threadgroup HullVertex& hullVertex,
int vertexId,
float4x4 modelViewProjectionMatrix,
OsdPatchParamBufferSet osdBuffers
)
{
hullVertex.position = position;
hullVertex.position = position;
#if OSD_ENABLE_PATCH_CULL
float4 clipPos = mul(modelViewProjectionMatrix, position);
short3 clip0 = short3(clipPos.x < clipPos.w,
clipPos.y < clipPos.w,
clipPos.z < clipPos.w);
short3 clip1 = short3(clipPos.x > -clipPos.w,
clipPos.y > -clipPos.w,
clipPos.z > -clipPos.w);
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
float4 clipPos = mul(modelViewProjectionMatrix, position);
short3 clip0 = short3(clipPos.x < clipPos.w,
clipPos.y < clipPos.w,
clipPos.z < clipPos.w);
short3 clip1 = short3(clipPos.x > -clipPos.w,
clipPos.y > -clipPos.w,
clipPos.z > -clipPos.w);
hullVertex.clipFlag = short3(clip0) + 2*short3(clip1);
#endif
}
@ -54,31 +54,31 @@ void OsdComputePerVertex(
//----------------------------------------------------------
void OsdComputePerPatchFactors(
int3 patchParam,
float tessLevel,
unsigned patchID,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
OsdPatchParamBufferSet osdBuffer,
threadgroup PatchVertexType* patchVertices,
device MTLQuadTessellationFactorsHalf& quadFactors
)
int3 patchParam,
float tessLevel,
unsigned patchID,
float4x4 projectionMatrix,
float4x4 modelViewMatrix,
OsdPatchParamBufferSet osdBuffer,
threadgroup PatchVertexType* patchVertices,
device MTLQuadTessellationFactorsHalf& quadFactors
)
{
float4 tessLevelOuter = float4(0,0,0,0);
float2 tessLevelInner = float2(0,0);
OsdGetTessLevels(
tessLevel,
projectionMatrix,
modelViewMatrix,
patchVertices[0].position.xyz,
patchVertices[3].position.xyz,
patchVertices[2].position.xyz,
patchVertices[1].position.xyz,
patchParam,
tessLevelOuter,
tessLevelInner
);
OsdGetTessLevels(
tessLevel,
projectionMatrix,
modelViewMatrix,
patchVertices[0].position.xyz,
patchVertices[3].position.xyz,
patchVertices[2].position.xyz,
patchVertices[1].position.xyz,
patchParam,
tessLevelOuter,
tessLevelInner
);
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
@ -93,15 +93,15 @@ void OsdComputePerPatchFactors(
//----------------------------------------------------------
void OsdComputePerPatchVertex(
int3 patchParam,
unsigned ID,
unsigned PrimitiveID,
unsigned ControlID,
threadgroup PatchVertexType* patchVertices,
OsdPatchParamBufferSet osdBuffers
)
int3 patchParam,
unsigned ID,
unsigned PrimitiveID,
unsigned ControlID,
threadgroup PatchVertexType* patchVertices,
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>
#endif
OsdPatchVertex ds_gregory_basis_patches(
#if USE_STAGE_IN
PerPatchVertexGregoryBasis patch,
PerPatchVertexGregoryBasis patch,
#else
const device OsdInputVertexType* patch,
const device unsigned* patchIndices,
const device OsdInputVertexType* patch,
const device unsigned* patchIndices,
#endif
int3 patchParam,
float2 UV
)
int3 patchParam,
float2 UV
)
{
OsdPatchVertex output;
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);
#if USE_STAGE_IN
float3 cv[20];
for(int i = 0; i < 20; i++)
cv[i] = patch[i].position;
#else
#else
#if USE_128BIT_GREGORY_BASIS_INDICES_READ
float3 cv[20];
for(int i = 0; i < 5; i++) {
int4 indices = ((device int4*)patchIndices)[i];
int n = i * 4;
cv[n + 0] = (patch + indices[0])->position;
cv[n + 1] = (patch + indices[1])->position;
@ -154,9 +153,9 @@ OsdPatchVertex ds_gregory_basis_patches(
}
#endif
#endif
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
output.position = P;
output.normal = N;
output.tangent = dPu;
@ -165,9 +164,9 @@ OsdPatchVertex ds_gregory_basis_patches(
output.Nu = dNu;
output.Nv = dNv;
#endif
output.patchCoord = OsdInterpolatePatchCoord(UV, patchParam);
return output;
}
@ -175,25 +174,25 @@ OsdPatchVertex ds_gregory_basis_patches(
template<typename PerPatchVertexGregoryBasis>
#endif
OsdPatchVertex OsdComputePatch(
float tessLevel,
float2 domainCoord,
unsigned patchID,
float tessLevel,
float2 domainCoord,
unsigned patchID,
#if USE_STAGE_IN
PerPatchVertexGregoryBasis osdPatch
PerPatchVertexGregoryBasis osdPatch
#else
OsdVertexBufferSet osdBuffers
OsdVertexBufferSet osdBuffers
#endif
)
)
{
return ds_gregory_basis_patches(
return ds_gregory_basis_patches(
#if USE_STAGE_IN
osdPatch.cv,
osdPatch.patchParam,
osdPatch.cv,
osdPatch.patchParam,
#else
osdBuffers.vertexBuffer,
osdBuffers.indexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
osdBuffers.patchParamBuffer[patchID],
osdBuffers.vertexBuffer,
osdBuffers.indexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
osdBuffers.patchParamBuffer[patchID],
#endif
domainCoord
);
domainCoord
);
}

View File

@ -22,36 +22,39 @@
// 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 "../version.h"
#import "../far/patchDescriptor.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
class MTLPatchShaderSource {
public:
static std::string GetCommonShaderSource();
namespace OPENSUBDIV_VERSION {
static std::string GetPatchBasisShaderSource();
static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
static std::string GetHullShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
namespace Osd {
class MTLPatchShaderSource {
public:
static std::string GetCommonShaderSource();
static std::string GetPatchBasisShaderSource();
static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
static std::string GetHullShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_MTL_PATCH_SHADER_SOURCE

View File

@ -30,127 +30,131 @@
#include <TargetConditionals.h>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
static std::string commonShaderSource(
namespace OPENSUBDIV_VERSION {
namespace Osd {
static std::string commonShaderSource(
#include "mtlPatchCommon.gen.h"
);
static std::string patchBasisTypesShaderSource(
static std::string patchBasisTypesShaderSource(
#include "patchBasisCommonTypes.gen.h"
);
static std::string patchBasisShaderSource(
static std::string patchBasisShaderSource(
#include "patchBasisCommon.gen.h"
);
static std::string patchBasisEvalShaderSource(
static std::string patchBasisEvalShaderSource(
#include "patchBasisCommonEval.gen.h"
);
static std::string bsplineShaderSource(
static std::string bsplineShaderSource(
#include "mtlPatchBSpline.gen.h"
);
static std::string gregoryShaderSource(
static std::string gregoryShaderSource(
#include "mtlPatchGregory.gen.h"
);
static std::string gregoryBasisShaderSource(
static std::string gregoryBasisShaderSource(
#include "mtlPatchGregoryBasis.gen.h"
);
static std::string GetPatchTypeDefine(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
std::stringstream ss;
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
GetPatchTypeDefine(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
static std::string GetPatchTypeSource(Far::PatchDescriptor::Type type) {
switch(type) {
case Far::PatchDescriptor::QUADS: return "";
case Far::PatchDescriptor::REGULAR: return bsplineShaderSource;
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
}
std::stringstream ss;
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
MTLPatchShaderSource::GetPatchBasisShaderSource() {
std::stringstream ss;
ss << "#define OSD_PATCH_BASIS_METAL 1\n";
#if defined(OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES)
ss << "#define OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES 1\n";
static std::string
GetPatchTypeSource(Far::PatchDescriptor::Type type) {
switch(type) {
case Far::PatchDescriptor::QUADS: return "";
case Far::PatchDescriptor::REGULAR: return bsplineShaderSource;
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
ss << patchBasisTypesShaderSource;
ss << patchBasisShaderSource;
ss << patchBasisEvalShaderSource;
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
std::stringstream ss;
ss << GetPatchTypeDefine(type, fvarType);
ss << GetCommonShaderSource();
ss << GetPatchTypeSource(type);
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
std::stringstream ss;
ss << GetPatchTypeDefine(type, fvarType);
ss << GetCommonShaderSource();
ss << GetPatchTypeSource(type);
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetDomainShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
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
}
/*static*/
std::string
MTLPatchShaderSource::GetPatchBasisShaderSource() {
std::stringstream ss;
ss << "#define OSD_PATCH_BASIS_METAL 1\n";
#if defined(OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES)
ss << "#define OPENSUBDIV_GREGORY_EVAL_TRUE_DERIVATIVES 1\n";
#endif
ss << patchBasisTypesShaderSource;
ss << patchBasisShaderSource;
ss << patchBasisEvalShaderSource;
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
std::stringstream ss;
ss << GetPatchTypeDefine(type, fvarType);
ss << GetCommonShaderSource();
ss << GetPatchTypeSource(type);
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
std::stringstream ss;
ss << GetPatchTypeDefine(type, fvarType);
ss << GetCommonShaderSource();
ss << GetPatchTypeSource(type);
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetDomainShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
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

View File

@ -34,65 +34,64 @@
@protocol MTLDevice;
@protocol MTLBuffer;
namespace OpenSubdiv
{
namespace OPENSUBDIV_VERSION
namespace OpenSubdiv {
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
{
class PatchTable;
}
return Create(farPatchTable, context);
}
namespace Osd
{
class MTLPatchTable : private NonCopyable<MTLPatchTable>
{
public:
typedef id<MTLBuffer> VertexBufferBinding;
static MTLPatchTable *Create(Far::PatchTable const *farPatchTable, MTLContext* context);
MTLPatchTable();
~MTLPatchTable();
PatchArrayVector const &GetPatchArrays() const { return _patchArrays; }
id<MTLBuffer> GetPatchIndexBuffer() const { return _indexBuffer; }
id<MTLBuffer> GetPatchParamBuffer() const { return _patchParamBuffer; }
template<typename DEVICE_CONTEXT>
static MTLPatchTable *Create(Far::PatchTable const *farPatchTable, DEVICE_CONTEXT context)
{
return Create(farPatchTable, context);
}
PatchArrayVector const &GetVaryingPatchArrays() const { return _varyingPatchArrays; }
id<MTLBuffer> GetVaryingPatchIndexBuffer() const { return _varyingPatchIndexBuffer; }
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; }
id<MTLBuffer> GetPatchIndexBuffer() const { return _indexBuffer; }
id<MTLBuffer> GetPatchParamBuffer() const { return _patchParamBuffer; }
protected:
bool allocate(Far::PatchTable const *farPatchTable, MTLContext* context);
PatchArrayVector const &GetVaryingPatchArrays() const { return _varyingPatchArrays; }
id<MTLBuffer> GetVaryingPatchIndexBuffer() const { return _varyingPatchIndexBuffer; }
PatchArrayVector _patchArrays;
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]; }
id<MTLBuffer> _indexBuffer;
id<MTLBuffer> _patchParamBuffer;
protected:
bool allocate(Far::PatchTable const *farPatchTable, MTLContext* context);
PatchArrayVector _varyingPatchArrays;
PatchArrayVector _patchArrays;
id<MTLBuffer> _indexBuffer;
id<MTLBuffer> _patchParamBuffer;
id<MTLBuffer> _varyingPatchIndexBuffer;
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;
std::vector<id<MTLBuffer>> _fvarIndexBuffers;
std::vector<id<MTLBuffer>> _fvarParamBuffers;
};
} // end namespace Osd
} //end namespace OPENSUBDIV_VERSION
} //end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
using namespace OPENSUBDIV_VERSION;
} //end namespace OpenSubdiv
#endif //end OPENSUBDIV3_OSD_MTL_PATCH_TABLE_H

View File

@ -29,6 +29,7 @@
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
MTLPatchTable::MTLPatchTable()
@ -43,7 +44,7 @@ _varyingPatchIndexBuffer(nil)
MTLPatchTable::~MTLPatchTable()
{
}
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();
_patchArrays.assign(cpuTable.GetPatchArrayBuffer(), cpuTable.GetPatchArrayBuffer() + numPatchArrays);
_indexBuffer = createBuffer(cpuTable.GetPatchIndexBuffer(), indexSize * sizeof(unsigned), context);
if(_indexBuffer == nil)
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);
if(_fvarParamBuffers[fvc] == nil)
return false;
}
}
return true;

View File

@ -31,54 +31,53 @@
@protocol MTLDevice;
@protocol MTLBuffer;
namespace OpenSubdiv
{
namespace OPENSUBDIV_VERSION
{
namespace Osd
{
class CPUMTLVertexBuffer
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
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:
static CPUMTLVertexBuffer* Create(int numElements, int numVertices, MTLContext* context);
return _numElements;
}
void UpdateData(const float* src, int startVertex, int numVertices, MTLContext* context);
int GetNumVertices() const
{
return _numVertices;
}
int GetNumElements() const
{
return _numElements;
}
float* BindCpuBuffer();
id<MTLBuffer> BindMTLBuffer(MTLContext* context);
int GetNumVertices() const
{
return _numVertices;
}
id<MTLBuffer> BindVBO(MTLContext* context)
{
return BindMTLBuffer(context);
}
float* BindCpuBuffer();
id<MTLBuffer> BindMTLBuffer(MTLContext* context);
protected:
id<MTLBuffer> BindVBO(MTLContext* context)
{
return BindMTLBuffer(context);
}
CPUMTLVertexBuffer(int numElements, int numVertices);
protected:
bool allocate(MTLContext* context);
CPUMTLVertexBuffer(int numElements, int numVertices);
bool allocate(MTLContext* context);
private:
int _numElements;
int _numVertices;
id<MTLBuffer> _buffer;
bool _dirty;
};
private:
int _numElements;
int _numVertices;
id<MTLBuffer> _buffer;
bool _dirty;
};
} //end namespace Osd
} //end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} //end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_MTL_VERTEX_BUFFER_H

View File

@ -26,12 +26,11 @@
#include <Metal/Metal.h>
#include <TargetConditionals.h>
namespace OpenSubdiv
{
namespace OPENSUBDIV_VERSION
{
namespace Osd
{
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
CPUMTLVertexBuffer::CPUMTLVertexBuffer(int numElements, int numVertices)
:
_numElements(numElements), _numVertices(numVertices),
@ -83,7 +82,7 @@ float* CPUMTLVertexBuffer::BindCpuBuffer()
id<MTLBuffer> CPUMTLVertexBuffer::BindMTLBuffer(MTLContext* context)
{
#if TARGET_OS_OSX
if(_dirty)
if(_dirty)
[_buffer didModifyRange:NSMakeRange(0, _buffer.length)];
_dirty = false;
#endif
@ -93,6 +92,6 @@ id<MTLBuffer> CPUMTLVertexBuffer::BindMTLBuffer(MTLContext* context)
} //end namepsace Osd
} //end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} //end namespace OpenSubdiv