Mtl implementation fixed example fvar interp

Refactored the Metal viewer's implementation of
smooth face-varying uv interpolation so that the
face-varying patch basis is correctly determined
by inspecting the face-varying patch array type
descriptors.
This commit is contained in:
David G Yu 2019-05-24 16:35:08 -07:00
parent 8912b3f3d3
commit ebf2917dc7
4 changed files with 213 additions and 132 deletions

View File

@ -390,6 +390,49 @@ kernel void compute_main(
}
}
#if SHADING_TYPE == SHADING_TYPE_FACE_VARYING
float3
interpolateFaceVaryingColor(
int patch_id,
float2 uv,
const device float* fvarData,
const device int* fvarIndices,
const device packed_int3* fvarPatchParams,
const constant int* fvarPatchArrays)
{
OsdPatchArray fvarPatchArray = OsdPatchArrayInit(
fvarPatchArrays[0],
fvarPatchArrays[1],
fvarPatchArrays[2],
fvarPatchArrays[3],
fvarPatchArrays[4],
fvarPatchArrays[5]);
OsdPatchParam fvarParam = OsdPatchParamInit(
fvarPatchParams[patch_id][0],
fvarPatchParams[patch_id][1],
fvarPatchParams[patch_id][2]);
int fvarPatchType = OsdPatchParamIsRegular(fvarParam)
? fvarPatchArray.regDesc
: fvarPatchArray.desc;
float wP[20], wDu[20], wDv[20], wDuu[20], wDuv[20], wDvv[20];
int numPoints = OsdEvaluatePatchBasisNormalized(fvarPatchType, fvarParam,
uv.x, uv.y, wP, wDu, wDv, wDuu, wDuv, wDvv);
int primOffset = patch_id * fvarPatchArray.stride;
float2 interpUV = float2(0);
for (int i = 0; i < numPoints; ++i) {
int index = fvarIndices[primOffset + i] * 2 /* OSD_FVAR_WIDTH */ + 0 /* fvarOffset */;
float2 cv = float2(fvarData[index + 0], fvarData[index + 1]);
interpUV += wP[i] * cv;
}
return float3(interpUV, 0);
}
#endif
[[patch(quad, VERTEX_CONTROL_POINTS_PER_PATCH)]]
vertex OutputVertex vertex_main(
const constant PerFrameConstants& frameConsts [[buffer(FRAME_CONST_BUFFER_INDEX)]],
@ -401,6 +444,7 @@ vertex OutputVertex vertex_main(
const device float* osdFaceVaryingData [[buffer(OSD_FVAR_DATA_BUFFER_INDEX)]],
const device int* osdFaceVaryingIndices [[buffer(OSD_FVAR_INDICES_BUFFER_INDEX)]],
const device packed_int3* osdFaceVaryingPatchParams [[buffer(OSD_FVAR_PATCHPARAM_BUFFER_INDEX)]],
const constant int* osdFaceVaryingPatchArrays [[buffer(OSD_FVAR_PATCH_ARRAYS_BUFFER_INDEX)]],
float2 position_in_patch [[position_in_patch]],
uint patch_id [[patch_id]]
)
@ -433,51 +477,13 @@ vertex OutputVertex vertex_main(
#elif SHADING_TYPE == SHADING_TYPE_PATCH_COORD
out.patchColor = patchVertex.patchCoord.xyz;
#elif SHADING_TYPE == SHADING_TYPE_FACE_VARYING
int patchIndex = OsdGetPatchIndex(patch_id);
float2 uv = patchVertex.tessCoord;
#if OSD_FACEVARYING_PATCH_REGULAR
float wP[16], wDs[16], wDt[16], wDss[16], wDst[16], wDtt[16];
int patchCVs = 16;
int patchStride = patchCVs;
int3 fvarPatchParam = osdFaceVaryingPatchParams[patchIndex];
int boundaryMask = OsdGetPatchBoundaryMask(fvarPatchParam);
OsdGetBSplinePatchWeights(uv.x, uv.y, 1.0f, boundaryMask, wP, wDs, wDt, wDss, wDst, wDtt);
#elif OSD_FACEVARYING_PATCH_GREGORY_BASIS
float wP[20], wDs[20], wDt[20], wDss[20], wDst[20], wDtt[20];
int patchCVs = 20;
int patchStride = patchCVs;
int3 fvarPatchParam = osdFaceVaryingPatchParams[patchIndex];
if (OsdGetPatchIsRegular(fvarPatchParam)) {
float wP16[16], wDs16[16], wDt16[16], wDss16[16], wDst16[16], wDtt16[16];
patchCVs = 16;
int boundaryMask = OsdGetPatchBoundaryMask(fvarPatchParam);
OsdGetBSplinePatchWeights(uv.x, uv.y, 1.0f, boundaryMask, wP16, wDs16, wDt16, wDss16, wDst16, wDtt16);
for (int i=0; i<patchCVs; ++i) {
wP[i] = wP16[i];
}
} else {
OsdGetGregoryPatchWeights(uv.x, uv.y, 1.0f, wP, wDs, wDt, wDss, wDst, wDtt);
}
#elif OSD_FACEVARYING_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
TODO
#else
float wP[4], wDs[4], wDt[4], wDss[4], wDst[4], wDtt[4];
int patchCVs = 4;
int patchStride = patchCVs;
OsdGetBilinearPatchWeights(uv.x, uv.y, 1.0f, wP, wDs, wDt, wDss, wDst, wDtt);
#endif
int primOffset = patchIndex * patchStride;
float2 fvarUV = float2(0.);
for (int i = 0; i < patchCVs; ++i) {
int index = osdFaceVaryingIndices[primOffset + i] * 2 /* OSD_FVAR_WIDTH */ + 0 /* fvarOffset */;
float2 cv = float2(osdFaceVaryingData[index + 0], osdFaceVaryingData[index + 1]);
fvarUV += wP[i] * cv;
}
out.patchColor.rg = fvarUV;
out.patchColor = interpolateFaceVaryingColor(
patch_id,
patchVertex.tessCoord.xy,
osdFaceVaryingData,
osdFaceVaryingIndices,
osdFaceVaryingPatchParams,
osdFaceVaryingPatchArrays);
#endif
return out;

View File

@ -70,12 +70,11 @@
#define OSD_FVAR_DATA_BUFFER_INDEX 16
#define OSD_FVAR_INDICES_BUFFER_INDEX 17
#define OSD_FVAR_PATCHPARAM_BUFFER_INDEX 18
#define OSD_FVAR_PATCH_ARRAYS_BUFFER_INDEX 19
#define FRAME_CONST_BUFFER_INDEX 11
#define INDICES_BUFFER_INDEX 2
#define USE_FACE_VARYING 1
#define FVAR_SINGLE_BUFFER 1
using namespace OpenSubdiv::OPENSUBDIV_VERSION;
@ -204,8 +203,8 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
self.kernelType = kMetal;
self.refinementLevel = 2;
self.tessellationLevel = 8;
self.shadingMode = kShadingMaterial;
self.displayStyle = kDisplayStyleShaded;
self.shadingMode = kShadingPatchType;
self.displayStyle = kDisplayStyleWireOnShaded;
_frameCount = 0;
_animationFrames = 0;
@ -302,18 +301,25 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
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];
if (_numFaceVaryingElements > 0) {
#if FVAR_SINGLE_BUFFER
int faceVaryingDataBufferOffset = _doAdaptive ? 0 : _shape->uvs.size() * sizeof(float);
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:faceVaryingDataBufferOffset atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
int faceVaryingDataBufferOffset = _doAdaptive ? 0 : _shape->uvs.size() * sizeof(float);
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:faceVaryingDataBufferOffset atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
#else
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:0 atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
[renderCommandEncoder setVertexBuffer:_faceVaryingDataBuffer offset:0 atIndex:OSD_FVAR_DATA_BUFFER_INDEX];
#endif
[renderCommandEncoder setVertexBuffer:_faceVaryingIndicesBuffer offset:0 atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
[renderCommandEncoder setVertexBuffer:_faceVaryingIndicesBuffer offset:0 atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
auto fvarPatchArrays = _mesh->GetPatchTable()->GetFVarPatchArrays();
[renderCommandEncoder setVertexBytes:fvarPatchArrays.data()
length:fvarPatchArrays.size() *
sizeof(fvarPatchArrays[0])
atIndex:OSD_FVAR_PATCH_ARRAYS_BUFFER_INDEX];
}
if(_doAdaptive)
{
@ -321,7 +327,11 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
[renderCommandEncoder setVertexBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXBEZIER_BUFFER_INDEX];
[renderCommandEncoder setVertexBuffer:_mesh->GetPatchTable()->GetPatchParamBuffer() offset:0 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
[renderCommandEncoder setVertexBuffer:_perPatchDataBuffer offset:0 atIndex:OSD_PERPATCHVERTEXGREGORY_BUFFER_INDEX];
[renderCommandEncoder setVertexBuffer:_faceVaryingPatchParamBuffer offset:0 atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
if (_numFaceVaryingElements > 0) {
[renderCommandEncoder setVertexBuffer:_faceVaryingPatchParamBuffer
offset:0
atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
}
}
if(_endCapMode == kEndCapLegacyGregory)
@ -352,11 +362,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
{
[renderCommandEncoder setVertexBufferOffset:patch.primitiveIdBase * sizeof(int) * 3 atIndex:OSD_PATCHPARAM_BUFFER_INDEX];
auto& fvarPatch = pfvarav[i];
assert(sizeof(Osd::PatchParam) == sizeof(int) * 3);
if (_numFaceVaryingElements > 0) {
auto pfvarav = _mesh->GetPatchTable()->GetFVarPatchArrays();
auto& fvarPatch = pfvarav[0]; // XXXdyu-mtl
assert(sizeof(Osd::PatchParam) == sizeof(int) * 3);
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.primitiveIdBase+patch.primitiveIdBase) * sizeof(int) * 3 atIndex:OSD_FVAR_PATCHPARAM_BUFFER_INDEX];
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.indexBase+(patch.primitiveIdBase*fvarPatch.desc.GetNumControlVertices())) * sizeof(unsigned) atIndex:OSD_FVAR_INDICES_BUFFER_INDEX];
[renderCommandEncoder setVertexBufferOffset:(fvarPatch.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];
@ -662,17 +675,14 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
int level = _refinementLevel;
_numVertexElements = 3;
#if USE_FACE_VARYING
_numFaceVaryingElements = _shape->HasUV() ? 2 : 0;
#else
_numFaceVaryingElements = 0;
#endif
_numVaryingElements = 0;
bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, _numVaryingElements > 0);
bits.set(OpenSubdiv::Osd::MeshFVarData, _numFaceVaryingElements > 0);
bits.set(OpenSubdiv::Osd::MeshFVarAdaptive, _doAdaptive);
_numFaceVaryingElements = (_shadingMode == kShadingFaceVarying && _shape->HasUV()) ? 2 : 0;
if (_numFaceVaryingElements > 0) {
bits.set(OpenSubdiv::Osd::MeshFVarData, _numFaceVaryingElements > 0);
bits.set(OpenSubdiv::Osd::MeshFVarAdaptive, _doAdaptive);
}
int numElements = _numVertexElements + _numVaryingElements;
@ -762,60 +772,61 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
Osd::MTLStencilTable mtlStencilTable = Osd::MTLStencilTable(stencilTable, &_context);
uint32_t fvarWidth = _numFaceVaryingElements;
uint32_t coarseFVarValuesCount = _shape->uvs.size() / fvarWidth;
uint32_t finalFVarValuesCount = stencilTable->GetNumStencils();
if (_numFaceVaryingElements > 0) {
uint32_t fvarWidth = _numFaceVaryingElements;
uint32_t coarseFVarValuesCount = _shape->uvs.size() / fvarWidth;
uint32_t finalFVarValuesCount = stencilTable->GetNumStencils();
#if FVAR_SINGLE_BUFFER
Osd::CPUMTLVertexBuffer *fvarDataBuffer = Osd::CPUMTLVertexBuffer::Create(fvarWidth, coarseFVarValuesCount + finalFVarValuesCount, &_context);
fvarDataBuffer->UpdateData(_shape->uvs.data(), 0, coarseFVarValuesCount, &_context);
Osd::CPUMTLVertexBuffer *fvarDataBuffer = Osd::CPUMTLVertexBuffer::Create(fvarWidth, coarseFVarValuesCount + finalFVarValuesCount, &_context);
fvarDataBuffer->UpdateData(_shape->uvs.data(), 0, coarseFVarValuesCount, &_context);
_faceVaryingDataBuffer = fvarDataBuffer->BindMTLBuffer(&_context);
_faceVaryingDataBuffer.label = @"OSD FVar data";
_faceVaryingDataBuffer = fvarDataBuffer->BindMTLBuffer(&_context);
_faceVaryingDataBuffer.label = @"OSD FVar data";
Osd::BufferDescriptor srcDesc(0, fvarWidth, fvarWidth);
Osd::BufferDescriptor dstDesc(coarseFVarValuesCount * fvarWidth, fvarWidth, fvarWidth);
Osd::BufferDescriptor srcDesc(0, fvarWidth, fvarWidth);
Osd::BufferDescriptor dstDesc(coarseFVarValuesCount * fvarWidth, fvarWidth, fvarWidth);
Osd::MTLComputeEvaluator::EvalStencils(fvarDataBuffer, srcDesc,
fvarDataBuffer, dstDesc,
&mtlStencilTable,
nullptr,
&_context);
Osd::MTLComputeEvaluator::EvalStencils(fvarDataBuffer, srcDesc,
fvarDataBuffer, dstDesc,
&mtlStencilTable,
nullptr,
&_context);
delete fvarDataBuffer;
#else
Osd::CPUMTLVertexBuffer *coarseFVarDataBuffer = Osd::CPUMTLVertexBuffer::Create(fvarWidth, coarseFVarValuesCount, &_context);
coarseFVarDataBuffer->UpdateData(_shape->uvs.data(), 0, coarseFVarValuesCount, &_context);
Osd::CPUMTLVertexBuffer *coarseFVarDataBuffer = Osd::CPUMTLVertexBuffer::Create(fvarWidth, coarseFVarValuesCount, &_context);
coarseFVarDataBuffer->UpdateData(_shape->uvs.data(), 0, coarseFVarValuesCount, &_context);
id<MTLBuffer> mtlCoarseFVarDataBuffer = coarseFVarDataBuffer->BindMTLBuffer(&_context);
mtlCoarseFVarDataBuffer.label = @"OSD FVar coarse data";
id<MTLBuffer> mtlCoarseFVarDataBuffer = coarseFVarDataBuffer->BindMTLBuffer(&_context);
mtlCoarseFVarDataBuffer.label = @"OSD FVar coarse data";
Osd::CPUMTLVertexBuffer *refinedFVarDataBuffer = Osd::CPUMTLVertexBuffer::Create(fvarWidth, finalFVarValuesCount, &_context);
_faceVaryingDataBuffer = refinedFVarDataBuffer->BindMTLBuffer(&_context);
_faceVaryingDataBuffer.label = @"OSD FVar data";
Osd::CPUMTLVertexBuffer *refinedFVarDataBuffer = Osd::CPUMTLVertexBuffer::Create(fvarWidth, finalFVarValuesCount, &_context);
_faceVaryingDataBuffer = refinedFVarDataBuffer->BindMTLBuffer(&_context);
_faceVaryingDataBuffer.label = @"OSD FVar data";
Osd::BufferDescriptor coarseBufferDescriptor(0, fvarWidth, fvarWidth);
Osd::BufferDescriptor refinedBufferDescriptor(0, fvarWidth, fvarWidth);
Osd::BufferDescriptor coarseBufferDescriptor(0, fvarWidth, fvarWidth);
Osd::BufferDescriptor refinedBufferDescriptor(0, fvarWidth, fvarWidth);
Osd::MTLComputeEvaluator::EvalStencils(coarseFVarDataBuffer, coarseBufferDescriptor,
refinedFVarDataBuffer, refinedBufferDescriptor,
&mtlStencilTable,
nullptr,
&_context);
Osd::MTLComputeEvaluator::EvalStencils(coarseFVarDataBuffer, coarseBufferDescriptor,
refinedFVarDataBuffer, refinedBufferDescriptor,
&mtlStencilTable,
nullptr,
&_context);
delete refinedFVarDataBuffer;
delete coarseFVarDataBuffer;
#endif
Osd::MTLPatchTable const *patchTable = _mesh->GetPatchTable();
Osd::MTLPatchTable const *patchTable = _mesh->GetPatchTable();
_faceVaryingIndicesBuffer = patchTable->GetFVarPatchIndexBuffer(0);
_faceVaryingIndicesBuffer.label = @"OSD FVar indices";
_faceVaryingIndicesBuffer = patchTable->GetFVarPatchIndexBuffer(0);
_faceVaryingIndicesBuffer.label = @"OSD FVar indices";
_faceVaryingPatchParamBuffer = patchTable->GetFVarPatchParamBuffer(0);
_faceVaryingPatchParamBuffer.label = @"OSD FVar patch params";
_faceVaryingPatchParamBuffer = patchTable->GetFVarPatchParamBuffer(0);
_faceVaryingPatchParamBuffer.label = @"OSD FVar patch params";
}
#if FVAR_SINGLE_BUFFER
delete fvarDataBuffer;
#else
delete refinedFVarDataBuffer;
delete coarseFVarDataBuffer;
#endif
delete stencilTable;
}
@ -939,11 +950,9 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
Osd::MTLPatchShaderSource shaderSource;
auto patchArrays = _mesh->GetPatchTable()->GetPatchArrays();
auto pFVarArray = _mesh->GetPatchTable()->GetFVarPatchArrays();
for(int i = 0; i < patchArrays.size(); ++i)
{
auto type = patchArrays[i].GetDescriptor().GetType();
auto fvarType = pFVarArray[i].GetDescriptor().GetType();
auto& threadsPerThreadgroup = _threadgroupSizes[type];
threadsPerThreadgroup = 32; //Initial guess of 32
int usefulControlPoints = patchArrays[i].GetDescriptor().GetNumControlVertices();
@ -999,7 +1008,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
)";
}
shaderBuilder << shaderSource.GetHullShaderSource(type, fvarType);
shaderBuilder << shaderSource.GetHullShaderSource(type);
if(_numFaceVaryingElements > 0)
shaderBuilder << shaderSource.GetPatchBasisShaderSource();
shaderBuilder << _osdShaderSource.UTF8String;
@ -1048,6 +1057,7 @@ using PerFrameBuffer = MTLRingBuffer<DataType, FRAME_LAG>;
DEFINE(OSD_FVAR_DATA_BUFFER_INDEX, OSD_FVAR_DATA_BUFFER_INDEX);
DEFINE(OSD_FVAR_INDICES_BUFFER_INDEX, OSD_FVAR_INDICES_BUFFER_INDEX);
DEFINE(OSD_FVAR_PATCHPARAM_BUFFER_INDEX, OSD_FVAR_PATCHPARAM_BUFFER_INDEX);
DEFINE(OSD_FVAR_PATCH_ARRAYS_BUFFER_INDEX, OSD_FVAR_PATCH_ARRAYS_BUFFER_INDEX);
compileOptions.preprocessorMacros = preprocessor;

View File

@ -25,9 +25,9 @@
#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"
#import <string>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
@ -40,14 +40,25 @@ class MTLPatchShaderSource {
static std::string GetPatchBasisShaderSource();
static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type);
static std::string GetHullShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
static std::string GetHullShaderSource(Far::PatchDescriptor::Type type);
static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType);
static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type);
/// These methods are deprecated. Clients should determine the
/// patch type of a face-varying patch by inspecting the
/// face-varying patch array descriptors.
/// \brief Deprecated
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

