mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-23 04:00:07 +00:00
Mtl implementation mtlViewer support for Loop
Updated mtlViewer to support drawing of tessellated Loop scheme meshes.
This commit is contained in:
parent
2e175ff52b
commit
4789df9522
@ -183,6 +183,8 @@ getAdaptivePatchColor(int3 patchParam
|
||||
patchType = 5;
|
||||
#elif OSD_PATCH_GREGORY_BASIS
|
||||
patchType = 6;
|
||||
#elif OSD_PATCH_GREGORY_TRIANGLE
|
||||
patchType = 6;
|
||||
#endif
|
||||
|
||||
int pattern = popcount(OsdGetPatchTransitionMask(patchParam));
|
||||
@ -205,7 +207,7 @@ getAdaptiveDepthColor(int3 patchParam)
|
||||
|
||||
#if OSD_IS_ADAPTIVE
|
||||
#if USE_STAGE_IN
|
||||
#if OSD_PATCH_REGULAR
|
||||
#if OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE
|
||||
struct ControlPoint
|
||||
{
|
||||
float3 P [[attribute(0)]];
|
||||
@ -226,7 +228,7 @@ struct ControlPoint
|
||||
float3 Fp [[attribute(3)]];
|
||||
float3 Fm [[attribute(4)]];
|
||||
};
|
||||
#elif OSD_PATCH_GREGORY_BASIS
|
||||
#elif OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE
|
||||
struct ControlPoint
|
||||
{
|
||||
float3 position [[attribute(0)]];
|
||||
@ -244,6 +246,13 @@ struct PatchInput
|
||||
};
|
||||
#endif
|
||||
|
||||
#if OSD_PATCH_REGULAR || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
typedef MTLQuadTessellationFactorsHalf PatchTessFactors;
|
||||
#elif OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_TRIANGLE
|
||||
typedef MTLTriangleTessellationFactorsHalf PatchTessFactors;
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
// OSD Kernel
|
||||
//----------------------------------------------------------
|
||||
@ -256,7 +265,7 @@ kernel void compute_main(
|
||||
unsigned thread_position_in_threadgroup [[thread_position_in_threadgroup]],
|
||||
unsigned threadgroup_position_in_grid [[threadgroup_position_in_grid]],
|
||||
OsdPatchParamBufferSet osdBuffers, //This struct contains all of the buffers needed by OSD
|
||||
device MTLQuadTessellationFactorsHalf* patchTessellationFactors [[buffer(PATCH_TESSFACTORS_INDEX)]]
|
||||
device PatchTessFactors* patchTessellationFactors [[buffer(PATCH_TESSFACTORS_INDEX)]]
|
||||
#if OSD_USE_PATCH_INDEX_BUFFER
|
||||
,device unsigned* patchIndex [[buffer(OSD_PATCH_INDEX_BUFFER_INDEX)]]
|
||||
,device MTLDrawPatchIndirectArguments* drawIndirectCommands [[buffer(OSD_DRAWINDIRECT_BUFFER_INDEX)]]
|
||||
@ -318,12 +327,19 @@ kernel void compute_main(
|
||||
if (!OsdCullPerPatchVertex(patch, frameConsts.ModelViewMatrix))
|
||||
{
|
||||
#if !OSD_USE_PATCH_INDEX_BUFFER
|
||||
#if OSD_PATCH_REGULAR || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
patchTessellationFactors[primitiveID].edgeTessellationFactor[0] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].edgeTessellationFactor[1] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].edgeTessellationFactor[2] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].edgeTessellationFactor[3] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].insideTessellationFactor[0] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].insideTessellationFactor[1] = 0.0h;
|
||||
#elif OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_TRIANGLE
|
||||
patchTessellationFactors[primitiveID].edgeTessellationFactor[0] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].edgeTessellationFactor[1] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].edgeTessellationFactor[2] = 0.0h;
|
||||
patchTessellationFactors[primitiveID].insideTessellationFactor = 0.0h;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
patchParam[primitiveIDInTG].z = -1;
|
||||
@ -431,7 +447,11 @@ interpolateFaceVaryingColor(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OSD_PATCH_REGULAR || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
[[patch(quad, VERTEX_CONTROL_POINTS_PER_PATCH)]]
|
||||
#elif OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_TRIANGLE
|
||||
[[patch(triangle, VERTEX_CONTROL_POINTS_PER_PATCH)]]
|
||||
#endif
|
||||
vertex OutputVertex vertex_main(
|
||||
const constant PerFrameConstants& frameConsts [[buffer(FRAME_CONST_BUFFER_INDEX)]],
|
||||
#if USE_STAGE_IN
|
||||
@ -443,7 +463,11 @@ vertex OutputVertex vertex_main(
|
||||
const device int* osdFaceVaryingIndices [[buffer(OSD_FVAR_INDICES_BUFFER_INDEX)]],
|
||||
const device packed_int3* osdFaceVaryingPatchParams [[buffer(OSD_FVAR_PATCHPARAM_BUFFER_INDEX)]],
|
||||
const constant int* osdFaceVaryingPatchArrays [[buffer(OSD_FVAR_PATCH_ARRAYS_BUFFER_INDEX)]],
|
||||
#if OSD_PATCH_REGULAR || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
float2 position_in_patch [[position_in_patch]],
|
||||
#elif OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_TRIANGLE
|
||||
float3 position_in_patch [[position_in_patch]],
|
||||
#endif
|
||||
uint patch_id [[patch_id]]
|
||||
)
|
||||
{
|
||||
|
@ -65,6 +65,7 @@
|
||||
#define OSD_PERPATCHTESSFACTORS_BUFFER_INDEX 8
|
||||
#define PATCH_TESSFACTORS_INDEX 10
|
||||
#define QUAD_TESSFACTORS_INDEX PATCH_TESSFACTORS_INDEX
|
||||
#define TRIANGLE_TESSFACTORS_INDEX PATCH_TESSFACTORS_INDEX
|
||||
#define OSD_PATCH_INDEX_BUFFER_INDEX 13
|
||||
#define OSD_DRAWINDIRECT_BUFFER_INDEX 14
|
||||
#define OSD_KERNELLIMIT_BUFFER_INDEX 15
|
||||
@ -187,7 +188,6 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
||||
NSString* _osdShaderSource;
|
||||
simd::float3 _meshCenter;
|
||||
NSMutableArray<NSString*>* _loadedModels;
|
||||
bool _doAdaptive;
|
||||
int _patchCounts[DISPATCHSLOTS];
|
||||
}
|
||||
|
||||
@ -202,6 +202,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
|
||||
struct PipelineConfig {
|
||||
Far::PatchDescriptor::Type patchType;
|
||||
bool useTessellation;
|
||||
bool useTriangleTessellation;
|
||||
bool useSingleCreasePatch;
|
||||
bool useLegacyBuffers;
|
||||
bool drawIndexed;
|
||||
@ -218,6 +219,7 @@ struct PipelineConfig {
|
||||
|
||||
config.patchType = patchType;
|
||||
config.useTessellation = false;
|
||||
config.useTriangleTessellation = false;
|
||||
config.useSingleCreasePatch = false;
|
||||
config.useLegacyBuffers = false;
|
||||
config.drawIndexed = false;
|
||||
@ -237,6 +239,15 @@ struct PipelineConfig {
|
||||
config.numControlPointsPerThreadToDraw = 3;
|
||||
config.numThreadsPerPatch = 1;
|
||||
break;
|
||||
case Far::PatchDescriptor::LOOP:
|
||||
config.useTessellation = true;
|
||||
config.useTriangleTessellation = true;
|
||||
config.numControlPointsPerPatchRefined = 12;
|
||||
config.numControlPointsPerPatchToDraw = 15;
|
||||
config.numControlPointsPerThreadRefined = 3;
|
||||
config.numControlPointsPerThreadToDraw = 4;
|
||||
config.numThreadsPerPatch = 4;
|
||||
break;
|
||||
case Far::PatchDescriptor::REGULAR:
|
||||
config.useTessellation = true;
|
||||
config.useSingleCreasePatch = useSingleCreasePatch;
|
||||
@ -273,6 +284,16 @@ struct PipelineConfig {
|
||||
config.numControlPointsPerThreadToDraw = 5;
|
||||
config.numThreadsPerPatch = 4;
|
||||
break;
|
||||
case Far::PatchDescriptor::GREGORY_TRIANGLE:
|
||||
config.useTessellation = true;
|
||||
config.useTriangleTessellation = true;
|
||||
config.drawIndexed = true;
|
||||
config.numControlPointsPerPatchRefined = 18;
|
||||
config.numControlPointsPerPatchToDraw = 18;
|
||||
config.numControlPointsPerThreadRefined = 5;
|
||||
config.numControlPointsPerThreadToDraw = 5;
|
||||
config.numThreadsPerPatch = 4;
|
||||
break;
|
||||
default:
|
||||
assert("Unsupported patch type" && 0); break;
|
||||
}
|
||||
@ -356,7 +377,7 @@ struct PipelineConfig {
|
||||
|
||||
[self _updateState];
|
||||
|
||||
if(_doAdaptive) {
|
||||
if (_useAdaptive) {
|
||||
auto computeEncoder = [commandBuffer computeCommandEncoder];
|
||||
[self _computeTessFactors:computeEncoder];
|
||||
[computeEncoder endEncoding];
|
||||
@ -364,7 +385,7 @@ struct PipelineConfig {
|
||||
|
||||
auto renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:[_delegate renderPassDescriptorFor: self]];
|
||||
|
||||
if(_usePrimitiveBackfaceCulling) {
|
||||
if (_usePrimitiveBackfaceCulling) {
|
||||
[renderEncoder setCullMode:MTLCullModeBack];
|
||||
} else {
|
||||
[renderEncoder setCullMode:MTLCullModeNone];
|
||||
@ -401,7 +422,7 @@ struct PipelineConfig {
|
||||
|
||||
if (_numFaceVaryingElements > 0) {
|
||||
#if FVAR_SINGLE_BUFFER
|
||||
int faceVaryingDataBufferOffset = _doAdaptive ? 0 : _shape->uvs.size() * sizeof(float);
|
||||
int faceVaryingDataBufferOffset = _useAdaptive ? 0 : _shape->uvs.size() * sizeof(float);
|
||||
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:faceVaryingDataBufferOffset atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
|
||||
#else
|
||||
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:0 atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
|
||||
@ -415,7 +436,7 @@ struct PipelineConfig {
|
||||
atIndex:OSD_FVAR_PATCH_ARRAYS_BUFFER_INDEX];
|
||||
}
|
||||
|
||||
if(_doAdaptive)
|
||||
if (_useAdaptive)
|
||||
{
|
||||
[renderCommandEncoder setVertexBuffer:_perPatchTessFactorsBuffer offset:0 atIndex:OSD_PERPATCHTESSFACTORS_BUFFER_INDEX];
|
||||
[renderCommandEncoder setVertexBuffer:_perPatchVertexBuffer offset:0 atIndex:OSD_PERPATCHVERTEX_BUFFER_INDEX];
|
||||
@ -473,7 +494,7 @@ struct PipelineConfig {
|
||||
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.indexBase+(patch.primitiveIdBase*fvarPatch.desc.GetNumControlVertices())) * sizeof(unsigned) atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
|
||||
}
|
||||
|
||||
if(_usePatchIndexBuffer) {
|
||||
if (_usePatchIndexBuffer) {
|
||||
if (pipelineConfig.drawIndexed) {
|
||||
[renderCommandEncoder drawIndexedPatches:pipelineConfig.numControlPointsPerPatchToDraw
|
||||
patchStart:0 patchCount:patch.GetNumPatches()
|
||||
@ -662,12 +683,8 @@ struct PipelineConfig {
|
||||
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||
_numVertices = refBaseLevel.GetNumVertices();
|
||||
|
||||
|
||||
// Adaptive refinement currently supported only for catmull-clark scheme
|
||||
_doAdaptive = (_useAdaptive && scheme == kCatmark);
|
||||
|
||||
Osd::MeshBitset bits;
|
||||
bits.set(Osd::MeshAdaptive, _doAdaptive);
|
||||
bits.set(Osd::MeshAdaptive, _useAdaptive);
|
||||
bits.set(Osd::MeshUseSmoothCornerPatch, _useSmoothCornerPatch);
|
||||
bits.set(Osd::MeshUseSingleCreasePatch, _useSingleCreasePatch);
|
||||
bits.set(Osd::MeshUseInfSharpPatch, _useInfinitelySharpPatch);
|
||||
@ -756,7 +773,7 @@ struct PipelineConfig {
|
||||
stencilTableFactoryOptions.interpolationMode = Far::StencilTableFactory::INTERPOLATE_FACE_VARYING;
|
||||
stencilTableFactoryOptions.generateOffsets = true;
|
||||
stencilTableFactoryOptions.generateControlVerts = false;
|
||||
stencilTableFactoryOptions.generateIntermediateLevels = _doAdaptive;
|
||||
stencilTableFactoryOptions.generateIntermediateLevels = _useAdaptive;
|
||||
stencilTableFactoryOptions.factorizeIntermediateLevels = true;
|
||||
stencilTableFactoryOptions.maxLevel = level;
|
||||
stencilTableFactoryOptions.fvarChannel = 0;
|
||||
@ -841,7 +858,7 @@ struct PipelineConfig {
|
||||
|
||||
pData->TessLevel = static_cast<float>(1 << _tessellationLevel);
|
||||
|
||||
if(_doAdaptive && _usePatchIndexBuffer)
|
||||
if (_useAdaptive && _usePatchIndexBuffer)
|
||||
{
|
||||
for (auto& patch : _mesh->GetPatchTable()->GetPatchArrays())
|
||||
{
|
||||
@ -870,7 +887,7 @@ struct PipelineConfig {
|
||||
_drawIndirectCommandsBuffer.alloc(_context.device, DISPATCHSLOTS, @"draw patch indirect commands");
|
||||
}
|
||||
|
||||
if(_doAdaptive)
|
||||
if (_useAdaptive)
|
||||
{
|
||||
for (auto& patch : _mesh->GetPatchTable()->GetPatchArrays())
|
||||
{
|
||||
@ -892,7 +909,9 @@ struct PipelineConfig {
|
||||
_perPatchVertexOffsets[patchType] = totalPatchDataSize;
|
||||
_tessFactorOffsets[patchType] = totalTessFactorsSize;
|
||||
totalPatchDataSize += elementFloats * sizeof(float) * patch.GetNumPatches() * pipelineConfig.numControlPointsPerPatchToDraw;
|
||||
totalTessFactorsSize += patch.GetNumPatches() * sizeof(MTLQuadTessellationFactorsHalf);
|
||||
totalTessFactorsSize += patch.GetNumPatches() * (pipelineConfig.useTriangleTessellation
|
||||
? sizeof(MTLTriangleTessellationFactorsHalf)
|
||||
: sizeof(MTLQuadTessellationFactorsHalf));
|
||||
}
|
||||
|
||||
totalPatches += patch.GetNumPatches();
|
||||
@ -965,6 +984,7 @@ struct PipelineConfig {
|
||||
DEFINE(INDICES_BUFFER_INDEX,INDICES_BUFFER_INDEX);
|
||||
DEFINE(PATCH_TESSFACTORS_INDEX,PATCH_TESSFACTORS_INDEX);
|
||||
DEFINE(QUAD_TESSFACTORS_INDEX,QUAD_TESSFACTORS_INDEX);
|
||||
DEFINE(TRIANGLE_TESSFACTORS_INDEX,TRIANGLE_TESSFACTORS_INDEX);
|
||||
DEFINE(OSD_PATCH_INDEX_BUFFER_INDEX,OSD_PATCH_INDEX_BUFFER_INDEX);
|
||||
DEFINE(OSD_DRAWINDIRECT_BUFFER_INDEX,OSD_DRAWINDIRECT_BUFFER_INDEX);
|
||||
DEFINE(OSD_KERNELLIMIT_BUFFER_INDEX,OSD_KERNELLIMIT_BUFFER_INDEX);
|
||||
@ -1007,7 +1027,7 @@ struct PipelineConfig {
|
||||
DEFINE(SHADING_TYPE, _shadingMode);
|
||||
DEFINE(OSD_USE_PATCH_INDEX_BUFFER, _usePatchIndexBuffer);
|
||||
DEFINE(OSD_ENABLE_SCREENSPACE_TESSELLATION, _useScreenspaceTessellation);
|
||||
DEFINE(OSD_ENABLE_PATCH_CULL, _usePatchClipCulling && _doAdaptive);
|
||||
DEFINE(OSD_ENABLE_PATCH_CULL, _usePatchClipCulling && _useAdaptive);
|
||||
DEFINE(OSD_FVAR_DATA_BUFFER_INDEX, OSD_FVAR_DATA_BUFFER_INDEX);
|
||||
DEFINE(OSD_FVAR_INDICES_BUFFER_INDEX, OSD_FVAR_INDICES_BUFFER_INDEX);
|
||||
DEFINE(OSD_FVAR_PATCHPARAM_BUFFER_INDEX, OSD_FVAR_PATCHPARAM_BUFFER_INDEX);
|
||||
@ -1063,7 +1083,7 @@ struct PipelineConfig {
|
||||
auto vertexDesc = pipelineDesc.vertexDescriptor;
|
||||
[vertexDesc reset];
|
||||
|
||||
if(_doAdaptive)
|
||||
if (_useAdaptive)
|
||||
{
|
||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatch;
|
||||
vertexDesc.layouts[OSD_PATCHPARAM_BUFFER_INDEX].stepRate = 1;
|
||||
@ -1077,8 +1097,10 @@ struct PipelineConfig {
|
||||
|
||||
switch(patchType)
|
||||
{
|
||||
case Far::PatchDescriptor::LOOP:
|
||||
case Far::PatchDescriptor::REGULAR:
|
||||
case Far::PatchDescriptor::GREGORY_BASIS:
|
||||
case Far::PatchDescriptor::GREGORY_TRIANGLE:
|
||||
if (pipelineConfig.drawIndexed) {
|
||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
|
||||
vertexDesc.layouts[VERTEX_BUFFER_INDEX].stepRate = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user