mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-09 00:00:18 +00:00
Mtl implementation whitespace fixes
Fixed numerous whitespace inconsistencies and violations in the core osd metal implementation and examples.
This commit is contained in:
parent
24c37eecd3
commit
291eff0bed
@ -48,42 +48,42 @@ const constant float4 patchColors[] = {
|
||||
float4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
||||
float4(0.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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
@ -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
|
||||
|
@ -315,6 +315,4 @@ kernel void eval_patches(
|
||||
if(args.dvvDesc.y > 0)
|
||||
writeDvv(current, dvv, dvvDerivativeBuffer, args);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -96,5 +96,6 @@ void MTLLegacyGregoryPatchTable::UpdateVertexBuffer(id<MTLBuffer> vbo, int numVe
|
||||
}
|
||||
|
||||
} //end namespace Osd
|
||||
|
||||
} //end namespace OPENSUBDIV_VERSION
|
||||
} //end namespace OpenSubdiv
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user