View File

@ -64,24 +64,43 @@ static std::string gregoryBasisShaderSource(
static std::string
GetPatchTypeDefine(Far::PatchDescriptor::Type type,
Far::PatchDescriptor::Type fvarType) {
Far::PatchDescriptor::Type fvarType =
Far::PatchDescriptor::NON_PATCH) {
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_BOUNDARY 1\n"; break;
case Far::PatchDescriptor::GREGORY_BASIS: ss << "#define OSD_PATCH_GREGORY_BASIS 1\n"; break;
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_BOUNDARY 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;
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();
}
@ -92,11 +111,16 @@ 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;
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 "";
@ -133,6 +157,16 @@ MTLPatchShaderSource::GetPatchBasisShaderSource() {
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type) {
std::stringstream ss;
ss << GetPatchTypeDefine(type);
ss << GetCommonShaderSource();
ss << GetPatchTypeSource(type);
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type,
@ -144,6 +178,16 @@ MTLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type,
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type) {
std::stringstream ss;
ss << GetPatchTypeDefine(type);
ss << GetCommonShaderSource();
ss << GetPatchTypeSource(type);
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type,
@ -155,6 +199,16 @@ MTLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type,
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetDomainShaderSource(Far::PatchDescriptor::Type type) {
std::stringstream ss;
ss << GetPatchTypeDefine(type);
ss << GetCommonShaderSource();
ss << GetPatchTypeSource(type);
return ss.str();
}
/*static*/
std::string
MTLPatchShaderSource::GetDomainShaderSource(Far::PatchDescriptor::Type type,