From c2ed7d5cf01530386ec78a83a94fecd032ca3183 Mon Sep 17 00:00:00 2001 From: David G Yu Date: Thu, 7 Sep 2023 16:44:43 -0700 Subject: [PATCH 1/2] Reorganized legacy patch drawing shader source Relocated from PatchCommon to PatchLegacy several aspects of the shader source which can cause problems with typical use cases. Specifically, things like resource bindings, input assembler and interstage declarations are best left to client code. These are not removed, just relocated and remain available for backward compatibility. Updated the GLSL, HLSL, and MSL source. --- opensubdiv/osd/glslPatchCommon.glsl | 146 +-------------- opensubdiv/osd/glslPatchLegacy.glsl | 122 ++++++++++++ opensubdiv/osd/hlslPatchCommon.hlsl | 128 +------------ opensubdiv/osd/hlslPatchLegacy.hlsl | 122 ++++++++++++ opensubdiv/osd/mtlPatchCommon.metal | 237 +++--------------------- opensubdiv/osd/mtlPatchCommonTess.metal | 4 + opensubdiv/osd/mtlPatchLegacy.metal | 194 +++++++++++++++++++ 7 files changed, 471 insertions(+), 482 deletions(-) diff --git a/opensubdiv/osd/glslPatchCommon.glsl b/opensubdiv/osd/glslPatchCommon.glsl index 1bb113e7..11bfaf62 100644 --- a/opensubdiv/osd/glslPatchCommon.glsl +++ b/opensubdiv/osd/glslPatchCommon.glsl @@ -22,101 +22,11 @@ // language governing permissions and limitations under the Apache License. // -// -// typical shader composition ordering (see glDrawRegistry:_CompileShader) -// -// -// - glsl version string (#version 430) -// -// - common defines (#define OSD_ENABLE_PATCH_CULL, ...) -// - source defines (#define VERTEX_SHADER, ...) -// -// - osd headers (glslPatchCommon: varying structs, -// glslPtexCommon: ptex functions) -// - client header (Osd*Matrix(), displacement callback, ...) -// -// - osd shader source (glslPatchBSpline, glslPatchGregory, ...) -// or -// client shader source (vertex/geometry/fragment shader) -// - -//---------------------------------------------------------- -// Patches.Common -//---------------------------------------------------------- - -// XXXdyu all handling of varying data can be managed by client code -#ifndef OSD_USER_VARYING_DECLARE -#define OSD_USER_VARYING_DECLARE -// type var; -#endif - -#ifndef OSD_USER_VARYING_ATTRIBUTE_DECLARE -#define OSD_USER_VARYING_ATTRIBUTE_DECLARE -// layout(location = loc) in type var; -#endif - -#ifndef OSD_USER_VARYING_PER_VERTEX -#define OSD_USER_VARYING_PER_VERTEX() -// output.var = var; -#endif - -#ifndef OSD_USER_VARYING_PER_CONTROL_POINT -#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN) -// output[ID_OUT].var = input[ID_IN].var -#endif - -#ifndef OSD_USER_VARYING_PER_EVAL_POINT -#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d) -// output.var = -// mix(mix(input[a].var, input[b].var, UV.x), -// mix(input[c].var, input[d].var, UV.x), UV.y) -#endif - -#ifndef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE -#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c) -// output.var = -// input[a].var * (1.0f-UV.x-UV.y) + -// input[b].var * UV.x + -// input[c].var * UV.y; -#endif - -#if __VERSION__ < 420 - #define centroid -#endif - -struct ControlVertex { - vec4 position; -#ifdef OSD_ENABLE_PATCH_CULL - ivec3 clipFlag; -#endif -}; - -// XXXdyu all downstream data can be handled by client code -struct OutputVertex { - vec4 position; - vec3 normal; - vec3 tangent; - vec3 bitangent; - vec4 patchCoord; // u, v, faceLevel, faceId - vec2 tessCoord; // tesscoord.st -#if defined OSD_COMPUTE_NORMAL_DERIVATIVES - vec3 Nu; - vec3 Nv; -#endif -}; - -// osd shaders need following functions defined +// The following callback functions are used when evaluating tessellation +// rates and when using legacy patch drawing. mat4 OsdModelViewMatrix(); mat4 OsdProjectionMatrix(); -mat4 OsdModelViewProjectionMatrix(); float OsdTessLevel(); -int OsdGregoryQuadOffsetBase(); -int OsdPrimitiveIdBase(); -int OsdBaseVertex(); - -#ifndef OSD_DISPLACEMENT_CALLBACK -#define OSD_DISPLACEMENT_CALLBACK -#endif // ---------------------------------------------------------------------------- // Patch Parameters @@ -130,22 +40,6 @@ int OsdBaseVertex(); // bitfield -- refinement-level, non-quad, boundary, transition, uv-offset // sharpness -- crease sharpness for single-crease patches // -// These are stored in OsdPatchParamBuffer indexed by the value returned -// from OsdGetPatchIndex() which is a function of the current PrimitiveID -// along with an optional client provided offset. -// - -uniform isamplerBuffer OsdPatchParamBuffer; - -int OsdGetPatchIndex(int primitiveId) -{ - return (primitiveId + OsdPrimitiveIdBase()); -} - -ivec3 OsdGetPatchParam(int patchIndex) -{ - return texelFetch(OsdPatchParamBuffer, patchIndex).xyz; -} int OsdGetPatchFaceId(ivec3 patchParam) { @@ -239,38 +133,6 @@ vec4 OsdInterpolatePatchCoordTriangle(vec2 localUV, ivec3 patchParam) return result; } -// ---------------------------------------------------------------------------- -// patch culling -// ---------------------------------------------------------------------------- - -#ifdef OSD_ENABLE_PATCH_CULL - -#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \ - vec4 clipPos = OsdModelViewProjectionMatrix() * P; \ - bvec3 clip0 = lessThan(clipPos.xyz, vec3(clipPos.w)); \ - bvec3 clip1 = greaterThan(clipPos.xyz, -vec3(clipPos.w)); \ - outpt.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \ - -#define OSD_PATCH_CULL(N) \ - ivec3 clipFlag = ivec3(0); \ - for(int i = 0; i < N; ++i) { \ - clipFlag |= inpt[i].v.clipFlag; \ - } \ - if (clipFlag != ivec3(3) ) { \ - gl_TessLevelInner[0] = 0; \ - gl_TessLevelInner[1] = 0; \ - gl_TessLevelOuter[0] = 0; \ - gl_TessLevelOuter[1] = 0; \ - gl_TessLevelOuter[2] = 0; \ - gl_TessLevelOuter[3] = 0; \ - return; \ - } - -#else -#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) -#define OSD_PATCH_CULL(N) -#endif - // ---------------------------------------------------------------------------- void @@ -582,7 +444,7 @@ OsdFlipMatrix(mat4 m) } // Regular BSpline to Bezier -uniform mat4 Q = mat4( +const mat4 Q = mat4( 1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f, 0.f, 4.f/6.f, 2.f/6.f, 0.f, 0.f, 2.f/6.f, 4.f/6.f, 0.f, @@ -590,7 +452,7 @@ uniform mat4 Q = mat4( ); // Infinitely Sharp (boundary) -uniform mat4 Mi = mat4( +const mat4 Mi = mat4( 1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f, 0.f, 4.f/6.f, 2.f/6.f, 0.f, 0.f, 2.f/6.f, 4.f/6.f, 0.f, diff --git a/opensubdiv/osd/glslPatchLegacy.glsl b/opensubdiv/osd/glslPatchLegacy.glsl index e1e7002d..ff988178 100644 --- a/opensubdiv/osd/glslPatchLegacy.glsl +++ b/opensubdiv/osd/glslPatchLegacy.glsl @@ -22,6 +22,128 @@ // language governing permissions and limitations under the Apache License. // +//---------------------------------------------------------- +// Patches.Common +//---------------------------------------------------------- + +// XXXdyu all handling of varying data can be managed by client code +#ifndef OSD_USER_VARYING_DECLARE +#define OSD_USER_VARYING_DECLARE +// type var; +#endif + +#ifndef OSD_USER_VARYING_ATTRIBUTE_DECLARE +#define OSD_USER_VARYING_ATTRIBUTE_DECLARE +// layout(location = loc) in type var; +#endif + +#ifndef OSD_USER_VARYING_PER_VERTEX +#define OSD_USER_VARYING_PER_VERTEX() +// output.var = var; +#endif + +#ifndef OSD_USER_VARYING_PER_CONTROL_POINT +#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN) +// output[ID_OUT].var = input[ID_IN].var +#endif + +#ifndef OSD_USER_VARYING_PER_EVAL_POINT +#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d) +// output.var = +// mix(mix(input[a].var, input[b].var, UV.x), +// mix(input[c].var, input[d].var, UV.x), UV.y) +#endif + +#ifndef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE +#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c) +// output.var = +// input[a].var * (1.0f-UV.x-UV.y) + +// input[b].var * UV.x + +// input[c].var * UV.y; +#endif + +#if __VERSION__ < 420 + #define centroid +#endif + +struct ControlVertex { + vec4 position; +#ifdef OSD_ENABLE_PATCH_CULL + ivec3 clipFlag; +#endif +}; + +// XXXdyu all downstream data can be handled by client code +struct OutputVertex { + vec4 position; + vec3 normal; + vec3 tangent; + vec3 bitangent; + vec4 patchCoord; // u, v, faceLevel, faceId + vec2 tessCoord; // tesscoord.st +#if defined OSD_COMPUTE_NORMAL_DERIVATIVES + vec3 Nu; + vec3 Nv; +#endif +}; + +mat4 OsdModelViewProjectionMatrix(); +int OsdGregoryQuadOffsetBase(); +int OsdPrimitiveIdBase(); +int OsdBaseVertex(); + +#ifndef OSD_DISPLACEMENT_CALLBACK +#define OSD_DISPLACEMENT_CALLBACK +#endif + +// These are stored in OsdPatchParamBuffer indexed by the value returned +// from OsdGetPatchIndex() which is a function of the current PrimitiveID +// along with an optional client provided offset. + +uniform isamplerBuffer OsdPatchParamBuffer; + +int OsdGetPatchIndex(int primitiveId) +{ + return (primitiveId + OsdPrimitiveIdBase()); +} + +ivec3 OsdGetPatchParam(int patchIndex) +{ + return texelFetch(OsdPatchParamBuffer, patchIndex).xyz; +} + +// ---------------------------------------------------------------------------- +// patch culling +// ---------------------------------------------------------------------------- + +#ifdef OSD_ENABLE_PATCH_CULL + +#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \ + vec4 clipPos = OsdModelViewProjectionMatrix() * P; \ + bvec3 clip0 = lessThan(clipPos.xyz, vec3(clipPos.w)); \ + bvec3 clip1 = greaterThan(clipPos.xyz, -vec3(clipPos.w)); \ + outpt.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \ + +#define OSD_PATCH_CULL(N) \ + ivec3 clipFlag = ivec3(0); \ + for(int i = 0; i < N; ++i) { \ + clipFlag |= inpt[i].v.clipFlag; \ + } \ + if (clipFlag != ivec3(3) ) { \ + gl_TessLevelInner[0] = 0; \ + gl_TessLevelInner[1] = 0; \ + gl_TessLevelOuter[0] = 0; \ + gl_TessLevelOuter[1] = 0; \ + gl_TessLevelOuter[2] = 0; \ + gl_TessLevelOuter[3] = 0; \ + return; \ + } + +#else +#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) +#define OSD_PATCH_CULL(N) +#endif + // ---------------------------------------------------------------------------- // Legacy Gregory // ---------------------------------------------------------------------------- diff --git a/opensubdiv/osd/hlslPatchCommon.hlsl b/opensubdiv/osd/hlslPatchCommon.hlsl index a824477b..d580e81a 100644 --- a/opensubdiv/osd/hlslPatchCommon.hlsl +++ b/opensubdiv/osd/hlslPatchCommon.hlsl @@ -22,52 +22,11 @@ // language governing permissions and limitations under the Apache License. // -//---------------------------------------------------------- -// Patches.Common -//---------------------------------------------------------- - -struct InputVertex { - float4 position : POSITION; - float3 normal : NORMAL; -}; - -struct HullVertex { - float4 position : POSITION; -#ifdef OSD_ENABLE_PATCH_CULL - int3 clipFlag : CLIPFLAG; -#endif -}; - -// XXXdyu all downstream data can be handled by client code -struct OutputVertex { - float4 positionOut : SV_Position; - float4 position : POSITION1; - float3 normal : NORMAL; - float3 tangent : TANGENT; - float3 bitangent : TANGENT1; - float4 patchCoord : PATCHCOORD; // u, v, faceLevel, faceId - noperspective float4 edgeDistance : EDGEDISTANCE; -#if defined(OSD_COMPUTE_NORMAL_DERIVATIVES) - float3 Nu : TANGENT2; - float3 Nv : TANGENT3; -#endif -#if defined OSD_PATCH_ENABLE_SINGLE_CREASE - float2 vSegments : VSEGMENTS; -#endif -}; - -// osd shaders need following functions defined +// The following callback functions are used when evaluating tessellation +// rates and when using legacy patch drawing. float4x4 OsdModelViewMatrix(); float4x4 OsdProjectionMatrix(); -float4x4 OsdModelViewProjectionMatrix(); float OsdTessLevel(); -int OsdGregoryQuadOffsetBase(); -int OsdPrimitiveIdBase(); -int OsdBaseVertex(); - -#ifndef OSD_DISPLACEMENT_CALLBACK -#define OSD_DISPLACEMENT_CALLBACK -#endif // ---------------------------------------------------------------------------- // Patch Parameters @@ -81,31 +40,6 @@ int OsdBaseVertex(); // bitfield -- refinement-level, non-quad, boundary, transition, uv-offset // sharpness -- crease sharpness for single-crease patches // -// These are stored in OsdPatchParamBuffer indexed by the value returned -// from OsdGetPatchIndex() which is a function of the current PrimitiveID -// along with an optional client provided offset. -// - -#if defined OSD_PATCH_ENABLE_SINGLE_CREASE - Buffer OsdPatchParamBuffer : register( t0 ); -#else - Buffer OsdPatchParamBuffer : register( t0 ); -#endif - -int OsdGetPatchIndex(int primitiveId) -{ - return (primitiveId + OsdPrimitiveIdBase()); -} - -int3 OsdGetPatchParam(int patchIndex) -{ -#if defined OSD_PATCH_ENABLE_SINGLE_CREASE - return OsdPatchParamBuffer[patchIndex].xyz; -#else - uint2 p = OsdPatchParamBuffer[patchIndex].xy; - return int3(p.x, p.y, 0); -#endif -} int OsdGetPatchFaceId(int3 patchParam) { @@ -199,60 +133,6 @@ float4 OsdInterpolatePatchCoordTriangle(float2 localUV, int3 patchParam) return result; } -// ---------------------------------------------------------------------------- -// patch culling -// ---------------------------------------------------------------------------- - -#ifdef OSD_ENABLE_PATCH_CULL - -#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \ - float4 clipPos = mul(OsdModelViewProjectionMatrix(), P); \ - int3 clip0 = int3(clipPos.x < clipPos.w, \ - clipPos.y < clipPos.w, \ - clipPos.z < clipPos.w); \ - int3 clip1 = int3(clipPos.x > -clipPos.w, \ - clipPos.y > -clipPos.w, \ - clipPos.z > -clipPos.w); \ - output.clipFlag = int3(clip0) + 2*int3(clip1); \ - -#define OSD_PATCH_CULL(N) \ - int3 clipFlag = int3(0,0,0); \ - for(int i = 0; i < N; ++i) { \ - clipFlag |= patch[i].clipFlag; \ - } \ - if (any(clipFlag != int3(3,3,3))) { \ - output.tessLevelInner[0] = 0; \ - output.tessLevelInner[1] = 0; \ - output.tessLevelOuter[0] = 0; \ - output.tessLevelOuter[1] = 0; \ - output.tessLevelOuter[2] = 0; \ - output.tessLevelOuter[3] = 0; \ - output.tessOuterLo = float4(0,0,0,0); \ - output.tessOuterHi = float4(0,0,0,0); \ - return output; \ - } - -#define OSD_PATCH_CULL_TRIANGLE(N) \ - int3 clipFlag = int3(0,0,0); \ - for(int i = 0; i < N; ++i) { \ - clipFlag |= patch[i].clipFlag; \ - } \ - if (any(clipFlag != int3(3,3,3))) { \ - output.tessLevelInner[0] = 0; \ - output.tessLevelOuter[0] = 0; \ - output.tessLevelOuter[1] = 0; \ - output.tessLevelOuter[2] = 0; \ - output.tessOuterLo = float4(0,0,0,0); \ - output.tessOuterHi = float4(0,0,0,0); \ - return output; \ - } - -#else -#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) -#define OSD_PATCH_CULL(N) -#define OSD_PATCH_CULL_TRIANGLE(N) -#endif - // ---------------------------------------------------------------------------- void @@ -564,7 +444,7 @@ OsdFlipMatrix(float4x4 m) } // Regular BSpline to Bezier -static float4x4 Q = { +static const float4x4 Q = { 1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f, 0.f, 4.f/6.f, 2.f/6.f, 0.f, 0.f, 2.f/6.f, 4.f/6.f, 0.f, @@ -572,7 +452,7 @@ static float4x4 Q = { }; // Infinitely Sharp (boundary) -static float4x4 Mi = { +static const float4x4 Mi = { 1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f, 0.f, 4.f/6.f, 2.f/6.f, 0.f, 0.f, 2.f/6.f, 4.f/6.f, 0.f, diff --git a/opensubdiv/osd/hlslPatchLegacy.hlsl b/opensubdiv/osd/hlslPatchLegacy.hlsl index 606291ea..5ec5813c 100644 --- a/opensubdiv/osd/hlslPatchLegacy.hlsl +++ b/opensubdiv/osd/hlslPatchLegacy.hlsl @@ -22,6 +22,128 @@ // language governing permissions and limitations under the Apache License. // +//---------------------------------------------------------- +// Patches.Common +//---------------------------------------------------------- + +struct InputVertex { + float4 position : POSITION; + float3 normal : NORMAL; +}; + +struct HullVertex { + float4 position : POSITION; +#ifdef OSD_ENABLE_PATCH_CULL + int3 clipFlag : CLIPFLAG; +#endif +}; + +// XXXdyu all downstream data can be handled by client code +struct OutputVertex { + float4 positionOut : SV_Position; + float4 position : POSITION1; + float3 normal : NORMAL; + float3 tangent : TANGENT; + float3 bitangent : TANGENT1; + float4 patchCoord : PATCHCOORD; // u, v, faceLevel, faceId + noperspective float4 edgeDistance : EDGEDISTANCE; +#if defined(OSD_COMPUTE_NORMAL_DERIVATIVES) + float3 Nu : TANGENT2; + float3 Nv : TANGENT3; +#endif +#if defined OSD_PATCH_ENABLE_SINGLE_CREASE + float2 vSegments : VSEGMENTS; +#endif +}; + +float4x4 OsdModelViewProjectionMatrix(); +int OsdGregoryQuadOffsetBase(); +int OsdPrimitiveIdBase(); +int OsdBaseVertex(); + +#ifndef OSD_DISPLACEMENT_CALLBACK +#define OSD_DISPLACEMENT_CALLBACK +#endif + +// These are stored in OsdPatchParamBuffer indexed by the value returned +// from OsdGetPatchIndex() which is a function of the current PrimitiveID +// along with an optional client provided offset. + +#if defined OSD_PATCH_ENABLE_SINGLE_CREASE + Buffer OsdPatchParamBuffer : register( t0 ); +#else + Buffer OsdPatchParamBuffer : register( t0 ); +#endif + +int OsdGetPatchIndex(int primitiveId) +{ + return (primitiveId + OsdPrimitiveIdBase()); +} + +int3 OsdGetPatchParam(int patchIndex) +{ +#if defined OSD_PATCH_ENABLE_SINGLE_CREASE + return OsdPatchParamBuffer[patchIndex].xyz; +#else + uint2 p = OsdPatchParamBuffer[patchIndex].xy; + return int3(p.x, p.y, 0); +#endif +} + +// ---------------------------------------------------------------------------- +// patch culling +// ---------------------------------------------------------------------------- + +#ifdef OSD_ENABLE_PATCH_CULL + +#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \ + float4 clipPos = mul(OsdModelViewProjectionMatrix(), P); \ + int3 clip0 = int3(clipPos.x < clipPos.w, \ + clipPos.y < clipPos.w, \ + clipPos.z < clipPos.w); \ + int3 clip1 = int3(clipPos.x > -clipPos.w, \ + clipPos.y > -clipPos.w, \ + clipPos.z > -clipPos.w); \ + output.clipFlag = int3(clip0) + 2*int3(clip1); \ + +#define OSD_PATCH_CULL(N) \ + int3 clipFlag = int3(0,0,0); \ + for(int i = 0; i < N; ++i) { \ + clipFlag |= patch[i].clipFlag; \ + } \ + if (any(clipFlag != int3(3,3,3))) { \ + output.tessLevelInner[0] = 0; \ + output.tessLevelInner[1] = 0; \ + output.tessLevelOuter[0] = 0; \ + output.tessLevelOuter[1] = 0; \ + output.tessLevelOuter[2] = 0; \ + output.tessLevelOuter[3] = 0; \ + output.tessOuterLo = float4(0,0,0,0); \ + output.tessOuterHi = float4(0,0,0,0); \ + return output; \ + } + +#define OSD_PATCH_CULL_TRIANGLE(N) \ + int3 clipFlag = int3(0,0,0); \ + for(int i = 0; i < N; ++i) { \ + clipFlag |= patch[i].clipFlag; \ + } \ + if (any(clipFlag != int3(3,3,3))) { \ + output.tessLevelInner[0] = 0; \ + output.tessLevelOuter[0] = 0; \ + output.tessLevelOuter[1] = 0; \ + output.tessLevelOuter[2] = 0; \ + output.tessOuterLo = float4(0,0,0,0); \ + output.tessOuterHi = float4(0,0,0,0); \ + return output; \ + } + +#else +#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) +#define OSD_PATCH_CULL(N) +#define OSD_PATCH_CULL_TRIANGLE(N) +#endif + // ---------------------------------------------------------------------------- // Legacy Gregory // ---------------------------------------------------------------------------- diff --git a/opensubdiv/osd/mtlPatchCommon.metal b/opensubdiv/osd/mtlPatchCommon.metal index 60c1a18d..8d0ea18c 100644 --- a/opensubdiv/osd/mtlPatchCommon.metal +++ b/opensubdiv/osd/mtlPatchCommon.metal @@ -24,173 +24,15 @@ // language governing permissions and limitations under the Apache License. // -//---------------------------------------------------------- -// Patches.Common -//---------------------------------------------------------- - #include -#define offsetof_(X, Y) &(((device X*)nullptr)->Y) - -#define OSD_IS_ADAPTIVE (OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY) - -#ifndef OSD_MAX_TESS_LEVEL -#define OSD_MAX_TESS_LEVEL 64 -#endif - -#ifndef OSD_NUM_ELEMENTS -#define OSD_NUM_ELEMENTS 3 -#endif - using namespace metal; -using OsdPatchParamBufferType = packed_int3; - -struct OsdPerVertexGregory { - float3 P; - short3 clipFlag; - int valence; - float3 e0; - float3 e1; -#if OSD_PATCH_GREGORY_BOUNDARY - int zerothNeighbor; - float3 org; -#endif - float3 r[OSD_MAX_VALENCE]; -}; - -struct OsdPerPatchVertexGregory { - packed_float3 P; - packed_float3 Ep; - packed_float3 Em; - packed_float3 Fp; - packed_float3 Fm; -}; - -//---------------------------------------------------------- -// HLSL->Metal Compatibility -//---------------------------------------------------------- - -float4 mul(float4x4 a, float4 b) -{ - return a * b; -} - -float3 mul(float4x4 a, float3 b) -{ - float3x3 m(a[0].xyz, a[1].xyz, a[2].xyz); - return m * b; - -} - -//---------------------------------------------------------- -// Patches.Common -//---------------------------------------------------------- - -struct HullVertex { - float4 position; -#if OSD_ENABLE_PATCH_CULL - short3 clipFlag; -#endif - - float3 GetPosition() threadgroup - { - return position.xyz; - } - - void SetPosition(float3 v) threadgroup - { - position.xyz = v; - } -}; - -// XXXdyu all downstream data can be handled by client code -struct OsdPatchVertex { - float3 position; - float3 normal; - float3 tangent; - float3 bitangent; - float4 patchCoord; //u, v, faceLevel, faceId - float2 tessCoord; // tesscoord.st -#if OSD_COMPUTE_NORMAL_DERIVATIVES - float3 Nu; - float3 Nv; -#endif -#if OSD_PATCH_ENABLE_SINGLE_CREASE - float2 vSegments; -#endif -}; - -struct OsdPerPatchTessFactors { - float4 tessOuterLo; - float4 tessOuterHi; -}; - -struct OsdPerPatchVertexBezier { - packed_float3 P; -#if OSD_PATCH_ENABLE_SINGLE_CREASE - packed_float3 P1; - packed_float3 P2; -#if !USE_PTVS_SHARPNESS - float2 vSegments; -#endif -#endif -}; - -struct OsdPerPatchVertexGregoryBasis { - packed_float3 P; -}; - -#if OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE -using PatchVertexType = HullVertex; -using PerPatchVertexType = OsdPerPatchVertexBezier; -#elif OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY -using PatchVertexType = OsdPerVertexGregory; -using PerPatchVertexType = OsdPerPatchVertexGregory; -#elif OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE -using PatchVertexType = HullVertex; -using PerPatchVertexType = OsdPerPatchVertexGregoryBasis; -#else -using PatchVertexType = OsdInputVertexType; -using PerPatchVertexType = OsdInputVertexType; -#endif - -//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 OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]]; - - device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]]; - -#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)]]; -#endif - - 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 OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]]; - - device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]]; - -#if !USE_PTVS_FACTORS - device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]]; -#endif -}; +// The following callback functions are used when evaluating tessellation +// rates and when using legacy patch drawing. +float4x4 OsdModelViewMatrix(); +float4x4 OsdProjectionMatrix(); +float OsdTessLevel(); // ---------------------------------------------------------------------------- // Patch Parameters @@ -204,25 +46,6 @@ struct OsdVertexBufferSet // bitfield -- refinement-level, non-quad, boundary, transition, uv-offset // sharpness -- crease sharpness for single-crease patches // -// These are stored in OsdPatchParamBuffer indexed by the value returned -// from OsdGetPatchIndex() which is a function of the current PrimitiveID -// along with an optional client provided offset. -// - -int3 OsdGetPatchParam(int patchIndex, const device OsdPatchParamBufferType* osdPatchParamBuffer) -{ -#if OSD_PATCH_ENABLE_SINGLE_CREASE - return int3(osdPatchParamBuffer[patchIndex]); -#else - auto p = osdPatchParamBuffer[patchIndex]; - return int3(p[0], p[1], 0); -#endif -} - -int OsdGetPatchIndex(int primitiveId) -{ - return primitiveId; -} int OsdGetPatchFaceId(int3 patchParam) { @@ -316,40 +139,6 @@ float4 OsdInterpolatePatchCoordTriangle(float2 localUV, int3 patchParam) return result; } -// ---------------------------------------------------------------------------- -// patch culling -// ---------------------------------------------------------------------------- - -bool OsdCullPerPatchVertex( - threadgroup PatchVertexType* patch, - float4x4 ModelViewMatrix - ) -{ -#if OSD_ENABLE_BACKPATCH_CULL && OSD_PATCH_REGULAR - auto v0 = float3(ModelViewMatrix * patch[5].position); - auto v3 = float3(ModelViewMatrix * patch[6].position); - auto v12 = float3(ModelViewMatrix * patch[9].position); - - auto n = normalize(cross(v3 - v0, v12 - v0)); - v0 = normalize(v0 + v3 + v12); - - if(dot(v0, n) > 0.6f) - { - return false; - } -#endif -#if OSD_ENABLE_PATCH_CULL - short3 clipFlag = short3(0,0,0); - for(int i = 0; i < CONTROL_POINTS_PER_PATCH; ++i) { - clipFlag |= patch[i].clipFlag; - } - if (any(clipFlag != short3(3,3,3))) { - return false; - } -#endif - return true; -} - // ---------------------------------------------------------------------------- void @@ -421,6 +210,17 @@ OsdUnivar4x4(float u, thread float* B, thread float* D, thread float* C) // ---------------------------------------------------------------------------- +struct OsdPerPatchVertexBezier { + packed_float3 P; +#if OSD_PATCH_ENABLE_SINGLE_CREASE + packed_float3 P1; + packed_float3 P2; +#if !USE_PTVS_SHARPNESS + float2 vSegments; +#endif +#endif +}; + float3 OsdEvalBezier(float3 cp[16], float2 uv) { @@ -1088,6 +888,10 @@ OsdEvalPatchBezier(int3 patchParam, float2 UV, // Gregory Basis // ---------------------------------------------------------------------------- +struct OsdPerPatchVertexGregoryBasis { + packed_float3 P; +}; + void OsdComputePerPatchVertexGregoryBasis(int3 patchParam, int ID, float3 cv, device OsdPerPatchVertexGregoryBasis& result) @@ -1444,3 +1248,4 @@ OsdEvalPatchGregoryTriangle(int3 patchParam, float2 UV, float3 cv[18], OsdEvalPatchBezierTriangle(patchParam, UV, bezcv, P, dPu, dPv, N, dNu, dNv); } + diff --git a/opensubdiv/osd/mtlPatchCommonTess.metal b/opensubdiv/osd/mtlPatchCommonTess.metal index f75f7426..7818ff09 100644 --- a/opensubdiv/osd/mtlPatchCommonTess.metal +++ b/opensubdiv/osd/mtlPatchCommonTess.metal @@ -81,6 +81,10 @@ // (0,0) (1,0) // +#ifndef OSD_MAX_TESS_LEVEL +#define OSD_MAX_TESS_LEVEL 64 +#endif + float OsdComputePostProjectionSphereExtent( const float4x4 OsdProjectionMatrix, float3 center, float diameter) { diff --git a/opensubdiv/osd/mtlPatchLegacy.metal b/opensubdiv/osd/mtlPatchLegacy.metal index a171e3ce..987e6a75 100644 --- a/opensubdiv/osd/mtlPatchLegacy.metal +++ b/opensubdiv/osd/mtlPatchLegacy.metal @@ -24,6 +24,200 @@ // language governing permissions and limitations under the Apache License. // +//---------------------------------------------------------- +// Patches.Common +//---------------------------------------------------------- + +#define offsetof_(X, Y) &(((device X*)nullptr)->Y) + +#define OSD_IS_ADAPTIVE (OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY) + +#ifndef OSD_NUM_ELEMENTS +#define OSD_NUM_ELEMENTS 3 +#endif + +struct OsdPerVertexGregory { + float3 P; + short3 clipFlag; + int valence; + float3 e0; + float3 e1; +#if OSD_PATCH_GREGORY_BOUNDARY + int zerothNeighbor; + float3 org; +#endif + float3 r[OSD_MAX_VALENCE]; +}; + +struct OsdPerPatchVertexGregory { + packed_float3 P; + packed_float3 Ep; + packed_float3 Em; + packed_float3 Fp; + packed_float3 Fm; +}; + +//---------------------------------------------------------- +// HLSL->Metal Compatibility +//---------------------------------------------------------- + +float4 mul(float4x4 a, float4 b) +{ + return a * b; +} + +float3 mul(float4x4 a, float3 b) +{ + float3x3 m(a[0].xyz, a[1].xyz, a[2].xyz); + return m * b; + +} + +struct HullVertex { + float4 position; +#if OSD_ENABLE_PATCH_CULL + short3 clipFlag; +#endif + + float3 GetPosition() threadgroup + { + return position.xyz; + } + + void SetPosition(float3 v) threadgroup + { + position.xyz = v; + } +}; + +// XXXdyu all downstream data can be handled by client code +struct OsdPatchVertex { + float3 position; + float3 normal; + float3 tangent; + float3 bitangent; + float4 patchCoord; //u, v, faceLevel, faceId + float2 tessCoord; // tesscoord.st +#if OSD_COMPUTE_NORMAL_DERIVATIVES + float3 Nu; + float3 Nv; +#endif +#if OSD_PATCH_ENABLE_SINGLE_CREASE + float2 vSegments; +#endif +}; + +struct OsdPerPatchTessFactors { + float4 tessOuterLo; + float4 tessOuterHi; +}; + +using OsdPatchParamBufferType = packed_int3; + +#if OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE +using PatchVertexType = HullVertex; +using PerPatchVertexType = OsdPerPatchVertexBezier; +#elif OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY +using PatchVertexType = OsdPerVertexGregory; +using PerPatchVertexType = OsdPerPatchVertexGregory; +#elif OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE +using PatchVertexType = HullVertex; +using PerPatchVertexType = OsdPerPatchVertexGregoryBasis; +#else +using PatchVertexType = OsdInputVertexType; +using PerPatchVertexType = OsdInputVertexType; +#endif + +//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 OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]]; + + device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]]; + +#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)]]; +#endif + + 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 OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]]; + + device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]]; + +#if !USE_PTVS_FACTORS + device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]]; +#endif +}; + +// These are stored in OsdPatchParamBuffer indexed by the value returned +// from OsdGetPatchIndex() which is a function of the current PrimitiveID +// along with an optional client provided offset. + +int3 OsdGetPatchParam(int patchIndex, const device OsdPatchParamBufferType* osdPatchParamBuffer) +{ +#if OSD_PATCH_ENABLE_SINGLE_CREASE + return int3(osdPatchParamBuffer[patchIndex]); +#else + auto p = osdPatchParamBuffer[patchIndex]; + return int3(p[0], p[1], 0); +#endif +} + +int OsdGetPatchIndex(int primitiveId) +{ + return primitiveId; +} + +// ---------------------------------------------------------------------------- +// patch culling +// ---------------------------------------------------------------------------- + +bool OsdCullPerPatchVertex( + threadgroup PatchVertexType* patch, + float4x4 ModelViewMatrix + ) +{ +#if OSD_ENABLE_BACKPATCH_CULL && OSD_PATCH_REGULAR + auto v0 = float3(ModelViewMatrix * patch[5].position); + auto v3 = float3(ModelViewMatrix * patch[6].position); + auto v12 = float3(ModelViewMatrix * patch[9].position); + + auto n = normalize(cross(v3 - v0, v12 - v0)); + v0 = normalize(v0 + v3 + v12); + + if(dot(v0, n) > 0.6f) + { + return false; + } +#endif +#if OSD_ENABLE_PATCH_CULL + short3 clipFlag = short3(0,0,0); + for(int i = 0; i < CONTROL_POINTS_PER_PATCH; ++i) { + clipFlag |= patch[i].clipFlag; + } + if (any(clipFlag != short3(3,3,3))) { + return false; + } +#endif + return true; +} + // ---------------------------------------------------------------------------- // Legacy Gregory // ---------------------------------------------------------------------------- From fdb9ac9afbbf7c680f15ec5e3df4eb1d6875480d Mon Sep 17 00:00:00 2001 From: David G Yu Date: Thu, 7 Sep 2023 16:46:26 -0700 Subject: [PATCH 2/2] Added GetPatchDrawingShaderSource() This is a new method for GLSL, HLSL, and MSL which returns patch drawing shader source which excludes legacy shader source aspects. This improves portability and compatibility and may also improve shader compile times since the resulting shader source strings are smaller without the legacy shader source aspects. Tested with Vulkan and DX12 in addition to GL, DX11, and Metal. --- opensubdiv/osd/glslPatchShaderSource.cpp | 10 ++++++++- opensubdiv/osd/glslPatchShaderSource.h | 27 ++++++++++++++++++++--- opensubdiv/osd/hlslPatchShaderSource.cpp | 10 ++++++++- opensubdiv/osd/hlslPatchShaderSource.h | 27 ++++++++++++++++++++--- opensubdiv/osd/mtlPatchShaderSource.h | 28 +++++++++++++++++++++--- opensubdiv/osd/mtlPatchShaderSource.mm | 15 ++++++++----- 6 files changed, 101 insertions(+), 16 deletions(-) diff --git a/opensubdiv/osd/glslPatchShaderSource.cpp b/opensubdiv/osd/glslPatchShaderSource.cpp index 81a78041..f6f9f51b 100644 --- a/opensubdiv/osd/glslPatchShaderSource.cpp +++ b/opensubdiv/osd/glslPatchShaderSource.cpp @@ -67,10 +67,18 @@ static const char *gregoryTriangleShaderSource = /*static*/ std::string -GLSLPatchShaderSource::GetCommonShaderSource() { +GLSLPatchShaderSource::GetPatchDrawingShaderSource() { std::stringstream ss; ss << std::string(commonShaderSource); ss << std::string(commonTessShaderSource); + return ss.str(); +} + +/*static*/ +std::string +GLSLPatchShaderSource::GetCommonShaderSource() { + std::stringstream ss; + ss << GetPatchDrawingShaderSource(); ss << std::string(patchLegacyShaderSource); return ss.str(); } diff --git a/opensubdiv/osd/glslPatchShaderSource.h b/opensubdiv/osd/glslPatchShaderSource.h index 579a41ff..487fa411 100644 --- a/opensubdiv/osd/glslPatchShaderSource.h +++ b/opensubdiv/osd/glslPatchShaderSource.h @@ -26,20 +26,39 @@ #define OPENSUBDIV3_OSD_GLSL_PATCH_SHADER_SOURCE_H #include "../version.h" -#include + #include "../far/patchDescriptor.h" +#include + namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Osd { +/// \brief Provides shader source which can be used by client code. class GLSLPatchShaderSource { public: - static std::string GetCommonShaderSource(); - + /// \brief Returns shader source which can be used to evaluate + /// position and first and second derivatives on piecewise parametric + /// patches resulting from subdivision refinement. static std::string GetPatchBasisShaderSource(); + /// \brief Returns shader source which can be used while drawing + /// piecewise parametric patches resulting from subdivision refinement, + /// e.g. while using GPU HW tessellation. + static std::string GetPatchDrawingShaderSource(); + + /// \name Alternative methods + /// \{ + /// These methods return shader source which can be used + /// while drawing. Unlike the methods above, the source returned + /// by these methods includes support for legacy patch types along + /// with dependencies on specific resource bindings and interstage + /// shader variable declarations. + + static std::string GetCommonShaderSource(); + static std::string GetVertexShaderSource( Far::PatchDescriptor::Type type); @@ -48,6 +67,8 @@ public: static std::string GetTessEvalShaderSource( Far::PatchDescriptor::Type type); + + /// \} }; } // end namespace Osd diff --git a/opensubdiv/osd/hlslPatchShaderSource.cpp b/opensubdiv/osd/hlslPatchShaderSource.cpp index 6a3bba49..977835b1 100644 --- a/opensubdiv/osd/hlslPatchShaderSource.cpp +++ b/opensubdiv/osd/hlslPatchShaderSource.cpp @@ -69,10 +69,18 @@ static const char *gregoryTriangleShaderSource = /*static*/ std::string -HLSLPatchShaderSource::GetCommonShaderSource() { +HLSLPatchShaderSource::GetPatchDrawingShaderSource() { std::stringstream ss; ss << std::string(commonShaderSource); ss << std::string(commonTessShaderSource); + return ss.str(); +} + +/*static*/ +std::string +HLSLPatchShaderSource::GetCommonShaderSource() { + std::stringstream ss; + ss << GetPatchDrawingShaderSource(); ss << std::string(patchLegacyShaderSource); return ss.str(); } diff --git a/opensubdiv/osd/hlslPatchShaderSource.h b/opensubdiv/osd/hlslPatchShaderSource.h index 028637a9..96f55d93 100644 --- a/opensubdiv/osd/hlslPatchShaderSource.h +++ b/opensubdiv/osd/hlslPatchShaderSource.h @@ -26,25 +26,46 @@ #define OPENSUBDIV3_OSD_HLSL_PATCH_SHADER_SOURCE_H #include "../version.h" -#include + #include "../far/patchDescriptor.h" +#include + namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Osd { +/// \brief Provides shader source which can be used by client code. class HLSLPatchShaderSource { public: - static std::string GetCommonShaderSource(); - + /// \brief Returns shader source which can be used to evaluate + /// position and first and second derivatives on piecewise parametric + /// patches resulting from subdivision refinement. static std::string GetPatchBasisShaderSource(); + /// \brief Returns shader source which can be used while drawing + /// piecewise parametric patches resulting from subdivision refinement, + /// e.g. while using GPU HW tessellation. + static std::string GetPatchDrawingShaderSource(); + + /// \name Alternative methods + /// \{ + /// These methods return shader source which can be used + /// while drawing. Unlike the methods above, the source returned + /// by these methods includes support for legacy patch types along + /// with dependencies on specific resource bindings and interstage + /// shader variable declarations. + + static std::string GetCommonShaderSource(); + static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type); static std::string GetHullShaderSource(Far::PatchDescriptor::Type type); static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type); + + /// @} }; } // end namespace Osd diff --git a/opensubdiv/osd/mtlPatchShaderSource.h b/opensubdiv/osd/mtlPatchShaderSource.h index 54bbf6cd..616b7725 100644 --- a/opensubdiv/osd/mtlPatchShaderSource.h +++ b/opensubdiv/osd/mtlPatchShaderSource.h @@ -26,7 +26,9 @@ #define OPENSUBDIV3_OSD_MTL_PATCH_SHADER_SOURCE_H #import "../version.h" + #import "../far/patchDescriptor.h" + #import namespace OpenSubdiv { @@ -34,12 +36,29 @@ namespace OPENSUBDIV_VERSION { namespace Osd { +/// \brief Provides shader source which can be used by client code. class MTLPatchShaderSource { - public: - static std::string GetCommonShaderSource(); - +public: + /// \brief Returns shader source which can be used to evaluate + /// position and first and second derivatives on piecewise parametric + /// patches resulting from subdivision refinement. static std::string GetPatchBasisShaderSource(); + /// \brief Returns shader source which can be used while drawing + /// piecewise parametric patches resulting from subdivision refinement, + /// e.g. while using GPU HW tessellation. + static std::string GetPatchDrawingShaderSource(); + + /// \name Alternative methods + /// \{ + /// These methods return shader source which can be used + /// while drawing. Unlike the methods above, the source returned + /// by these methods includes support for legacy patch types along + /// with dependencies on specific resource bindings and interstage + /// shader variable declarations. + + static std::string GetCommonShaderSource(); + static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type); static std::string GetHullShaderSource(Far::PatchDescriptor::Type type); @@ -59,6 +78,9 @@ class MTLPatchShaderSource { static std::string GetDomainShaderSource( Far::PatchDescriptor::Type type, Far::PatchDescriptor::Type fvarType); + + /// @} + }; } // end namespace Osd diff --git a/opensubdiv/osd/mtlPatchShaderSource.mm b/opensubdiv/osd/mtlPatchShaderSource.mm index 754909f0..d73b3aae 100644 --- a/opensubdiv/osd/mtlPatchShaderSource.mm +++ b/opensubdiv/osd/mtlPatchShaderSource.mm @@ -147,20 +147,25 @@ GetPatchTypeSource(Far::PatchDescriptor::Type type) { /*static*/ std::string -MTLPatchShaderSource::GetCommonShaderSource() { +MTLPatchShaderSource::GetPatchDrawingShaderSource() { #if TARGET_OS_IOS || TARGET_OS_TV return std::string("#define OSD_METAL_IOS 1\n") .append(commonShaderSource) - .append(commonTessShaderSource) - .append(patchLegacyShaderSource); + .append(commonTessShaderSource); #elif TARGET_OS_OSX return std::string("#define OSD_METAL_OSX 1\n") .append(commonShaderSource) - .append(commonTessShaderSource) - .append(patchLegacyShaderSource); + .append(commonTessShaderSource); #endif } +/*static*/ +std::string +MTLPatchShaderSource::GetCommonShaderSource() { + return GetPatchDrawingShaderSource() + .append(patchLegacyShaderSource); +} + /*static*/ std::string MTLPatchShaderSource::GetPatchBasisShaderSource() {