From 109a3f5383158d45694c36a4a29d4430921e1560 Mon Sep 17 00:00:00 2001 From: Takahito Tejima Date: Wed, 20 May 2015 14:36:57 -0700 Subject: [PATCH] osd layer: Add GLPatchTable and retire DrawContext In osd layer, we use GLPatchTable (D3D11PatchTable) as a device-specific representation of FarPatchTables instead of DrawContext. GLPatchTable may be used not only for drawing but also for GPU eval APIs (not yet supported though. We may add CudaPatchTable etc as needed). The legacy gregory patch drawing buffers are carved out to the separate class, named GLLegacyGregoryPatchTable. Also face-varying data are split into client side for now, until we add new and more robust face-varying drawing structure (scheduled at 3.1 release) Tentatively replicate PatchArray structure in GLPatchTables. It will be revised in the upcoming change. Shifting hard-coded SRV locations of legacy gregory buffers in HLSL shaders. --- examples/common/patchColors.h | 8 +- examples/dxPtexViewer/dxPtexViewer.cpp | 122 +++---- examples/dxPtexViewer/shader.hlsl | 3 +- examples/dxViewer/dxviewer.cpp | 112 ++++--- examples/glEvalLimit/glEvalLimit.cpp | 1 - examples/glFVarViewer/glFVarViewer.cpp | 133 ++++---- examples/glImaging/glImaging.cpp | 35 +- examples/glPaintTest/glPaintTest.cpp | 78 ++--- examples/glPtexViewer/glPtexViewer.cpp | 79 ++--- examples/glViewer/glViewer.cpp | 160 ++++++--- opensubdiv/osd/CMakeLists.txt | 14 +- opensubdiv/osd/d3d11DrawContext.cpp | 303 ------------------ opensubdiv/osd/d3d11DrawContext.h | 167 ---------- .../osd/d3d11LegacyGregoryPatchTable.cpp | 165 ++++++++++ opensubdiv/osd/d3d11LegacyGregoryPatchTable.h | 102 ++++++ opensubdiv/osd/d3d11Mesh.h | 5 +- opensubdiv/osd/d3d11PatchTable.cpp | 182 +++++++++++ opensubdiv/osd/d3d11PatchTable.h | 125 ++++++++ opensubdiv/osd/drawContext.cpp | 133 -------- opensubdiv/osd/drawContext.h | 197 ------------ opensubdiv/osd/glDrawContext.cpp | 232 -------------- opensubdiv/osd/glDrawContext.h | 151 --------- opensubdiv/osd/glLegacyGregoryPatchTable.cpp | 106 ++++++ opensubdiv/osd/glLegacyGregoryPatchTable.h | 86 +++++ opensubdiv/osd/glMesh.h | 5 +- opensubdiv/osd/glPatchTable.cpp | 141 ++++++++ opensubdiv/osd/glPatchTable.h | 112 +++++++ opensubdiv/osd/hlslPatchCommon.hlsl | 4 +- opensubdiv/osd/hlslPatchGregory.hlsl | 6 +- opensubdiv/osd/mesh.h | 72 ++--- 30 files changed, 1431 insertions(+), 1608 deletions(-) delete mode 100644 opensubdiv/osd/d3d11DrawContext.cpp delete mode 100644 opensubdiv/osd/d3d11DrawContext.h create mode 100644 opensubdiv/osd/d3d11LegacyGregoryPatchTable.cpp create mode 100644 opensubdiv/osd/d3d11LegacyGregoryPatchTable.h create mode 100644 opensubdiv/osd/d3d11PatchTable.cpp create mode 100644 opensubdiv/osd/d3d11PatchTable.h delete mode 100644 opensubdiv/osd/drawContext.cpp delete mode 100644 opensubdiv/osd/drawContext.h delete mode 100644 opensubdiv/osd/glDrawContext.cpp delete mode 100644 opensubdiv/osd/glDrawContext.h create mode 100644 opensubdiv/osd/glLegacyGregoryPatchTable.cpp create mode 100644 opensubdiv/osd/glLegacyGregoryPatchTable.h create mode 100644 opensubdiv/osd/glPatchTable.cpp create mode 100644 opensubdiv/osd/glPatchTable.h diff --git a/examples/common/patchColors.h b/examples/common/patchColors.h index 7a16c3cd..c9a07edb 100644 --- a/examples/common/patchColors.h +++ b/examples/common/patchColors.h @@ -22,10 +22,8 @@ // language governing permissions and limitations under the Apache License. // -#ifndef COMMON_PATCH_COLORS_H -#define COMMON_PATCH_COLORS_H - -#include +#ifndef OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H +#define OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H #include @@ -33,4 +31,4 @@ float const * getAdaptivePatchColor(OpenSubdiv::Far::PatchDescriptor const & desc); -#endif /* COMMON_PATCH_COLORS_H */ +#endif /* OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H */ diff --git a/examples/dxPtexViewer/dxPtexViewer.cpp b/examples/dxPtexViewer/dxPtexViewer.cpp index a5a86026..dec13cc4 100755 --- a/examples/dxPtexViewer/dxPtexViewer.cpp +++ b/examples/dxPtexViewer/dxPtexViewer.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -467,10 +466,6 @@ public: ss << "#define OSD_ENABLE_PATCH_CULL\n"; } - // for legacy gregory - ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n"; - ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n"; - // add ptex functions ss << D3D11PtexMipmapTexture::GetShaderSource(); @@ -741,7 +736,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -753,7 +748,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -765,7 +760,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -778,7 +773,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -792,7 +787,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -804,7 +799,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -821,21 +816,10 @@ createOsdMesh(int level, int kernel) { //------------------------------------------------------------------------------ static void -bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) { +bindProgram(Effect effect, OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch) { EffectDesc effectDesc(patch.GetDescriptor(), effect); - // only legacy gregory needs maxValence and numElements - int maxValence = g_mesh->GetDrawContext()->GetMaxValence(); - int numElements = 6; - - typedef OpenSubdiv::Far::PatchDescriptor Descriptor; - if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or - patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) { - effectDesc.maxValence = maxValence; - effectDesc.numElements = numElements; - } - D3D11DrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc); assert(g_pInputLayout); @@ -885,7 +869,6 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc __declspec(align(16)) struct Tessellation { float TessLevel; - int GregoryQuadOffsetBase; int PrimitiveIdBase; }; @@ -906,8 +889,7 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc Tessellation * pData = ( Tessellation* )MappedResource.pData; pData->TessLevel = static_cast(1 << g_tessLevel); - pData->GregoryQuadOffsetBase = patch.GetQuadOffsetIndex(); - pData->PrimitiveIdBase = patch.GetPatchIndex(); + pData->PrimitiveIdBase = patch.GetPrimitiveIdBase(); g_pd3dDeviceContext->Unmap( g_pcbTessellation, 0 ); } @@ -959,24 +941,12 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc g_pd3dDeviceContext->PSSetConstantBuffers(2, 1, &g_pcbLighting); g_pd3dDeviceContext->PSSetConstantBuffers(3, 1, &g_pcbConfig); - if (g_mesh->GetDrawContext()->vertexBufferSRV) { - g_pd3dDeviceContext->VSSetShaderResources(0, 1, &g_mesh->GetDrawContext()->vertexBufferSRV); - } - if (g_mesh->GetDrawContext()->vertexValenceBufferSRV) { - g_pd3dDeviceContext->VSSetShaderResources(1, 1, &g_mesh->GetDrawContext()->vertexValenceBufferSRV); - } - if (g_mesh->GetDrawContext()->quadOffsetBufferSRV) { - g_pd3dDeviceContext->HSSetShaderResources(2, 1, &g_mesh->GetDrawContext()->quadOffsetBufferSRV); - } - if (g_mesh->GetDrawContext()->patchParamBufferSRV) { - g_pd3dDeviceContext->HSSetShaderResources( - 3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV); - g_pd3dDeviceContext->DSSetShaderResources( - 3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV); - g_pd3dDeviceContext->GSSetShaderResources( - 3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV); - g_pd3dDeviceContext->PSSetShaderResources( - 3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV); + ID3D11ShaderResourceView *srv = g_mesh->GetPatchTable()->GetPatchParamSRV(); + if (srv) { + g_pd3dDeviceContext->HSSetShaderResources(0, 1, &srv); + g_pd3dDeviceContext->DSSetShaderResources(0, 1, &srv); + g_pd3dDeviceContext->GSSetShaderResources(0, 1, &srv); + g_pd3dDeviceContext->PSSetShaderResources(0, 1, &srv); } g_pd3dDeviceContext->PSSetShaderResources(4, 1, g_osdPTexImage->GetTexelsSRV()); @@ -1011,15 +981,16 @@ drawModel() { UINT hOffsets = 0; g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets); - OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = - g_mesh->GetDrawContext()->GetPatchArrays(); + OpenSubdiv::Osd::D3D11PatchTable::PatchArrayVector const & patches = + g_mesh->GetPatchTable()->GetPatchArrays(); - g_pd3dDeviceContext->IASetIndexBuffer(g_mesh->GetDrawContext()->patchIndexBuffer, - DXGI_FORMAT_R32_UINT, 0); + g_pd3dDeviceContext->IASetIndexBuffer( + g_mesh->GetPatchTable()->GetPatchIndexBuffer(), + DXGI_FORMAT_R32_UINT, 0); // patch drawing for (int i = 0; i < (int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch = patches[i]; OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); @@ -1054,7 +1025,7 @@ drawModel() { break; } break; - }; + } Effect effect; effect.value = 0; @@ -1076,8 +1047,10 @@ drawModel() { g_pd3dDeviceContext->IASetPrimitiveTopology(topology); - g_pd3dDeviceContext->DrawIndexed(patch.GetNumIndices(), - patch.GetVertIndex(), 0); + g_pd3dDeviceContext->DrawIndexed( + patch.GetNumPatches() * desc.GetNumControlVertices(), + patch.GetIndexBase(), 0); + } } @@ -1470,13 +1443,13 @@ initD3D11(HWND hWnd) { D3D_FEATURE_LEVEL hFeatureLevel = D3D_FEATURE_LEVEL_11_0; for(UINT driverTypeIndex=0; driverTypeIndex < numDriverTypes; driverTypeIndex++){ hDriverType = driverTypes[driverTypeIndex]; - unsigned int deviceFlags = 0; + unsigned int deviceFlags = 0; #ifndef NDEBUG // XXX: this is problematic in some environments. // deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif hr = D3D11CreateDeviceAndSwapChain(NULL, - hDriverType, NULL, deviceFlags, NULL, 0, + hDriverType, NULL, deviceFlags, NULL, 0, D3D11_SDK_VERSION, &hDXGISwapChainDesc, &g_pSwapChain, &g_pd3dDevice, &hFeatureLevel, &g_pd3dDeviceContext); @@ -1491,30 +1464,29 @@ initD3D11(HWND hWnd) { } #ifndef NDEBUG - // set break points on directx errors - ID3D11Debug *d3dDebug = nullptr; - hr = g_pd3dDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug); - if (SUCCEEDED(hr)) { + // set break points on directx errors + ID3D11Debug *d3dDebug = nullptr; + hr = g_pd3dDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug); + if (SUCCEEDED(hr)) { + ID3D11InfoQueue *d3dInfoQueue = nullptr; + hr = d3dDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue); + if (SUCCEEDED(hr)) { - ID3D11InfoQueue *d3dInfoQueue = nullptr; - hr = d3dDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue); - if (SUCCEEDED(hr)) { + d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); + d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); + d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true); - d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); - d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); - d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true); - - D3D11_MESSAGE_ID denied[] = { D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS }; - D3D11_INFO_QUEUE_FILTER filter; - memset(&filter, 0, sizeof(filter)); - filter.DenyList.NumIDs = _countof(denied); - filter.DenyList.pIDList = denied; - d3dInfoQueue->AddStorageFilterEntries(&filter); + D3D11_MESSAGE_ID denied[] = { D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS }; + D3D11_INFO_QUEUE_FILTER filter; + memset(&filter, 0, sizeof(filter)); + filter.DenyList.NumIDs = _countof(denied); + filter.DenyList.pIDList = denied; + d3dInfoQueue->AddStorageFilterEntries(&filter); - d3dInfoQueue->Release(); - } - d3dDebug->Release(); - } + d3dInfoQueue->Release(); + } + d3dDebug->Release(); + } #endif // create rasterizer diff --git a/examples/dxPtexViewer/shader.hlsl b/examples/dxPtexViewer/shader.hlsl index 7774a92b..18d3a73d 100644 --- a/examples/dxPtexViewer/shader.hlsl +++ b/examples/dxPtexViewer/shader.hlsl @@ -34,7 +34,6 @@ cbuffer Transform : register( b0 ) { cbuffer Tessellation : register( b1 ) { float TessLevel; - int GregoryQuadOffsetBase; int PrimitiveIdBase; }; @@ -61,7 +60,7 @@ float OsdTessLevel() } int OsdGregoryQuadOffsetBase() { - return GregoryQuadOffsetBase; + return 0; } int OsdPrimitiveIdBase() { diff --git a/examples/dxViewer/dxviewer.cpp b/examples/dxViewer/dxviewer.cpp index d4c583ab..e5b643c8 100644 --- a/examples/dxViewer/dxviewer.cpp +++ b/examples/dxViewer/dxviewer.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -57,7 +56,9 @@ #include #include -OpenSubdiv::Osd::D3D11MeshInterface *g_mesh; +#include +OpenSubdiv::Osd::D3D11MeshInterface *g_mesh = NULL; +OpenSubdiv::Osd::D3D11LegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL; #include #include "../common/stopwatch.h" @@ -321,7 +322,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -333,7 +334,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -345,7 +346,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -358,7 +359,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -372,7 +373,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -384,7 +385,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -396,6 +397,15 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= printf("Unsupported kernel %s\n", getKernelName(kernel)); } + // legacy gregory + delete g_legacyGregoryPatchTable; + g_legacyGregoryPatchTable = NULL; + if (g_endCap == kEndCapLegacyGregory) { + g_legacyGregoryPatchTable = + Osd::D3D11LegacyGregoryPatchTable::Create( + g_mesh->GetFarPatchTables(), g_pd3dDeviceContext); + } + // compute model bounding float min[3] = { FLT_MAX, FLT_MAX, FLT_MAX}; float max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; @@ -618,16 +628,16 @@ ShaderCache g_shaderCache; //------------------------------------------------------------------------------ static void -bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) { +bindProgram(Effect effect, OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch) { EffectDesc effectDesc(patch.GetDescriptor(), effect); + typedef OpenSubdiv::Far::PatchDescriptor Descriptor; // only legacy gregory needs maxValence and numElements // neither legacy gregory nor gregory basis need single crease - typedef OpenSubdiv::Far::PatchDescriptor Descriptor; if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) { - int maxValence = g_mesh->GetDrawContext()->GetMaxValence(); + int maxValence = g_mesh->GetMaxValence(); int numElements = 6; effectDesc.maxValence = maxValence; effectDesc.numElements = numElements; @@ -706,8 +716,9 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc Tessellation * pData = ( Tessellation* )MappedResource.pData; pData->TessLevel = static_cast(1 << g_tessLevel); - pData->GregoryQuadOffsetBase = patch.GetQuadOffsetIndex(); - pData->PrimitiveIdBase = patch.GetPatchIndex(); + pData->GregoryQuadOffsetBase = g_legacyGregoryPatchTable ? + g_legacyGregoryPatchTable->GetQuadOffsetsBase(patch.GetDescriptor().GetType()) : 0; + pData->PrimitiveIdBase = patch.GetPrimitiveIdBase(); g_pd3dDeviceContext->Unmap( g_pcbTessellation, 0 ); } @@ -761,22 +772,23 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc g_pd3dDeviceContext->PSSetConstantBuffers(2, 1, &g_pcbLighting); g_pd3dDeviceContext->PSSetConstantBuffers(3, 1, &g_pcbMaterial); - if (g_mesh->GetDrawContext()->vertexBufferSRV) { - g_pd3dDeviceContext->VSSetShaderResources(0, 1, &g_mesh->GetDrawContext()->vertexBufferSRV); + ID3D11ShaderResourceView *srv = g_mesh->GetPatchTable()->GetPatchParamSRV(); + if (srv) { + g_pd3dDeviceContext->HSSetShaderResources(0, 1, &srv); // t0 + g_pd3dDeviceContext->DSSetShaderResources(0, 1, &srv); + g_pd3dDeviceContext->PSSetShaderResources(0, 1, &srv); } - if (g_mesh->GetDrawContext()->vertexValenceBufferSRV) { - g_pd3dDeviceContext->VSSetShaderResources(1, 1, &g_mesh->GetDrawContext()->vertexValenceBufferSRV); - } - if (g_mesh->GetDrawContext()->quadOffsetBufferSRV) { - g_pd3dDeviceContext->HSSetShaderResources(2, 1, &g_mesh->GetDrawContext()->quadOffsetBufferSRV); - } - if (g_mesh->GetDrawContext()->patchParamBufferSRV) { - g_pd3dDeviceContext->HSSetShaderResources( - 3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV); - g_pd3dDeviceContext->DSSetShaderResources( - 3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV); - g_pd3dDeviceContext->PSSetShaderResources( - 3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV); + + if (g_legacyGregoryPatchTable) { + ID3D11ShaderResourceView *vertexSRV = + g_legacyGregoryPatchTable->GetVertexSRV(); + ID3D11ShaderResourceView *vertexValenceSRV = + g_legacyGregoryPatchTable->GetVertexValenceSRV(); + ID3D11ShaderResourceView *quadOffsetsSRV = + g_legacyGregoryPatchTable->GetQuadOffsetsSRV(); + g_pd3dDeviceContext->VSSetShaderResources(2, 1, &vertexSRV); // t2 + g_pd3dDeviceContext->VSSetShaderResources(3, 1, &vertexValenceSRV);// t3 + g_pd3dDeviceContext->HSSetShaderResources(4, 1, &quadOffsetsSRV); // t4 } } @@ -796,32 +808,23 @@ display() { ID3D11Buffer *buffer = g_mesh->BindVertexBuffer(); assert(buffer); + // vertex texture update for legacy gregory drawing + if (g_legacyGregoryPatchTable) { + g_legacyGregoryPatchTable->UpdateVertexBuffer(buffer, + g_mesh->GetNumVertices(), + 6, + g_pd3dDeviceContext); + } + UINT hStrides = 6*sizeof(float); UINT hOffsets = 0; g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets); - OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->GetPatchArrays(); + OpenSubdiv::Osd::D3D11PatchTable::PatchArrayVector const & patches = + g_mesh->GetPatchTable()->GetPatchArrays(); - g_pd3dDeviceContext->IASetIndexBuffer(g_mesh->GetDrawContext()->patchIndexBuffer, DXGI_FORMAT_R32_UINT, 0); - - // cv drawing -#if 0 - - if (g_drawPatchCVs) { - - bindProgram(kPoint, OpenSubdiv::Osd::DrawContext::PatchArray()); - - g_pd3dDeviceContext->IASetPrimitiveTopology( - D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - - for (int i=0; i<(int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; - - g_pd3dDeviceContext->DrawIndexed(patch.GetNumIndices(), - patch.GetVertIndex(), 0); - } - } -#endif + g_pd3dDeviceContext->IASetIndexBuffer( + g_mesh->GetPatchTable()->GetPatchIndexBuffer(), DXGI_FORMAT_R32_UINT, 0); // patch drawing int patchCount[12]; // [Type] (see far/patchTables.h) @@ -829,7 +832,7 @@ display() { int numDrawCalls = 0; for (int i=0; i<(int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch = patches[i]; OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); @@ -868,13 +871,15 @@ display() { break; } break; - }; + } bindProgram(GetEffect(), patch); g_pd3dDeviceContext->IASetPrimitiveTopology(topology); - g_pd3dDeviceContext->DrawIndexed(patch.GetNumIndices(), patch.GetVertIndex(), 0); + g_pd3dDeviceContext->DrawIndexed( + patch.GetNumPatches() * desc.GetNumControlVertices(), + patch.GetIndexBase(), 0); } g_fpsTimer.Stop(); @@ -1254,7 +1259,8 @@ initD3D11(HWND hWnd) { D3D11_RASTERIZER_DESC rasterDesc; ZeroMemory(&rasterDesc, sizeof(rasterDesc)); rasterDesc.AntialiasedLineEnable = false; - rasterDesc.CullMode = D3D11_CULL_NONE; // XXX + //rasterDesc.CullMode = D3D11_CULL_NONE; // XXX + rasterDesc.CullMode = D3D11_CULL_BACK; // XXX rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; diff --git a/examples/glEvalLimit/glEvalLimit.cpp b/examples/glEvalLimit/glEvalLimit.cpp index 8c21f6d0..0e9beb31 100755 --- a/examples/glEvalLimit/glEvalLimit.cpp +++ b/examples/glEvalLimit/glEvalLimit.cpp @@ -45,7 +45,6 @@ GLFWmonitor* g_primary=0; #include #include #include -#include #include #include diff --git a/examples/glFVarViewer/glFVarViewer.cpp b/examples/glFVarViewer/glFVarViewer.cpp index 0ea0dcd9..433f5386 100644 --- a/examples/glFVarViewer/glFVarViewer.cpp +++ b/examples/glFVarViewer/glFVarViewer.cpp @@ -42,7 +42,6 @@ GLFWwindow* g_window = 0; GLFWmonitor* g_primary = 0; -#include #include #include @@ -155,6 +154,51 @@ struct Program { GLuint attrColor; } g_defaultProgram; +struct FVarData +{ + FVarData() : + textureBuffer(0) { + } + ~FVarData() { + Release(); + } + void Release() { + if (textureBuffer) + glDeleteTextures(1, &textureBuffer); + textureBuffer = 0; + } + void Create(OpenSubdiv::Far::PatchTables const *patchTables, + int fvarWidth, std::vector const & fvarSrcData) { + Release(); + OpenSubdiv::Far::ConstIndexArray indices = + patchTables->GetFVarPatchesValues(0); + + // expand fvardata to per-patch array + std::vector data; + data.reserve(indices.size() * fvarWidth); + + for (int fvert = 0; fvert < (int)indices.size(); ++fvert) { + int index = indices[fvert] * fvarWidth; + for (int i = 0; i < fvarWidth; ++i) { + data.push_back(fvarSrcData[index++]); + } + } + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(float), + &data[0], GL_STATIC_DRAW); + + glBindTexture(GL_TEXTURE_BUFFER, textureBuffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + glBindTexture(GL_ARRAY_BUFFER, 0); + + glDeleteBuffers(1, &buffer); + } + GLuint textureBuffer; +} g_fvarData; + //------------------------------------------------------------------------------ static GLuint compileShader(GLenum shaderType, const char *source) { @@ -362,7 +406,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark) g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -372,7 +416,9 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark) InterpolateFVarData(*refiner, *shape, fvarData); - g_mesh->SetFVarDataChannel(shape->GetFVarWidth(), fvarData); + // set fvardata to texture buffer + g_fvarData.Create(g_mesh->GetFarPatchTables(), + shape->GetFVarWidth(), fvarData); delete shape; @@ -397,7 +443,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark) // -------- VAO glBindVertexArray(g_vao); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer()); glBindBuffer(GL_ARRAY_BUFFER, g_mesh->BindVertexBuffer()); glEnableVertexAttribArray(0); @@ -672,21 +718,13 @@ public: // assign texture locations GLint loc; glUseProgram(program); - if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) { + if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) { glUniform1i(loc, 0); // GL_TEXTURE0 } - if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) { + if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) { glUniform1i(loc, 1); // GL_TEXTURE1 } - if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) { - glUniform1i(loc, 2); // GL_TEXTURE2 - } - if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) { - glUniform1i(loc, 3); // GL_TEXTURE3 - } - if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) { - glUniform1i(loc, 4); // GL_TEXTURE4 - } + return config; } @@ -733,50 +771,23 @@ updateUniformBlocks() { static void bindTextures() { - if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) { + if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) { - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetFvarDataTextureBuffer()) { - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetFvarDataTextureBuffer()); + g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()); } + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_BUFFER, g_fvarData.textureBuffer); glActiveTexture(GL_TEXTURE0); } static GLenum -bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) { +bindProgram(Effect effect, OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) { EffectDesc effectDesc(patch.GetDescriptor(), effect); typedef OpenSubdiv::Far::PatchDescriptor Descriptor; - if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or - patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) { - // only legacy gregory needs maxValence and numElements - int maxValence = g_mesh->GetDrawContext()->GetMaxValence(); - int numElements = 3; - - effectDesc.maxValence = maxValence; - effectDesc.numElements = numElements; - } // lookup shader cache (compile the shader if needed) GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc); @@ -787,14 +798,10 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc glUseProgram(program); // bind standalone uniforms - GLint uniformGregoryQuadOffsetBase = - glGetUniformLocation(program, "GregoryQuadOffsetBase"); GLint uniformPrimitiveIdBase = glGetUniformLocation(program, "PrimitiveIdBase"); - if (uniformGregoryQuadOffsetBase >= 0) - glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex()); if (uniformPrimitiveIdBase >=0) - glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex()); + glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase()); // return primtype GLenum primType; @@ -858,8 +865,8 @@ display() { glBindVertexArray(g_vao); - OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = - g_mesh->GetDrawContext()->GetPatchArrays(); + OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches = + g_mesh->GetPatchTable()->GetPatchArrays(); if (g_displayStyle == kWire) glDisable(GL_CULL_FACE); @@ -869,12 +876,15 @@ display() { // patch drawing for (int i = 0; i < (int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i]; GLenum primType = bindProgram(GetEffect(), patch); - glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT, - (void *)(patch.GetVertIndex() * sizeof(unsigned int))); + glDrawElements( + primType, + patch.GetNumPatches()*patch.GetDescriptor().GetNumControlVertices(), + GL_UNSIGNED_INT, + (void *)(patch.GetIndexBase() * sizeof(unsigned int))); } if (g_displayStyle == kWire) glEnable(GL_CULL_FACE); @@ -896,12 +906,15 @@ display() { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); for (int i = 0; i < (int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i]; GLenum primType = bindProgram(GetEffect(/*uvDraw=*/ true), patch); - glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT, - (void *)(patch.GetVertIndex() * sizeof(unsigned int))); + glDrawElements( + primType, + patch.GetNumPatches()*patch.GetDescriptor().GetNumControlVertices(), + GL_UNSIGNED_INT, + (void *)(patch.GetIndexBase() * sizeof(unsigned int))); } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); diff --git a/examples/glImaging/glImaging.cpp b/examples/glImaging/glImaging.cpp index 805eb378..f145db90 100755 --- a/examples/glImaging/glImaging.cpp +++ b/examples/glImaging/glImaging.cpp @@ -82,7 +82,6 @@ #include #endif -#include #include #include @@ -235,7 +234,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -245,7 +244,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -256,7 +255,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -267,7 +266,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( refiner, numVertexElements, @@ -281,7 +280,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -292,7 +291,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -303,7 +302,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -405,7 +404,7 @@ void runTest(ShapeDesc const &shapeDesc, std::string const &kernel, glBindVertexArray(vao); // bind vertex - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetDrawContext()->GetPatchIndexBuffer()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetPatchTable()->GetPatchIndexBuffer()); glBindBuffer(GL_ARRAY_BUFFER, mesh->BindVertexBuffer()); glEnableVertexAttribArray(0); @@ -417,17 +416,17 @@ void runTest(ShapeDesc const &shapeDesc, std::string const &kernel, (const void*)(sizeof(GLfloat)*3)); // bind patchparam - if (mesh->GetDrawContext()->GetPatchParamTextureBuffer()) { + if (mesh->GetPatchTable()->GetPatchParamTextureBuffer()) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, - mesh->GetDrawContext()->GetPatchParamTextureBuffer()); + mesh->GetPatchTable()->GetPatchParamTextureBuffer()); } - Osd::DrawContext::PatchArrayVector const & patches = - mesh->GetDrawContext()->GetPatchArrays(); + Osd::GLPatchTable::PatchArrayVector const & patches = + mesh->GetPatchTable()->GetPatchArrays(); for (int i=0; i<(int)patches.size(); ++i) { - Osd::DrawContext::PatchArray const & patch = patches[i]; + Osd::GLPatchTable::PatchArray const & patch = patches[i]; Far::PatchDescriptor desc = patch.GetDescriptor(); Far::PatchDescriptor::Type patchType = desc.GetType(); @@ -457,13 +456,15 @@ void runTest(ShapeDesc const &shapeDesc, std::string const &kernel, glProgramUniform4f(program, diffuseColor, color[0], color[1], color[2], color[3]); glProgramUniform1i(program, uniformPrimitiveIdBase, - patch.GetPatchIndex()); + patch.GetPrimitiveIdBase()); } else { glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1); } - glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT, - (void *)(patch.GetVertIndex() * sizeof(unsigned int))); + glDrawElements(primType, + patch.GetNumPatches() * desc.GetNumControlVertices(), + GL_UNSIGNED_INT, + (void *)(patch.GetIndexBase() * sizeof(unsigned int))); } glDisableVertexAttribArray(0); diff --git a/examples/glPaintTest/glPaintTest.cpp b/examples/glPaintTest/glPaintTest.cpp index 65761066..57f41a19 100644 --- a/examples/glPaintTest/glPaintTest.cpp +++ b/examples/glPaintTest/glPaintTest.cpp @@ -42,7 +42,6 @@ GLFWwindow* g_window=0; GLFWmonitor* g_primary=0; -#include #include #include @@ -241,7 +240,7 @@ createOsdMesh() { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, 3, 0, g_level, bits); // compute model bounding @@ -265,7 +264,7 @@ createOsdMesh() { // -------- VAO glBindVertexArray(g_vao); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer()); glBindBuffer(GL_ARRAY_BUFFER, g_mesh->BindVertexBuffer()); glEnableVertexAttribArray(0); @@ -462,17 +461,8 @@ public: GLint loc; glUseProgram(program); - if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) { - glUniform1i(loc, 0); // GL_TEXTURE0 - } - if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) { - glUniform1i(loc, 1); // GL_TEXTURE1 - } - if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) { - glUniform1i(loc, 2); // GL_TEXTURE2 - } if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) { - glUniform1i(loc, 3); // GL_TEXTURE3 + glUniform1i(loc, 0); // GL_TEXTURE0 } if (effectDesc.effect.paint) { @@ -586,25 +576,11 @@ static void bindTextures(Effect effect) { glActiveTexture(GL_TEXTURE0); } else { - if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) { + if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) { glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) { - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()); + glBindTexture( + GL_TEXTURE_BUFFER, + g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()); } // color ptex @@ -621,19 +597,10 @@ static void bindTextures(Effect effect) { } static GLuint -bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) { +bindProgram(Effect effect, OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) { EffectDesc effectDesc(patch.GetDescriptor(), effect); - // only legacy gregory needs maxValence and numElements - typedef OpenSubdiv::Far::PatchDescriptor Descriptor; - if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or - patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) { - int maxValence = g_mesh->GetDrawContext()->GetMaxValence(); - effectDesc.maxValence = maxValence; - effectDesc.numElements = 3; - } - // lookup shader cache (compile the shader if needed) GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc); if (!config) return 0; @@ -646,15 +613,10 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc if (uniformImageSize >= 0) glUniform1i(uniformImageSize, g_pageSize); - GLint uniformGregoryQuadOffsetBase = - glGetUniformLocation(program, "GregoryQuadOffsetBase"); - if (uniformGregoryQuadOffsetBase >= 0) - glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex()); - GLint uniformPrimitiveIdBase = glGetUniformLocation(program, "PrimitiveIdBase"); if (uniformPrimitiveIdBase >= 0) - glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex()); + glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase()); return program; @@ -708,12 +670,12 @@ display() { glBindVertexArray(g_vao); - OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = - g_mesh->GetDrawContext()->GetPatchArrays(); + OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches = + g_mesh->GetPatchTable()->GetPatchArrays(); // patch drawing for (int i=0; i<(int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i]; OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); GLenum primType = GL_PATCHES; @@ -724,8 +686,9 @@ display() { glProgramUniform4f(program, diffuseColor, 1, 1, 1, 1); glDrawElements(primType, - patch.GetNumIndices(), GL_UNSIGNED_INT, - (void *)(patch.GetVertIndex() * sizeof(unsigned int))); + patch.GetNumPatches() * desc.GetNumControlVertices(), + GL_UNSIGNED_INT, + (void *)(patch.GetIndexBase() * sizeof(unsigned int))); } glBindVertexArray(0); @@ -844,13 +807,13 @@ drawStroke(int x, int y) { effect.paint = 1; bindTextures(effect); - OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = - g_mesh->GetDrawContext()->GetPatchArrays(); + OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches = + g_mesh->GetPatchTable()->GetPatchArrays(); // patch drawing for (int i=0; i<(int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i]; OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); GLenum primType = GL_PATCHES; @@ -859,8 +822,9 @@ drawStroke(int x, int y) { bindProgram(effect, patch); glDrawElements(primType, - patch.GetNumIndices(), GL_UNSIGNED_INT, - (void *)(patch.GetVertIndex() * sizeof(unsigned int))); + patch.GetNumPatches() * desc.GetNumControlVertices(), + GL_UNSIGNED_INT, + (void *)(patch.GetIndexBase() * sizeof(unsigned int))); } glBindVertexArray(0); diff --git a/examples/glPtexViewer/glPtexViewer.cpp b/examples/glPtexViewer/glPtexViewer.cpp index b8f22071..1e572dbc 100644 --- a/examples/glPtexViewer/glPtexViewer.cpp +++ b/examples/glPtexViewer/glPtexViewer.cpp @@ -49,8 +49,6 @@ GLFWmonitor* g_primary = 0; #include #include #include - -#include #include #include @@ -783,17 +781,8 @@ public: GLint loc; // patch textures glUseProgram(program); - if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) { - glUniform1i(loc, 0); // GL_TEXTURE0 - } - if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) { - glUniform1i(loc, 1); // GL_TEXTURE1 - } - if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) { - glUniform1i(loc, 2); // GL_TEXTURE2 - } if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) { - glUniform1i(loc, 3); // GL_TEXTURE3 + glUniform1i(loc, 0); // GL_TEXTURE0 } // environment textures @@ -948,7 +937,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -958,7 +947,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -969,7 +958,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -981,7 +970,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( refiner, numVertexElements, @@ -995,7 +984,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -1007,7 +996,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -1020,7 +1009,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -1051,7 +1040,7 @@ createOsdMesh(int level, int kernel) { glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (float*)12); } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer()); // ------ Cage VAO glBindVertexArray(g_cageEdgeVAO); @@ -1201,27 +1190,10 @@ updateConstantUniformBlock() { static void bindTextures() { -#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0) - if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) { + if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()); - } -#endif - if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) { - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()); + g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()); } // other textures @@ -1273,18 +1245,9 @@ bindTextures() { //------------------------------------------------------------------------------ static GLenum bindProgram(Effect effect, - OpenSubdiv::Osd::DrawContext::PatchArray const & patch) { + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) { EffectDesc effectDesc(patch.GetDescriptor(), effect); - // only legacy gregory needs maxValence and numElements - typedef OpenSubdiv::Far::PatchDescriptor Descriptor; - if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or - patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) { - int maxValence = g_mesh->GetDrawContext()->GetMaxValence(); - effectDesc.maxValence = maxValence; - effectDesc.numElements = 3; - } - GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc); if (!config) return 0; @@ -1293,15 +1256,10 @@ bindProgram(Effect effect, glUseProgram(program); // bind standalone uniforms - GLint uniformGregoryQuadOffsetBase = - glGetUniformLocation(program, "GregoryQuadOffsetBase"); GLint uniformPrimitiveIdBase = glGetUniformLocation(program, "PrimitiveIdBase"); - - if (uniformGregoryQuadOffsetBase >= 0) - glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex()); if (uniformPrimitiveIdBase >= 0) - glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex()); + glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase()); GLenum primType; switch(effectDesc.desc.GetType()) { @@ -1334,10 +1292,10 @@ drawModel() { glBindVertexArray(g_vao); // patch drawing - OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = - g_mesh->GetDrawContext()->GetPatchArrays(); + OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches = + g_mesh->GetPatchTable()->GetPatchArrays(); for (int i = 0; i < (int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i]; Effect effect; effect.value = 0; @@ -1357,8 +1315,9 @@ drawModel() { GLenum primType = bindProgram(effect, patch); glDrawElements(primType, - patch.GetNumIndices(), GL_UNSIGNED_INT, - (void *)(patch.GetVertIndex() * sizeof(unsigned int))); + patch.GetNumPatches() * patch.GetDescriptor().GetNumControlVertices(), + GL_UNSIGNED_INT, + (void *)(patch.GetIndexBase() * sizeof(unsigned int))); } glBindVertexArray(0); diff --git a/examples/glViewer/glViewer.cpp b/examples/glViewer/glViewer.cpp index 19c7c318..7e1243ec 100644 --- a/examples/glViewer/glViewer.cpp +++ b/examples/glViewer/glViewer.cpp @@ -43,7 +43,6 @@ GLFWwindow* g_window=0; GLFWmonitor* g_primary=0; #include -#include #include #include @@ -83,7 +82,9 @@ GLFWmonitor* g_primary=0; #endif #include -OpenSubdiv::Osd::GLMeshInterface *g_mesh; +#include +OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL; +OpenSubdiv::Osd::GLLegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL; #include #include "../common/stopwatch.h" @@ -232,6 +233,55 @@ struct Program GLuint attrColor; } g_defaultProgram; +// XXX: +// this struct meant to be used as a stopgap entity until we fully implement +// face-varying stuffs into patch table. +// +struct FVarData +{ + FVarData() : + textureBuffer(0) { + } + ~FVarData() { + Release(); + } + void Release() { + if (textureBuffer) + glDeleteTextures(1, &textureBuffer); + textureBuffer = 0; + } + void Create(OpenSubdiv::Far::PatchTables const *patchTables, + int fvarWidth, std::vector const & fvarSrcData) { + Release(); + OpenSubdiv::Far::ConstIndexArray indices = + patchTables->GetFVarPatchesValues(0); + + // expand fvardata to per-patch array + std::vector data; + data.reserve(indices.size() * fvarWidth); + + for (int fvert = 0; fvert < (int)indices.size(); ++fvert) { + int index = indices[fvert] * fvarWidth; + for (int i = 0; i < fvarWidth; ++i) { + data.push_back(fvarSrcData[index++]); + } + } + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(float), + &data[0], GL_STATIC_DRAW); + + glBindTexture(GL_TEXTURE_BUFFER, textureBuffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + glBindTexture(GL_ARRAY_BUFFER, 0); + + glDeleteBuffers(1, &buffer); + } + GLuint textureBuffer; +} g_fvarData; + static void checkGLErrors(std::string const & where = "") { @@ -532,7 +582,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -542,7 +592,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -553,7 +603,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -566,7 +616,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -580,7 +630,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -592,7 +642,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -605,7 +655,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -624,7 +674,17 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= InterpolateFVarData(*refiner, *shape, fvarData); - g_mesh->SetFVarDataChannel(shape->GetFVarWidth(), fvarData); + // set fvardata to texture buffer + g_fvarData.Create(g_mesh->GetFarPatchTables(), + shape->GetFVarWidth(), fvarData); + } + + // legacy gregory + delete g_legacyGregoryPatchTable; + g_legacyGregoryPatchTable = NULL; + if (g_endCap == kEndCapLegacyGregory) { + g_legacyGregoryPatchTable = + Osd::GLLegacyGregoryPatchTable::Create(g_mesh->GetFarPatchTables()); } if (not doAnim) { @@ -656,7 +716,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= // -------- VAO glBindVertexArray(g_vao); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer()); glBindBuffer(GL_ARRAY_BUFFER, g_mesh->BindVertexBuffer()); glEnableVertexAttribArray(0); @@ -994,19 +1054,20 @@ public: // assign texture locations GLint loc; glUseProgram(program); - if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) { + if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) { glUniform1i(loc, 0); // GL_TEXTURE0 } - if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) { + if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) { glUniform1i(loc, 1); // GL_TEXTURE1 } - if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) { + // for legacy gregory patches + if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) { glUniform1i(loc, 2); // GL_TEXTURE2 } - if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) { + if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) { glUniform1i(loc, 3); // GL_TEXTURE3 } - if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) { + if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) { glUniform1i(loc, 4); // GL_TEXTURE4 } glUseProgram(0); @@ -1089,37 +1150,36 @@ updateUniformBlocks() { static void bindTextures() { // bind patch textures - if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) { + if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexTextureBuffer()); + g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()); } - if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) { + + if (true) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()); + g_fvarData.textureBuffer); } - if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) { + + // legacy gregory + if (g_legacyGregoryPatchTable) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) { + g_legacyGregoryPatchTable->GetVertexTextureBuffer()); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()); - } - if (g_mesh->GetDrawContext()->GetFvarDataTextureBuffer()) { + g_legacyGregoryPatchTable->GetVertexValenceTextureBuffer()); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_BUFFER, - g_mesh->GetDrawContext()->GetFvarDataTextureBuffer()); + g_legacyGregoryPatchTable->GetQuadOffsetsTextureBuffer()); } glActiveTexture(GL_TEXTURE0); } static GLenum bindProgram(Effect effect, - OpenSubdiv::Osd::DrawContext::PatchArray const & patch) { + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) { EffectDesc effectDesc(patch.GetDescriptor(), effect); // only legacy gregory needs maxValence and numElements @@ -1127,7 +1187,7 @@ bindProgram(Effect effect, typedef OpenSubdiv::Far::PatchDescriptor Descriptor; if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) { - int maxValence = g_mesh->GetDrawContext()->GetMaxValence(); + int maxValence = g_mesh->GetMaxValence(); int numElements = (g_displayStyle == kInterleavedVaryingColor ? 7 : 3); effectDesc.maxValence = maxValence; effectDesc.numElements = numElements; @@ -1146,14 +1206,20 @@ bindProgram(Effect effect, glUseProgram(program); // bind standalone uniforms - GLint uniformGregoryQuadOffsetBase = - glGetUniformLocation(program, "GregoryQuadOffsetBase"); GLint uniformPrimitiveIdBase = glGetUniformLocation(program, "PrimitiveIdBase"); - if (uniformGregoryQuadOffsetBase >= 0) - glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex()); if (uniformPrimitiveIdBase >=0) - glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex()); + glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase()); + + // legacy gregory + if (g_endCap == kEndCapLegacyGregory) { + GLint uniformGregoryQuadOffsetBase = + glGetUniformLocation(program, "GregoryQuadOffsetBase"); + int quadOffsetBase = + g_legacyGregoryPatchTable->GetQuadOffsetsBase(patch.GetDescriptor().GetType()); + if (uniformGregoryQuadOffsetBase >= 0) + glUniform1i(uniformGregoryQuadOffsetBase, quadOffsetBase); + } // return primtype GLenum primType; @@ -1207,7 +1273,13 @@ display() { g_transformData.ProjectionMatrix); // make sure that the vertex buffer is interoped back as a GL resources. - g_mesh->BindVertexBuffer(); + GLuint vbo = g_mesh->BindVertexBuffer(); + + // vertex texture update for legacy gregory drawing + if (g_legacyGregoryPatchTable) { + glActiveTexture(GL_TEXTURE1); + g_legacyGregoryPatchTable->UpdateVertexBuffer(vbo); + } if (g_displayStyle == kVaryingColor) g_mesh->BindVaryingBuffer(); @@ -1225,8 +1297,8 @@ display() { glBindVertexArray(g_vao); - OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = - g_mesh->GetDrawContext()->GetPatchArrays(); + OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches = + g_mesh->GetPatchTable()->GetPatchArrays(); // patch drawing int patchCount[13]; // [Type] (see far/patchTables.h) @@ -1242,7 +1314,7 @@ display() { // core draw-calls for (int i=0; i<(int)patches.size(); ++i) { - OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i]; + OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i]; OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); @@ -1252,8 +1324,10 @@ display() { GLenum primType = bindProgram(GetEffect(), patch); - glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT, - (void *)(patch.GetVertIndex() * sizeof(unsigned int))); + glDrawElements(primType, + patch.GetNumPatches() * desc.GetNumControlVertices(), + GL_UNSIGNED_INT, + (void *)(patch.GetIndexBase() * sizeof(unsigned int))); ++numDrawCalls; } @@ -1395,6 +1469,10 @@ uninitGL() { if (g_mesh) delete g_mesh; + + if (g_legacyGregoryPatchTable) + delete g_legacyGregoryPatchTable; + } //------------------------------------------------------------------------------ diff --git a/opensubdiv/osd/CMakeLists.txt b/opensubdiv/osd/CMakeLists.txt index 775c155b..4994ef64 100644 --- a/opensubdiv/osd/CMakeLists.txt +++ b/opensubdiv/osd/CMakeLists.txt @@ -30,7 +30,6 @@ set(CPU_SOURCE_FILES cpuEvaluator.cpp cpuKernel.cpp cpuVertexBuffer.cpp - drawContext.cpp ) set(GPU_SOURCE_FILES ) @@ -48,7 +47,6 @@ set(PUBLIC_HEADER_FILES mesh.h nonCopyable.h opengl.h - drawContext.h vertexDescriptor.h ) @@ -106,7 +104,8 @@ list(APPEND DOXY_HEADER_FILES ${TBB_PUBLIC_HEADERS}) # GL code & dependencies set(GL_PUBLIC_HEADERS cpuGLVertexBuffer.h - glDrawContext.h + glLegacyGregoryPatchTable.h + glPatchTable.h glVertexBuffer.h glMesh.h glslPatchShaderSource.h @@ -115,7 +114,8 @@ set(GL_PUBLIC_HEADERS if( OPENGL_FOUND OR OPENGLES_FOUND ) list(APPEND GPU_SOURCE_FILES cpuGLVertexBuffer.cpp - glDrawContext.cpp + glLegacyGregoryPatchTable.cpp + glPatchTable.cpp glVertexBuffer.cpp glslPatchShaderSource.cpp ) @@ -182,7 +182,8 @@ list(APPEND DOXY_HEADER_FILES ${GL_4_3_PUBLIC_HEADERS}) set(DXSDK_PUBLIC_HEADERS cpuD3D11VertexBuffer.h d3d11ComputeEvaluator.h - d3d11DrawContext.h + d3d11LegacyGregoryPatchTable.h + d3d11PatchTable.h d3d11VertexBuffer.h d3d11Mesh.h hlslPatchShaderSource.h @@ -191,7 +192,8 @@ if( DXSDK_FOUND ) list(APPEND GPU_SOURCE_FILES cpuD3D11VertexBuffer.cpp d3d11ComputeEvaluator.cpp - d3d11DrawContext.cpp + d3d11LegacyGregoryPatchTable.cpp + d3d11PatchTable.cpp d3d11VertexBuffer.cpp hlslPatchShaderSource.cpp ) diff --git a/opensubdiv/osd/d3d11DrawContext.cpp b/opensubdiv/osd/d3d11DrawContext.cpp deleted file mode 100644 index d657147f..00000000 --- a/opensubdiv/osd/d3d11DrawContext.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// -// Copyright 2013 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// - -#include "../osd/d3d11DrawContext.h" - -#include - -#include - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { - -namespace Osd { - -D3D11DrawContext::D3D11DrawContext(int maxValence) : - DrawContext(maxValence), - patchIndexBuffer(NULL), - patchParamBuffer(NULL), - patchParamBufferSRV(NULL), - fvarDataBuffer(NULL), - fvarDataBufferSRV(NULL), - vertexBufferSRV(NULL), - vertexValenceBuffer(NULL), - vertexValenceBufferSRV(NULL), - quadOffsetBuffer(NULL), - quadOffsetBufferSRV(NULL) -{ -} - -D3D11DrawContext::~D3D11DrawContext() -{ - if (patchIndexBuffer) patchIndexBuffer->Release(); - if (patchParamBuffer) patchParamBuffer->Release(); - if (patchParamBufferSRV) patchParamBufferSRV->Release(); - if (fvarDataBuffer) fvarDataBuffer->Release(); - if (fvarDataBufferSRV) fvarDataBufferSRV->Release(); - if (vertexBufferSRV) vertexBufferSRV->Release(); - if (vertexValenceBuffer) vertexValenceBuffer->Release(); - if (vertexValenceBufferSRV) vertexValenceBufferSRV->Release(); - if (quadOffsetBuffer) quadOffsetBuffer->Release(); - if (quadOffsetBufferSRV) quadOffsetBufferSRV->Release(); -}; - -D3D11DrawContext * -D3D11DrawContext::Create(Far::PatchTables const *patchTables, - ID3D11DeviceContext *pd3d11DeviceContext) -{ - int maxValence = patchTables->GetMaxValence(); - D3D11DrawContext * result = new D3D11DrawContext(maxValence); - if (result->create(*patchTables, pd3d11DeviceContext)) - return result; - - delete result; - return NULL; -} - -bool -D3D11DrawContext::create(Far::PatchTables const &patchTables, - ID3D11DeviceContext *pd3d11DeviceContext) -{ - // adaptive patches - _isAdaptive = patchTables.IsFeatureAdaptive(); - - ID3D11Device *pd3d11Device = NULL; - pd3d11DeviceContext->GetDevice(&pd3d11Device); - assert(pd3d11Device); - - // Process PTable - Far::PatchTables::PatchVertsTable const & ptables = patchTables.GetPatchControlVerticesTable(); - - D3D11_BUFFER_DESC bd; - bd.ByteWidth = (int)ptables.size() * sizeof(int); - bd.Usage = D3D11_USAGE_DYNAMIC; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bd.MiscFlags = 0; - bd.StructureByteStride = sizeof(int); - HRESULT hr = pd3d11Device->CreateBuffer(&bd, NULL, &patchIndexBuffer); - if (FAILED(hr)) { - return false; - } - - D3D11_MAPPED_SUBRESOURCE mappedResource; - hr = pd3d11DeviceContext->Map(patchIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(hr)) { - return false; - } - unsigned int * indexBuffer = (unsigned int *) mappedResource.pData; - memcpy(indexBuffer, &ptables[0], ptables.size() * sizeof(unsigned int)); - - pd3d11DeviceContext->Unmap(patchIndexBuffer, 0); - - DrawContext::ConvertPatchArrays(patchTables, _patchArrays); - - // allocate and initialize additional buffer data - - // create patch param buffer - Far::PatchParamTable const & patchParamTables = - patchTables.GetPatchParamTable(); - - if (not patchParamTables.empty()) { - - int numElements = (int)patchParamTables.size(), - elementSize = sizeof(Far::PatchParam); - unsigned int const * values = - reinterpret_cast(&patchParamTables[0]); - - std::vector buffer; - - bool useSingleCrease = not patchTables.GetSharpnessIndexTable().empty(); - - if (useSingleCrease) { - // if indexed sharpnesses exists, flatten them and interleave into 3-component buffer - packSharpnessValues(patchTables, buffer); - elementSize += sizeof(float); - values = &buffer[0]; - } - - bd.ByteWidth = numElements * elementSize; - bd.Usage = D3D11_USAGE_DYNAMIC; - bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; - bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bd.MiscFlags = 0; - bd.StructureByteStride = sizeof(unsigned int); - hr = pd3d11Device->CreateBuffer(&bd, NULL, &patchParamBuffer); - if (FAILED(hr)) { - return false; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd; - ZeroMemory(&srvd, sizeof(srvd)); - srvd.Format = useSingleCrease ? DXGI_FORMAT_R32G32B32_UINT : DXGI_FORMAT_R32G32_UINT; - srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srvd.Buffer.FirstElement = 0; - srvd.Buffer.NumElements = numElements; - hr = pd3d11Device->CreateShaderResourceView( - patchParamBuffer, &srvd, &patchParamBufferSRV); - if (FAILED(hr)) { - return false; - } - hr = pd3d11DeviceContext->Map(patchParamBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(hr)) { - return false; - } - unsigned int *dst = (unsigned int *) mappedResource.pData; - memcpy(dst, values, numElements * elementSize); - pd3d11DeviceContext->Unmap(patchParamBuffer, 0); - } - - // create vertex valence buffer and vertex texture - Far::PatchTables::VertexValenceTable const & - valenceTable = patchTables.GetVertexValenceTable(); - - if (not valenceTable.empty()) { - D3D11_BUFFER_DESC bd; - bd.ByteWidth = UINT(valenceTable.size() * sizeof(unsigned int)); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; - bd.CPUAccessFlags = 0; - bd.MiscFlags = 0; - bd.StructureByteStride = sizeof(unsigned int); - D3D11_SUBRESOURCE_DATA initData; - initData.pSysMem = &valenceTable[0]; - HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, &vertexValenceBuffer); - if (FAILED(hr)) { - return false; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd; - ZeroMemory(&srvd, sizeof(srvd)); - srvd.Format = DXGI_FORMAT_R32_SINT; - srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srvd.Buffer.FirstElement = 0; - srvd.Buffer.NumElements = UINT(valenceTable.size()); - hr = pd3d11Device->CreateShaderResourceView(vertexValenceBuffer, &srvd, &vertexValenceBufferSRV); - if (FAILED(hr)) { - return false; - } - } - - Far::PatchTables::QuadOffsetsTable const & - quadOffsetTable = patchTables.GetQuadOffsetsTable(); - - if (not quadOffsetTable.empty()) { - D3D11_BUFFER_DESC bd; - bd.ByteWidth = UINT(quadOffsetTable.size() * sizeof(unsigned int)); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; - bd.CPUAccessFlags = 0; - bd.MiscFlags = 0; - bd.StructureByteStride = sizeof(unsigned int); - D3D11_SUBRESOURCE_DATA initData; - initData.pSysMem = &quadOffsetTable[0]; - HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, &quadOffsetBuffer); - if (FAILED(hr)) { - return false; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd; - ZeroMemory(&srvd, sizeof(srvd)); - srvd.Format = DXGI_FORMAT_R32_SINT; - srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srvd.Buffer.FirstElement = 0; - srvd.Buffer.NumElements = UINT(quadOffsetTable.size()); - hr = pd3d11Device->CreateShaderResourceView(quadOffsetBuffer, &srvd, &quadOffsetBufferSRV); - if (FAILED(hr)) { - return false; - } - } - - return true; -} - -bool -D3D11DrawContext::SetFVarDataTexture(Far::PatchTables const & patchTables, - int fvarWidth, FVarData const & fvarData, - ID3D11DeviceContext *pd3d11DeviceContext) { - - if (not fvarData.empty()) { - - FVarData fvarDataTable; - - packFVarData(patchTables, fvarWidth, fvarData, fvarDataTable); - - ID3D11Device *pd3d11Device = NULL; - pd3d11DeviceContext->GetDevice(&pd3d11Device); - assert(pd3d11Device); - - D3D11_BUFFER_DESC bd; - bd.ByteWidth = UINT(fvarDataTable.size() * sizeof(float)); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; - bd.CPUAccessFlags = 0; - bd.MiscFlags = 0; - bd.StructureByteStride = sizeof(float); - D3D11_SUBRESOURCE_DATA initData; - initData.pSysMem = &fvarDataTable[0]; - HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, &fvarDataBuffer); - if (FAILED(hr)) { - return false; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd; - ZeroMemory(&srvd, sizeof(srvd)); - srvd.Format = DXGI_FORMAT_R32_FLOAT; - srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srvd.Buffer.FirstElement = 0; - srvd.Buffer.NumElements = UINT(fvarDataTable.size()); - hr = pd3d11Device->CreateShaderResourceView(fvarDataBuffer, &srvd, &fvarDataBufferSRV); - if (FAILED(hr)) { - return false; - } - } - return true; -} - -void -D3D11DrawContext::updateVertexTexture(ID3D11Buffer *vbo, - ID3D11DeviceContext *pd3d11DeviceContext, - int numVertices, - int numVertexElements) -{ - ID3D11Device *pd3d11Device = NULL; - pd3d11DeviceContext->GetDevice(&pd3d11Device); - assert(pd3d11Device); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd; - ZeroMemory(&srvd, sizeof(srvd)); - srvd.Format = DXGI_FORMAT_R32_FLOAT; - srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srvd.Buffer.FirstElement = 0; - srvd.Buffer.NumElements = numVertices * numVertexElements; - HRESULT hr = pd3d11Device->CreateShaderResourceView(vbo, &srvd, &vertexBufferSRV); - if (FAILED(hr)) { - return; - } -} - -} // end namespace Osd - -} // end namespace OPENSUBDIV_VERSION -} // end namespace OpenSubdiv diff --git a/opensubdiv/osd/d3d11DrawContext.h b/opensubdiv/osd/d3d11DrawContext.h deleted file mode 100644 index 87ad9702..00000000 --- a/opensubdiv/osd/d3d11DrawContext.h +++ /dev/null @@ -1,167 +0,0 @@ -// -// Copyright 2013 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// - -#ifndef OPENSUBDIV3_OSD_D3D11L_DRAW_CONTEXT_H -#define OPENSUBDIV3_OSD_D3D11L_DRAW_CONTEXT_H - -#include "../version.h" - -#include "../far/patchTables.h" -#include "../osd/drawContext.h" - -#include - -struct ID3D11VertexShader; -struct ID3D11HullShader; -struct ID3D11DomainShader; -struct ID3D11GeometryShader; -struct ID3D11PixelShader; - -struct ID3D11Buffer; -struct ID3D11ShaderResourceView; -struct ID3D11Device; -struct ID3D11DeviceContext; - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { - -namespace Osd { - -/// \brief D3D11 specialized DrawContext class -/// -/// D3D11DrawContext implements the OSD drawing interface with Microsoft(c) -/// DirectX D3D11 API. -/// Some functionality may be disabled depending on compile and run-time driver -/// support. -/// -/// Contexts interface the serialized topological data pertaining to the -/// geometric primitives with the capabilities of the selected discrete -/// compute device. -/// -class D3D11DrawContext : public DrawContext { -public: - typedef ID3D11Buffer * VertexBufferBinding; - - virtual ~D3D11DrawContext(); - - /// \brief Create an D3D11DrawContext from Far::PatchTables - /// - /// @param patchTables A valid set of Far::PatchTables - /// - /// @param pd3d11DeviceContext A device context - /// - static D3D11DrawContext *Create(Far::PatchTables const *patchTables, - ID3D11DeviceContext *pd3d11DeviceContext); - - /// template version for custom context (OpenCL) used by OsdMesh - template - static D3D11DrawContext *Create(Far::PatchTables const *patchtables, - DEVICE_CONTEXT context) { - return Create(patchtables, context->GetDeviceContext()); - } - - /// Set vbo as a vertex texture (for gregory patch drawing) - /// - /// @param vbo The vertex buffer object to update - /// - /// @param pd3d11DeviceContext A device context - /// - template - void UpdateVertexTexture(VERTEX_BUFFER *vbo, ID3D11DeviceContext *pd3d11DeviceContext) { - if (vbo) - updateVertexTexture(vbo->BindD3D11Buffer(pd3d11DeviceContext), - pd3d11DeviceContext, - vbo->GetNumVertices(), - vbo->GetNumElements()); - } - - /// template version for custom context (OpenCL) used by OsdMesh - template - void UpdateVertexTexture(VERTEX_BUFFER *vbo, DEVICE_CONTEXT context) { - UpdateVertexTexture(vbo, context->GetDeviceContext()); - } - - ID3D11Buffer *patchIndexBuffer; - - ID3D11Buffer *patchParamBuffer; - ID3D11ShaderResourceView *patchParamBufferSRV; - - ID3D11Buffer *fvarDataBuffer; - ID3D11ShaderResourceView *fvarDataBufferSRV; - - ID3D11ShaderResourceView *vertexBufferSRV; - ID3D11Buffer *vertexValenceBuffer; - ID3D11ShaderResourceView *vertexValenceBufferSRV; - ID3D11Buffer *quadOffsetBuffer; - ID3D11ShaderResourceView *quadOffsetBufferSRV; - - /// Sets face-varying data buffer - /// - /// @param patchTables A valid set of Far::PatchTables - /// - /// @param pd3d11DeviceContext A device context - /// - /// @param fvarWidth Total face-varying primvar data width in fvarData - /// - /// @param fvarData Vector containing the face-varying data - /// - /// @return True if the operation was successful - /// - bool SetFVarDataTexture(Far::PatchTables const & patchTables, - int fvarWidth, FVarData const & fvarData, - ID3D11DeviceContext *pd3d11DeviceContext); - - /// template version for custom context (OpenCL) used by OsdMesh - template - bool SetFVarDataTexture(Far::PatchTables const & patchTables, - int fvarWidth, FVarData const & fvarData, - DEVICE_CONTEXT context) { - return SetFVarDataTexture(patchTables, fvarWidth, fvarData, - context->GetDeviceContext()); - } - -private: - D3D11DrawContext(int maxValence); - - - // allocate buffers from patchTables - bool create(Far::PatchTables const &patchTables, - ID3D11DeviceContext *pd3d11DeviceContext); - - void updateVertexTexture(ID3D11Buffer *vbo, - ID3D11DeviceContext *pd3d11DeviceContext, - int numVertices, - int numVertexElements); - - int _numVertices; -}; - -} // end namespace Osd - -} // end namespace OPENSUBDIV_VERSION -using namespace OPENSUBDIV_VERSION; - -} // end namespace OpenSubdiv - -#endif /* OPENSUBDIV3_OSD_D3D11L_DRAW_CONTEXT_H */ diff --git a/opensubdiv/osd/d3d11LegacyGregoryPatchTable.cpp b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.cpp new file mode 100644 index 00000000..06b21fc6 --- /dev/null +++ b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.cpp @@ -0,0 +1,165 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#include "../osd/d3d11LegacyGregoryPatchTable.h" + +#include + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Osd { + +D3D11LegacyGregoryPatchTable::D3D11LegacyGregoryPatchTable() : + _vertexValenceBuffer(0), _quadOffsetsBuffer(0), + _vertexSRV(0), _vertexValenceSRV(0), _quadOffsetsSRV(0) { + _quadOffsetsBase[0] = _quadOffsetsBase[1] = 0; +} + +D3D11LegacyGregoryPatchTable::~D3D11LegacyGregoryPatchTable() { + if (_vertexValenceBuffer) _vertexValenceBuffer->Release(); + if (_quadOffsetsBuffer) _quadOffsetsBuffer->Release(); + if (_vertexSRV) _vertexSRV->Release(); + if (_vertexValenceSRV) _vertexValenceSRV->Release(); + if (_quadOffsetsSRV) _quadOffsetsSRV->Release(); +} + +D3D11LegacyGregoryPatchTable * +D3D11LegacyGregoryPatchTable::Create(Far::PatchTables const *farPatchTables, + ID3D11DeviceContext *pd3d11DeviceContext) { + ID3D11Device *pd3d11Device = NULL; + pd3d11DeviceContext->GetDevice(&pd3d11Device); + assert(pd3d11Device); + + D3D11LegacyGregoryPatchTable *result = new D3D11LegacyGregoryPatchTable(); + + Far::PatchTables::VertexValenceTable const & + valenceTable = farPatchTables->GetVertexValenceTable(); + Far::PatchTables::QuadOffsetsTable const & + quadOffsetsTable = farPatchTables->GetQuadOffsetsTable(); + + if (not valenceTable.empty()) { + D3D11_BUFFER_DESC bd; + bd.ByteWidth = UINT(valenceTable.size() * sizeof(unsigned int)); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; + bd.CPUAccessFlags = 0; + bd.MiscFlags = 0; + bd.StructureByteStride = sizeof(unsigned int); + D3D11_SUBRESOURCE_DATA initData; + initData.pSysMem = &valenceTable[0]; + HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, + &result->_vertexValenceBuffer); + if (FAILED(hr)) { + delete result; + return NULL; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC srvd; + ZeroMemory(&srvd, sizeof(srvd)); + srvd.Format = DXGI_FORMAT_R32_SINT; + srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvd.Buffer.FirstElement = 0; + srvd.Buffer.NumElements = UINT(valenceTable.size()); + hr = pd3d11Device->CreateShaderResourceView( + result->_vertexValenceBuffer, &srvd, + &result->_vertexValenceSRV); + if (FAILED(hr)) { + delete result; + return NULL; + } + } + + if (not quadOffsetsTable.empty()) { + D3D11_BUFFER_DESC bd; + bd.ByteWidth = UINT(quadOffsetsTable.size() * sizeof(unsigned int)); + bd.Usage = D3D11_USAGE_DEFAULT; + bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; + bd.CPUAccessFlags = 0; + bd.MiscFlags = 0; + bd.StructureByteStride = sizeof(unsigned int); + D3D11_SUBRESOURCE_DATA initData; + initData.pSysMem = &quadOffsetsTable[0]; + HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, + &result->_quadOffsetsBuffer); + if (FAILED(hr)) { + delete result; + return NULL; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC srvd; + ZeroMemory(&srvd, sizeof(srvd)); + srvd.Format = DXGI_FORMAT_R32_SINT; + srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvd.Buffer.FirstElement = 0; + srvd.Buffer.NumElements = UINT(quadOffsetsTable.size()); + hr = pd3d11Device->CreateShaderResourceView( + result->_quadOffsetsBuffer, &srvd, &result->_quadOffsetsSRV); + if (FAILED(hr)) { + delete result; + return NULL; + } + } + + result->_quadOffsetsBase[0] = 0; + result->_quadOffsetsBase[1] = 0; + + // scan patchtable to find quadOffsetsBase. + for (int i = 0; i < farPatchTables->GetNumPatchArrays(); ++i) { + // GREGORY_BOUNDARY's quadoffsets come after GREGORY's. + if (farPatchTables->GetPatchArrayDescriptor(i) == + Far::PatchDescriptor::GREGORY) { + result->_quadOffsetsBase[1] = farPatchTables->GetNumPatches(i) * 4; + break; + } + } + + return result; +} + +void +D3D11LegacyGregoryPatchTable::UpdateVertexBuffer( + ID3D11Buffer *vbo, int numVertices, int numVertexElements, + ID3D11DeviceContext *pd3d11DeviceContext) { + ID3D11Device *pd3d11Device = NULL; + pd3d11DeviceContext->GetDevice(&pd3d11Device); + assert(pd3d11Device); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvd; + ZeroMemory(&srvd, sizeof(srvd)); + srvd.Format = DXGI_FORMAT_R32_FLOAT; + srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvd.Buffer.FirstElement = 0; + srvd.Buffer.NumElements = numVertices * numVertexElements; + HRESULT hr = pd3d11Device->CreateShaderResourceView(vbo, &srvd, + &_vertexSRV); + if (FAILED(hr)) { + return; + } +} + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +} // end namespace OpenSubdiv diff --git a/opensubdiv/osd/d3d11LegacyGregoryPatchTable.h b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.h new file mode 100644 index 00000000..fdd16992 --- /dev/null +++ b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.h @@ -0,0 +1,102 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#ifndef OPENSUBDIV3_OSD_D3D11_LEGACY_GREGORY_PATCH_TABLE_H +#define OPENSUBDIV3_OSD_D3D11_LEGACY_GREGORY_PATCH_TABLE_H + +#include "../version.h" + +#include "../far/patchTables.h" +#include "../osd/nonCopyable.h" + +struct ID3D11Buffer; +struct ID3D11ShaderResourceView; +struct ID3D11Device; +struct ID3D11DeviceContext; + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Osd { + +class D3D11LegacyGregoryPatchTable + : private NonCopyable { +public: + ~D3D11LegacyGregoryPatchTable(); + + template + static D3D11LegacyGregoryPatchTable *Create( + Far::PatchTables const *farPatchTables, DEVICE_CONTEXT context) { + return Create(farPatchTables, context->GetDeviceContext()); + } + + static D3D11LegacyGregoryPatchTable *Create( + Far::PatchTables const *farPatchTables, + ID3D11DeviceContext *deviceContext); + + void UpdateVertexBuffer(ID3D11Buffer *vbo, + int numVertices, int numVertexElements, + ID3D11DeviceContext *pd3d11DeviceContext); + + ID3D11ShaderResourceView* GetVertexSRV() const { + return _vertexSRV; + } + + ID3D11ShaderResourceView* GetVertexValenceSRV() const { + return _vertexValenceSRV; + } + + ID3D11ShaderResourceView* GetQuadOffsetsSRV() const { + return _quadOffsetsSRV; + } + + int GetQuadOffsetsBase(Far::PatchDescriptor::Type type) { + if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) { + return _quadOffsetsBase[1]; + } + return _quadOffsetsBase[0]; + } + +protected: + D3D11LegacyGregoryPatchTable(); + +private: + ID3D11Buffer* _vertexValenceBuffer; + ID3D11Buffer* _quadOffsetsBuffer; + ID3D11ShaderResourceView* _vertexSRV; + ID3D11ShaderResourceView* _vertexValenceSRV; + ID3D11ShaderResourceView* _quadOffsetsSRV; + int _quadOffsetsBase[2]; // gregory, boundaryGregory +}; + + + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +using namespace OPENSUBDIV_VERSION; + +} // end namespace OpenSubdiv + +#endif // OPENSUBDIV3_OSD_D3D11_LEGACY_GREGORY_PATCH_TABLE_H diff --git a/opensubdiv/osd/d3d11Mesh.h b/opensubdiv/osd/d3d11Mesh.h index 550fd51a..5ce0a7f5 100644 --- a/opensubdiv/osd/d3d11Mesh.h +++ b/opensubdiv/osd/d3d11Mesh.h @@ -28,14 +28,15 @@ #include "../version.h" #include "../osd/mesh.h" -#include "../osd/d3d11DrawContext.h" +#include "../osd/d3d11PatchTable.h" namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Osd { -typedef MeshInterface D3D11MeshInterface; +typedef MeshInterface D3D11MeshInterface; + } // end namespace Osd diff --git a/opensubdiv/osd/d3d11PatchTable.cpp b/opensubdiv/osd/d3d11PatchTable.cpp new file mode 100644 index 00000000..cb886668 --- /dev/null +++ b/opensubdiv/osd/d3d11PatchTable.cpp @@ -0,0 +1,182 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#include "../osd/d3d11PatchTable.h" + +#include +#include "../far/patchTables.h" + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Osd { + +D3D11PatchTable::D3D11PatchTable() : + _indexBuffer(0), _patchParamBuffer(0), _patchParamBufferSRV(0) { +} + +D3D11PatchTable::~D3D11PatchTable() { + if (_indexBuffer) _indexBuffer->Release(); + if (_patchParamBuffer) _patchParamBuffer->Release(); + if (_patchParamBufferSRV) _patchParamBufferSRV->Release(); +} + +D3D11PatchTable * +D3D11PatchTable::Create(Far::PatchTables const *farPatchTables, + ID3D11DeviceContext *pd3d11DeviceContext) { + D3D11PatchTable *instance = new D3D11PatchTable(); + if (instance->allocate(farPatchTables, pd3d11DeviceContext)) + return instance; + delete instance; + return 0; +} + +bool +D3D11PatchTable::allocate(Far::PatchTables const *farPatchTables, + ID3D11DeviceContext *pd3d11DeviceContext) { + ID3D11Device *pd3d11Device = NULL; + pd3d11DeviceContext->GetDevice(&pd3d11Device); + assert(pd3d11Device); + + std::vector buffer; + std::vector ppBuffer; + + // needs reserve? + int nPatchArrays = farPatchTables->GetNumPatchArrays(); + + // for each patchArray + for (int j = 0; j < nPatchArrays; ++j) { + PatchArray patchArray(farPatchTables->GetPatchArrayDescriptor(j), + farPatchTables->GetNumPatches(j), + (int)buffer.size(), + (int)ppBuffer.size()/3); + _patchArrays.push_back(patchArray); + + // indices + Far::ConstIndexArray indices = farPatchTables->GetPatchArrayVertices(j); + for (int k = 0; k < indices.size(); ++k) { + buffer.push_back(indices[k]); + } + + // patchParams +#if 0 + // XXX: we need sharpness interface for patcharray or put sharpness + // into patchParam. + Far::ConstPatchParamArray patchParams = + farPatchTables->GetPatchParams(j); + for (int k = 0; k < patchParams.size(); ++k) { + float sharpness = 0.0; + ppBuffer.push_back(patchParams[k].faceIndex); + ppBuffer.push_back(patchParams[k].bitField.field); + ppBuffer.push_back(*((unsigned int *)&sharpness)); + } +#else + // XXX: workaround. GetPatchParamTable() will be deprecated though. + Far::PatchParamTable const & patchParamTables = + farPatchTables->GetPatchParamTable(); + std::vector const &sharpnessIndexTable = + farPatchTables->GetSharpnessIndexTable(); + int numPatches = farPatchTables->GetNumPatches(j); + for (int k = 0; k < numPatches; ++k) { + float sharpness = 0.0; + int patchIndex = (int)ppBuffer.size()/3; + if (patchIndex < (int)sharpnessIndexTable.size()) { + int sharpnessIndex = sharpnessIndexTable[patchIndex]; + if (sharpnessIndex >= 0) + sharpness = farPatchTables->GetSharpnessValues()[sharpnessIndex]; + } + ppBuffer.push_back(patchParamTables[patchIndex].faceIndex); + ppBuffer.push_back(patchParamTables[patchIndex].bitField.field); + ppBuffer.push_back(*((unsigned int *)&sharpness)); + } +#endif + } + + // index buffer + D3D11_BUFFER_DESC bd; + ZeroMemory(&bd, sizeof(bd)); + bd.ByteWidth = (int)buffer.size() * sizeof(int); + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.BindFlags = D3D11_BIND_INDEX_BUFFER; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + bd.StructureByteStride = sizeof(int); + HRESULT hr = pd3d11Device->CreateBuffer(&bd, NULL, &_indexBuffer); + if (FAILED(hr)) { + return false; + } + + D3D11_MAPPED_SUBRESOURCE mappedResource; + hr = pd3d11DeviceContext->Map(_indexBuffer, 0, + D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(hr)) { + return false; + } + unsigned int * indexBuffer = (unsigned int *) mappedResource.pData; + memcpy(indexBuffer, &buffer[0], buffer.size() * sizeof(unsigned int)); + + pd3d11DeviceContext->Unmap(_indexBuffer, 0); + + // patchparam buffer + ZeroMemory(&bd, sizeof(bd)); + bd.ByteWidth = (int)ppBuffer.size() * sizeof(int); + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + bd.StructureByteStride = sizeof(unsigned int); + hr = pd3d11Device->CreateBuffer(&bd, NULL, &_patchParamBuffer); + if (FAILED(hr)) { + return false; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC srvd; + ZeroMemory(&srvd, sizeof(srvd)); + srvd.Format = DXGI_FORMAT_R32G32B32_UINT; + srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvd.Buffer.FirstElement = 0; + srvd.Buffer.NumElements = (int)ppBuffer.size()/3; + hr = pd3d11Device->CreateShaderResourceView( + _patchParamBuffer, &srvd, &_patchParamBufferSRV); + if (FAILED(hr)) { + return false; + } + hr = pd3d11DeviceContext->Map(_patchParamBuffer, 0, + D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(hr)) { + return false; + } + unsigned int *dst = (unsigned int *) mappedResource.pData; + memcpy(dst, &ppBuffer[0], ppBuffer.size() * sizeof(int)); + pd3d11DeviceContext->Unmap(_patchParamBuffer, 0); + + return true; +} + + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +} // end namespace OpenSubdiv + diff --git a/opensubdiv/osd/d3d11PatchTable.h b/opensubdiv/osd/d3d11PatchTable.h new file mode 100644 index 00000000..604f7404 --- /dev/null +++ b/opensubdiv/osd/d3d11PatchTable.h @@ -0,0 +1,125 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#ifndef OPENSUBDIV3_OSD_GL_PATCH_TABLE_H +#define OPENSUBDIV3_OSD_GL_PATCH_TABLE_H + +#include "../version.h" + +#include +#include "../far/patchDescriptor.h" +#include "../osd/nonCopyable.h" + +struct ID3D11Buffer; +struct ID3D11ShaderResourceView; +struct ID3D11Device; +struct ID3D11DeviceContext; + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Far{ + class PatchTables; +}; + +namespace Osd { + +class D3D11PatchTable : private NonCopyable { +public: + typedef ID3D11Buffer * VertexBufferBinding; + + // XXX: this struct will be further refactored. + class PatchArray { + public: + PatchArray(Far::PatchDescriptor desc, int numPatches, + int indexBase, int primitiveIdBase) : + desc(desc), numPatches(numPatches), indexBase(indexBase), + primitiveIdBase(primitiveIdBase) {} + Far::PatchDescriptor const &GetDescriptor() const { + return desc; + } + int GetNumPatches() const { + return numPatches; + } + int GetIndexBase() const { + return indexBase; + } + int GetPrimitiveIdBase() const { + return primitiveIdBase; + } + private: + Far::PatchDescriptor desc; + int numPatches; + int indexBase; // an offset within the index buffer + int primitiveIdBase; // an offset within the patch param buffer + }; + typedef std::vector PatchArrayVector; + + D3D11PatchTable(); + ~D3D11PatchTable(); + + template + static D3D11PatchTable *Create(Far::PatchTables const *farPatchTables, + DEVICE_CONTEXT context) { + return Create(farPatchTables, context->GetDeviceContext()); + } + + static D3D11PatchTable *Create(Far::PatchTables const *farPatchTables, + ID3D11DeviceContext *deviceContext); + + PatchArrayVector const &GetPatchArrays() const { + return _patchArrays; + } + + /// Returns the index buffer containing the patch control vertices + ID3D11Buffer* GetPatchIndexBuffer() const { + return _indexBuffer; + } + + /// Returns the SRV containing the patch parameter + ID3D11ShaderResourceView* GetPatchParamSRV() const { + return _patchParamBufferSRV; + } + +protected: + // allocate buffers from patchTables + bool allocate(Far::PatchTables const *farPatchTables, + ID3D11DeviceContext *deviceContext); + + PatchArrayVector _patchArrays; + + ID3D11Buffer *_indexBuffer; + ID3D11Buffer *_patchParamBuffer; + ID3D11ShaderResourceView *_patchParamBufferSRV; +}; + + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +using namespace OPENSUBDIV_VERSION; + +} // end namespace OpenSubdiv + +#endif // OPENSUBDIV3_OSD_GL_PATCH_TABLE_H diff --git a/opensubdiv/osd/drawContext.cpp b/opensubdiv/osd/drawContext.cpp deleted file mode 100644 index d274a39e..00000000 --- a/opensubdiv/osd/drawContext.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// -// Copyright 2013 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// - -#include "../osd/drawContext.h" - -#include "../far/patchTables.h" - -#include - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { - -namespace Osd { - -DrawContext::~DrawContext() {} - -void -DrawContext::ConvertPatchArrays(Far::PatchTables const &patchTables, - PatchArrayVector &osdPatchArrays) { - - int narrays = patchTables.GetNumPatchArrays(); - - // allocate drawing patch arrays - osdPatchArrays.clear(); - osdPatchArrays.reserve(narrays); - - for (int array=0, pidx=0, vidx=0, qidx=0; array & dst) { - - dst.resize(patchTables.GetNumControlVerticesTotal()); - Index * ptr = &dst[0]; - - int narrays = patchTables.GetNumPatchArrays(); - for (int array=0; array & dst) { - - Far::PatchParamTable const & patchParamTables = - patchTables.GetPatchParamTable(); - - std::vector const &sharpnessIndexTable = - patchTables.GetSharpnessIndexTable(); - - std::vector const &sharpnessValues = - patchTables.GetSharpnessValues(); - - int npatches = (int)patchParamTables.size(); - - // PatchParam = sizeof(int)*2, 1 float for sharpness - dst.resize(npatches * (2 + 1)); - - for (int i = 0; i < npatches; ++i) { - float sharpness = sharpnessIndexTable[i] >= 0 ? - sharpnessValues[sharpnessIndexTable[i]] : 0.0f; - dst[i*3+0] = patchParamTables[i].faceIndex; - dst[i*3+1] = patchParamTables[i].bitField.field; - dst[i*3+2] = *((unsigned int *)&sharpness); - } -} - -void -DrawContext::packFVarData(Far::PatchTables const & patchTables, - int fvarWidth, FVarData const & src, FVarData & dst) { - - assert(fvarWidth and (not src.empty())); - - // XXXX OsdMesh only accesses channel 0 - Far::ConstIndexArray indices = patchTables.GetFVarPatchesValues(0); - - dst.resize(indices.size() * fvarWidth); - float * ptr = &dst[0]; - - for (int fvert=0; fvert<(int)indices.size(); ++fvert, ptr+=fvarWidth) { - - int index = indices[fvert] * fvarWidth; - assert(index<(int)src.size()); - - memcpy(ptr, &src[index], fvarWidth*sizeof(float)); - } -} - -} // end namespace Osd - -} // end namespace OPENSUBDIV_VERSION -} // end namespace OpenSubdiv diff --git a/opensubdiv/osd/drawContext.h b/opensubdiv/osd/drawContext.h deleted file mode 100644 index 923eb0ab..00000000 --- a/opensubdiv/osd/drawContext.h +++ /dev/null @@ -1,197 +0,0 @@ -// -// Copyright 2013 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// - -#ifndef OPENSUBDIV3_OSD_DRAW_CONTEXT_H -#define OPENSUBDIV3_OSD_DRAW_CONTEXT_H - -#include "../version.h" - -#include "../far/patchDescriptor.h" -#include "../far/types.h" - -#include -#include - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { - -namespace Far { - class PatchTables; -} - -namespace Osd { - -/// \brief Base DrawContext class -/// -/// DrawContext derives several sub-classes with API specific functionality -/// (GL, D3D11, ...). -/// -/// Current specificiation GPU hardware tessellation limitations require transition -/// patches to be split-up into several triangular bi-cubic sub-patches. -/// DrawContext processes FarPatchArrays from Far::PatchTables and generates the -/// additional sets of sub-patches. -/// -/// Contexts interface the serialized topological data pertaining to the -/// geometric primitives with the capabilities of the selected discrete -/// compute device. -/// -class DrawContext { - -public: - typedef Far::Index Index; - - class PatchArray { - public: - /// Constructor - /// - /// @param desc Patch descriptor defines the type, pattern, rotation of - /// the patches in the array - /// - /// @param npatches The number of patches in the array - /// - /// @param vertIndex Index of the first control vertex in the array - /// - /// @param patchIndex Index of the first patch in the array - /// - /// @param qoIndex Index of the first quad-offset entry - /// - PatchArray(Far::PatchDescriptor desc, int npatches, - Index vertIndex, Index patchIndex, Index qoIndex) : - _desc(desc), _npatches(npatches), - _vertIndex(vertIndex), _patchIndex(patchIndex), _quadOffsetIndex(qoIndex) { } - - /// Returns a patch descriptor defining the type of patches in the array - Far::PatchDescriptor GetDescriptor() const { - return _desc; - } - - /// Update a patch descriptor - void SetDescriptor(Far::PatchDescriptor desc) { - _desc = desc; - } - - /// Returns the index of the first control vertex of the first patch - /// of this array in the global PTable - unsigned int GetVertIndex() const { - return _vertIndex; - } - - /// Returns the global index of the first patch in this array (Used to - /// access ptex / fvar table data) - unsigned int GetPatchIndex() const { - return _patchIndex; - } - - /// Returns the number of patches in the array - unsigned int GetNumPatches() const { - return _npatches; - } - - /// Returns the number of patch indices in the array - unsigned int GetNumIndices() const { - return _npatches * _desc.GetNumControlVertices(); - } - - /// Returns the offset of quad offset table - unsigned int GetQuadOffsetIndex() const { - return _quadOffsetIndex; - } - - /// Set num patches (used at batch glomming) - void SetNumPatches(int npatches) { - _npatches = npatches; - } - - private: - Far::PatchDescriptor _desc; - int _npatches; - Index _vertIndex, - _patchIndex, - _quadOffsetIndex; - }; - - /// Constructor - DrawContext(int maxValence) : _isAdaptive(false), _maxValence(maxValence) {} - - /// Descrtuctor - virtual ~DrawContext(); - - /// Returns true if the primitive attached to the context uses feature adaptive - /// subdivision - bool IsAdaptive() const { - return _isAdaptive; - } - - typedef std::vector PatchArrayVector; - - PatchArrayVector const & GetPatchArrays() const { - return _patchArrays; - } - - /// The writable accessor to the internal patch array (tentative). - /// We should have a different api something like ConvertPatchArrays(). - PatchArrayVector &GetPatchArrays() { - return _patchArrays; - } - - // processes FarPatchArrays and inserts requisite sub-patches for the arrays - // containing transition patches - static void ConvertPatchArrays(Far::PatchTables const &patchTables, - DrawContext::PatchArrayVector &osdPatchArrays); - - // maxValence is needed for legacy gregorypatch drawing - int GetMaxValence() const { - return _maxValence; - } - - typedef std::vector FVarData; - - -protected: - - static void packPatchVerts(Far::PatchTables const & patchTables, - std::vector & dst); - - static void packSharpnessValues(Far::PatchTables const & patchTables, - std::vector & dst); - - static void packFVarData(Far::PatchTables const & patchTables, - int fvarWidth, FVarData const & src, FVarData & dst); - - // XXXX: move to private member - PatchArrayVector _patchArrays; - - bool _isAdaptive; - - int _maxValence; -}; - -} // end namespace Osd - -} // end namespace OPENSUBDIV_VERSION -using namespace OPENSUBDIV_VERSION; - -} // end namespace OpenSubdiv - -#endif /* OPENSUBDIV3_OSD_DRAW_CONTEXT_H */ diff --git a/opensubdiv/osd/glDrawContext.cpp b/opensubdiv/osd/glDrawContext.cpp deleted file mode 100644 index afef5b43..00000000 --- a/opensubdiv/osd/glDrawContext.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// -// Copyright 2013 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// - -#include "../osd/glDrawContext.h" - -#include "../osd/opengl.h" - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { - -namespace Osd { - -GLDrawContext::GLDrawContext(int maxValence) : - DrawContext(maxValence), - _patchIndexBuffer(0), _patchParamTextureBuffer(0), _fvarDataTextureBuffer(0), - _vertexTextureBuffer(0), _vertexValenceTextureBuffer(0), _quadOffsetsTextureBuffer(0) -{ -} - -GLDrawContext::~GLDrawContext() -{ - glDeleteBuffers(1, &_patchIndexBuffer); - glDeleteTextures(1, &_vertexTextureBuffer); - glDeleteTextures(1, &_vertexValenceTextureBuffer); - glDeleteTextures(1, &_quadOffsetsTextureBuffer); - glDeleteTextures(1, &_patchParamTextureBuffer); - glDeleteTextures(1, &_fvarDataTextureBuffer); -} - -template static GLuint -createTextureBuffer(T const &data, GLint format, int offset=0) -{ - GLuint buffer = 0, texture = 0; - -#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1) - glGenTextures(1, &texture); - glGenBuffers(1, &buffer); - -#if defined(GL_EXT_direct_state_access) - if (glNamedBufferDataEXT and glTextureBufferEXT) { - glNamedBufferDataEXT(buffer, (data.size()-offset) * sizeof(typename T::value_type), - &data[offset], GL_STATIC_DRAW); - glTextureBufferEXT(texture, GL_TEXTURE_BUFFER, format, buffer); - } else { -#else - { -#endif - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, (data.size()-offset) * sizeof(typename T::value_type), - &data[offset], GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glBindTexture(GL_TEXTURE_BUFFER, texture); - glTexBuffer(GL_TEXTURE_BUFFER, format, buffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - } - glDeleteBuffers(1, &buffer); - -#endif - - return texture; -} - -GLDrawContext * -GLDrawContext::Create(Far::PatchTables const * patchTables, void * /*deviceContext*/) { - - if (patchTables) { - - int maxValence = patchTables->GetMaxValence(); - GLDrawContext * result = new GLDrawContext(maxValence); - - if (result->create(*patchTables)) { - return result; - } else { - delete result; - } - } - return NULL; -} - -bool -GLDrawContext::create(Far::PatchTables const & patchTables) { - - _isAdaptive = patchTables.IsFeatureAdaptive(); - - // Process PTable - Far::PatchTables::PatchVertsTable const & ptables = patchTables.GetPatchControlVerticesTable(); - - glGenBuffers(1, &_patchIndexBuffer); - -#if defined(GL_EXT_direct_state_access) - if (glNamedBufferDataEXT) { - glNamedBufferDataEXT(_patchIndexBuffer, - ptables.size() * sizeof(unsigned int), &ptables[0], GL_STATIC_DRAW); - } else { -#else - { -#endif - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _patchIndexBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - ptables.size() * sizeof(unsigned int), &ptables[0], GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - - DrawContext::ConvertPatchArrays(patchTables, _patchArrays); - - // allocate and initialize additional buffer data - -#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1) - // create vertex valence buffer and vertex texture - Far::PatchTables::VertexValenceTable const & - valenceTable = patchTables.GetVertexValenceTable(); - - if (not valenceTable.empty()) { - _vertexValenceTextureBuffer = createTextureBuffer(valenceTable, GL_R32I); - - // also create vertex texture buffer (will be updated in UpdateVertexTexture()) - glGenTextures(1, &_vertexTextureBuffer); - } - - - // create quad offset table buffer - Far::PatchTables::QuadOffsetsTable const & - quadOffsetTable = patchTables.GetQuadOffsetsTable(); - - if (not quadOffsetTable.empty()) - _quadOffsetsTextureBuffer = createTextureBuffer(quadOffsetTable, GL_R32I); - - - // create ptex coordinate buffer - Far::PatchParamTable const & patchParamTables = - patchTables.GetPatchParamTable(); - - if (not patchParamTables.empty()) { - - if (patchTables.GetSharpnessIndexTable().empty()) { - - _patchParamTextureBuffer = createTextureBuffer(patchParamTables, GL_RG32I); - } else { - - // if indexed sharpnesses exists, flatten them and interleave into 3-component buffer - std::vector buffer; - packSharpnessValues(patchTables, buffer); - - _patchParamTextureBuffer = createTextureBuffer(buffer, GL_RGB32I); - } - } - - glBindBuffer(GL_TEXTURE_BUFFER, 0); -#endif - - return true; -} - -#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1) -bool -GLDrawContext::SetFVarDataTexture( - Far::PatchTables const & patchTables, int fvarWidth, FVarData const & fvarData, - void * /*deviceContext*/) { - - if (not fvarData.empty()) { - - FVarData fvarDataTable; - - packFVarData(patchTables, fvarWidth, fvarData, fvarDataTable); - - _fvarDataTextureBuffer = createTextureBuffer(fvarDataTable, GL_R32F); - - return true; - } - return false; -} -#else -bool -GLDrawContext::SetFVarDataTexture( - Far::PatchTables const &, int, FVarData const &, - void * /*deviceContext*/) { - - return false; -} -#endif - -#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1) -void -GLDrawContext::updateVertexTexture(GLuint vbo) -{ - -#if defined(GL_EXT_direct_state_access) - if (glTextureBufferEXT) { - glTextureBufferEXT(_vertexTextureBuffer, GL_TEXTURE_BUFFER, GL_R32F, vbo); - } else { -#else - { -#endif - glBindTexture(GL_TEXTURE_BUFFER, _vertexTextureBuffer); - glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, vbo); - glBindTexture(GL_TEXTURE_BUFFER, 0); - } -} -#else -void -GLDrawContext::updateVertexTexture(GLuint) -{ -} -#endif - - -} // end namespace Osd - -} // end namespace OPENSUBDIV_VERSION -} // end namespace OpenSubdiv diff --git a/opensubdiv/osd/glDrawContext.h b/opensubdiv/osd/glDrawContext.h deleted file mode 100644 index eeafecec..00000000 --- a/opensubdiv/osd/glDrawContext.h +++ /dev/null @@ -1,151 +0,0 @@ -// -// Copyright 2013 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// - -#ifndef OPENSUBDIV3_OSD_GL_DRAW_CONTEXT_H -#define OPENSUBDIV3_OSD_GL_DRAW_CONTEXT_H - -#include "../version.h" - -#include - -#include "../far/patchTables.h" -#include "../osd/drawContext.h" -#include "../osd/opengl.h" - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { - -namespace Osd { - -/// \brief OpenGL specialized DrawContext class -/// -/// GLDrawContext implements the OSD drawing interface with the OpenGL API. -/// Some functionality may be disabled depending on compile and run-time driver -/// support. -/// -/// Contexts interface the serialized topological data pertaining to the -/// geometric primitives with the capabilities of the selected discrete -/// compute device. -/// -class GLDrawContext : public DrawContext { -public: - typedef GLuint VertexBufferBinding; - - virtual ~GLDrawContext(); - - /// \brief Create an GLDraContext from Far::PatchTables - /// - /// @param patchTables a valid set of Far::PatchTables - /// - /// @param deviceContext not used in GLDrawContext - /// - static GLDrawContext * Create(Far::PatchTables const * patchTables, - void *deviceContext = NULL); - - /// Set vbo as a vertex texture (for gregory patch drawing) - /// - /// @param vbo the vertex buffer object to update - /// - template - void UpdateVertexTexture(VERTEX_BUFFER *vbo, void *deviceContext = NULL) { - (void)(deviceContext); // unused parameter - if (vbo) - updateVertexTexture(vbo->BindVBO()); - } - - /// Returns the GL texture buffer containing the patch control vertices array - GLuint GetPatchIndexBuffer() const { - return _patchIndexBuffer; - } - - /// Returns the GL texture buffer containing the patch local parameterization - /// data - GLuint GetPatchParamTextureBuffer() const { - return _patchParamTextureBuffer; - } - - /// Returns the GL texture buffer containing the vertex data - GLuint GetVertexTextureBuffer() const { - return _vertexTextureBuffer; - } - - /// Returns the GL texture buffer containing patch vertex valence data (only - /// used by Gregory patches) - GLuint GetVertexValenceTextureBuffer() const { - return _vertexValenceTextureBuffer; - } - - /// Returns the GL texture buffer containing patch quad offsets data (only - /// used by Gregory patches) - GLuint GetQuadOffsetsTextureBuffer() const { - return _quadOffsetsTextureBuffer; - } - - /// Returns the GL texture buffer containing fvar data - GLuint GetFvarDataTextureBuffer() const { - return _fvarDataTextureBuffer; - } - - /// Sets face-varying data buffer - /// - /// @param patchTables A valid set of Far::PatchTables - /// - /// @param fvarWidth Total face-varying primvar data width in fvarData - /// - /// @param fvarData Vector containing the face-varying data - /// - /// @param deviceContext (not used) - /// - /// @return True if the operation was successful - /// - bool SetFVarDataTexture(Far::PatchTables const & patchTables, - int fvarWidth, FVarData const & fvarData, - void *deviceContext = NULL); - -protected: - GLuint _patchIndexBuffer; - - GLuint _patchParamTextureBuffer; - GLuint _fvarDataTextureBuffer; - - GLuint _vertexTextureBuffer; - GLuint _vertexValenceTextureBuffer; - GLuint _quadOffsetsTextureBuffer; - - GLDrawContext(int maxValence); - - // allocate buffers from patchTables - bool create(Far::PatchTables const & patchTables); - - void updateVertexTexture(GLuint vbo); -}; - -} // end namespace Osd - -} // end namespace OPENSUBDIV_VERSION -using namespace OPENSUBDIV_VERSION; - -} // end namespace OpenSubdiv - -#endif /* OPENSUBDIV3_OSD_DRAW_CONTEXT_H */ diff --git a/opensubdiv/osd/glLegacyGregoryPatchTable.cpp b/opensubdiv/osd/glLegacyGregoryPatchTable.cpp new file mode 100644 index 00000000..6e139fa3 --- /dev/null +++ b/opensubdiv/osd/glLegacyGregoryPatchTable.cpp @@ -0,0 +1,106 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#include "../osd/glLegacyGregoryPatchTable.h" + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Osd { + +GLLegacyGregoryPatchTable::GLLegacyGregoryPatchTable() : + _vertexTextureBuffer(0), _vertexValenceTextureBuffer(0), + _quadOffsetsTextureBuffer(0) { + _quadOffsetsBase[0] = _quadOffsetsBase[1] = 0; +} + +GLLegacyGregoryPatchTable::~GLLegacyGregoryPatchTable() { + if (_vertexTextureBuffer) + glDeleteTextures(1, &_vertexTextureBuffer); + if (_vertexValenceTextureBuffer) + glDeleteTextures(1, &_vertexValenceTextureBuffer); + if (_quadOffsetsTextureBuffer) + glDeleteTextures(1, &_quadOffsetsTextureBuffer); +} + +GLLegacyGregoryPatchTable * +GLLegacyGregoryPatchTable::Create(Far::PatchTables const *farPatchTables) { + + GLLegacyGregoryPatchTable *result = new GLLegacyGregoryPatchTable(); + glGenTextures(1, &result->_vertexTextureBuffer); + glGenTextures(1, &result->_vertexValenceTextureBuffer); + glGenTextures(1, &result->_quadOffsetsTextureBuffer); + + Far::PatchTables::VertexValenceTable const & + valenceTable = farPatchTables->GetVertexValenceTable(); + Far::PatchTables::QuadOffsetsTable const & + quadOffsetsTable = farPatchTables->GetQuadOffsetsTable(); + + GLuint buffers[2]; + glGenBuffers(2, buffers); + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glBufferData(GL_ARRAY_BUFFER, valenceTable.size() * sizeof(int), + &valenceTable[0], GL_STATIC_DRAW); + + glBindTexture(GL_TEXTURE_BUFFER, result->_vertexValenceTextureBuffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffers[0]); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, buffers[1]); + glBufferData(GL_ARRAY_BUFFER, quadOffsetsTable.size() * sizeof(int), + &quadOffsetsTable[0], GL_STATIC_DRAW); + + glBindTexture(GL_TEXTURE_BUFFER, result->_quadOffsetsTextureBuffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffers[1]); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glDeleteBuffers(2, buffers); + + result->_quadOffsetsBase[0] = 0; + result->_quadOffsetsBase[1] = 0; + // scan patchtable to find quadOffsetsBase. + for (int i = 0; i < farPatchTables->GetNumPatchArrays(); ++i) { + // GREGORY_BOUNDARY's quadoffsets come after GREGORY's. + if (farPatchTables->GetPatchArrayDescriptor(i) == + Far::PatchDescriptor::GREGORY) { + result->_quadOffsetsBase[1] = farPatchTables->GetNumPatches(i) * 4; + break; + } + } + return result; +} + +void +GLLegacyGregoryPatchTable::UpdateVertexBuffer(GLuint vbo) { + glBindTexture(GL_TEXTURE_BUFFER, _vertexTextureBuffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, vbo); + glBindTexture(GL_TEXTURE_BUFFER, 0); +} + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +} // end namespace OpenSubdiv diff --git a/opensubdiv/osd/glLegacyGregoryPatchTable.h b/opensubdiv/osd/glLegacyGregoryPatchTable.h new file mode 100644 index 00000000..221f6667 --- /dev/null +++ b/opensubdiv/osd/glLegacyGregoryPatchTable.h @@ -0,0 +1,86 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#ifndef OPENSUBDIV3_OSD_GL_LEGACY_GREGORY_PATCH_TABLE_H +#define OPENSUBDIV3_OSD_GL_LEGACY_GREGORY_PATCH_TABLE_H + +#include "../version.h" + +#include "../far/patchTables.h" +#include "../osd/nonCopyable.h" +#include "../osd/opengl.h" + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Osd { + +class GLLegacyGregoryPatchTable + : private NonCopyable { +public: + ~GLLegacyGregoryPatchTable(); + + static GLLegacyGregoryPatchTable *Create(Far::PatchTables const *patchTable); + + void UpdateVertexBuffer(GLuint vbo); + + GLuint GetVertexTextureBuffer() const { + return _vertexTextureBuffer; + } + + GLuint GetVertexValenceTextureBuffer() const { + return _vertexValenceTextureBuffer; + } + + GLuint GetQuadOffsetsTextureBuffer() const { + return _quadOffsetsTextureBuffer; + } + + GLuint GetQuadOffsetsBase(Far::PatchDescriptor::Type type) { + if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) { + return _quadOffsetsBase[1]; + } + return _quadOffsetsBase[0]; + } + +protected: + GLLegacyGregoryPatchTable(); + +private: + GLuint _vertexTextureBuffer; + GLuint _vertexValenceTextureBuffer; + GLuint _quadOffsetsTextureBuffer; + GLuint _quadOffsetsBase[2]; // gregory, boundaryGregory +}; + + + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +using namespace OPENSUBDIV_VERSION; + +} // end namespace OpenSubdiv + +#endif // OPENSUBDIV3_OSD_GL_LEGACY_GREGORY_PATCH_TABLE_H diff --git a/opensubdiv/osd/glMesh.h b/opensubdiv/osd/glMesh.h index cdb6667f..3237e353 100644 --- a/opensubdiv/osd/glMesh.h +++ b/opensubdiv/osd/glMesh.h @@ -28,14 +28,15 @@ #include "../version.h" #include "../osd/mesh.h" -#include "../osd/glDrawContext.h" +#include "../osd/glPatchTable.h" namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Osd { -typedef MeshInterface GLMeshInterface; +typedef MeshInterface GLMeshInterface; + } // end namespace Osd diff --git a/opensubdiv/osd/glPatchTable.cpp b/opensubdiv/osd/glPatchTable.cpp new file mode 100644 index 00000000..27f12ce2 --- /dev/null +++ b/opensubdiv/osd/glPatchTable.cpp @@ -0,0 +1,141 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#include "../osd/glPatchTable.h" + +#include "../far/patchTables.h" +#include "../osd/opengl.h" + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Osd { + +GLPatchTable::GLPatchTable() : + _indexBuffer(0), _patchParamTexture(0) { +} + +GLPatchTable::~GLPatchTable() { + if (_indexBuffer) glDeleteBuffers(1, &_indexBuffer); + if (_patchParamTexture) glDeleteTextures(1, &_patchParamTexture); +} + +GLPatchTable * +GLPatchTable::Create(Far::PatchTables const *farPatchTables, + void * /*deviceContext*/) { + GLPatchTable *instance = new GLPatchTable(); + if (instance->allocate(farPatchTables)) return instance; + delete instance; + return 0; +} + +bool +GLPatchTable::allocate(Far::PatchTables const *farPatchTables) { + glGenBuffers(1, &_indexBuffer); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); + std::vector buffer; + std::vector ppBuffer; + + // needs reserve? + + int nPatchArrays = farPatchTables->GetNumPatchArrays(); + + // for each patchArray + for (int j = 0; j < nPatchArrays; ++j) { + PatchArray patchArray(farPatchTables->GetPatchArrayDescriptor(j), + farPatchTables->GetNumPatches(j), + (int)buffer.size(), + (int)ppBuffer.size()/3); + _patchArrays.push_back(patchArray); + + // indices + Far::ConstIndexArray indices = farPatchTables->GetPatchArrayVertices(j); + for (int k = 0; k < indices.size(); ++k) { + buffer.push_back(indices[k]); + } + + // patchParams +#if 0 + // XXX: we need sharpness interface for patcharray or put sharpness + // into patchParam. + Far::ConstPatchParamArray patchParams = + farPatchTables->GetPatchParams(j); + for (int k = 0; k < patchParams.size(); ++k) { + float sharpness = 0.0; + ppBuffer.push_back(patchParams[k].faceIndex); + ppBuffer.push_back(patchParams[k].bitField.field); + ppBuffer.push_back(*((unsigned int *)&sharpness)); + } +#else + // XXX: workaround. GetPatchParamTable() will be deprecated though. + Far::PatchParamTable const & patchParamTables = + farPatchTables->GetPatchParamTable(); + std::vector const &sharpnessIndexTable = + farPatchTables->GetSharpnessIndexTable(); + int numPatches = farPatchTables->GetNumPatches(j); + for (int k = 0; k < numPatches; ++k) { + float sharpness = 0.0; + int patchIndex = (int)ppBuffer.size()/3; + if (patchIndex < (int)sharpnessIndexTable.size()) { + int sharpnessIndex = sharpnessIndexTable[patchIndex]; + if (sharpnessIndex >= 0) + sharpness = farPatchTables->GetSharpnessValues()[sharpnessIndex]; + } + ppBuffer.push_back(patchParamTables[patchIndex].faceIndex); + ppBuffer.push_back(patchParamTables[patchIndex].bitField.field); + ppBuffer.push_back(*((unsigned int *)&sharpness)); + } +#endif + } + + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + (int)buffer.size()*sizeof(int), &buffer[0], GL_STATIC_DRAW); + + // patchParam is currently expected to be texture (it can be SSBO) + GLuint texBuffer = 0; + glGenBuffers(1, &texBuffer); + glBindBuffer(GL_ARRAY_BUFFER, texBuffer); + glBufferData(GL_ARRAY_BUFFER, ppBuffer.size()*sizeof(unsigned int), + &ppBuffer[0], GL_STATIC_DRAW); + + glGenTextures(1, &_patchParamTexture); + glBindTexture(GL_TEXTURE_BUFFER, _patchParamTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32I, texBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glDeleteBuffers(1, &texBuffer); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + return true; +} + + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +} // end namespace OpenSubdiv + diff --git a/opensubdiv/osd/glPatchTable.h b/opensubdiv/osd/glPatchTable.h new file mode 100644 index 00000000..43656ca8 --- /dev/null +++ b/opensubdiv/osd/glPatchTable.h @@ -0,0 +1,112 @@ +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#ifndef OPENSUBDIV3_OSD_GL_PATCH_TABLE_H +#define OPENSUBDIV3_OSD_GL_PATCH_TABLE_H + +#include "../version.h" + +#include +#include "../far/patchDescriptor.h" +#include "../osd/nonCopyable.h" +#include "../osd/opengl.h" + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Far{ + class PatchTables; +}; + +namespace Osd { + +class GLPatchTable : private NonCopyable { +public: + typedef GLuint VertexBufferBinding; + + // XXX: this struct will be further refactored. + class PatchArray { + public: + PatchArray(Far::PatchDescriptor desc, int numPatches, + int indexBase, int primitiveIdBase) : + desc(desc), numPatches(numPatches), indexBase(indexBase), + primitiveIdBase(primitiveIdBase) {} + Far::PatchDescriptor const &GetDescriptor() const { + return desc; + } + int GetNumPatches() const { + return numPatches; + } + int GetIndexBase() const { + return indexBase; + } + int GetPrimitiveIdBase() const { + return primitiveIdBase; + } + private: + Far::PatchDescriptor desc; + int numPatches; + int indexBase; // an offset within the index buffer + int primitiveIdBase; // an offset within the patch param buffer + }; + typedef std::vector PatchArrayVector; + + GLPatchTable(); + ~GLPatchTable(); + + static GLPatchTable *Create(Far::PatchTables const *farPatchTables, + void *deviceContext = NULL); + + PatchArrayVector const &GetPatchArrays() const { + return _patchArrays; + } + + /// Returns the GL index buffer containing the patch control vertices + GLuint GetPatchIndexBuffer() const { + return _indexBuffer; + } + + /// Returns the GL texture buffer containing the patch parameter + GLuint GetPatchParamTextureBuffer() const { + return _patchParamTexture; + } + +protected: + // allocate buffers from patchTables + bool allocate(Far::PatchTables const *farPatchTables); + + PatchArrayVector _patchArrays; + GLuint _indexBuffer; + GLuint _patchParamTexture; +}; + + +} // end namespace Osd + +} // end namespace OPENSUBDIV_VERSION +using namespace OPENSUBDIV_VERSION; + +} // end namespace OpenSubdiv + +#endif // OPENSUBDIV3_OSD_GL_PATCH_TABLE_H diff --git a/opensubdiv/osd/hlslPatchCommon.hlsl b/opensubdiv/osd/hlslPatchCommon.hlsl index 1cfb255a..cda8b4d3 100644 --- a/opensubdiv/osd/hlslPatchCommon.hlsl +++ b/opensubdiv/osd/hlslPatchCommon.hlsl @@ -127,9 +127,9 @@ int OsdPrimitiveIdBase(); // #if defined OSD_PATCH_ENABLE_SINGLE_CREASE - Buffer OsdPatchParamBuffer : register( t3 ); + Buffer OsdPatchParamBuffer : register( t0 ); #else - Buffer OsdPatchParamBuffer : register( t3 ); + Buffer OsdPatchParamBuffer : register( t0 ); #endif int OsdGetPatchIndex(int primitiveId) diff --git a/opensubdiv/osd/hlslPatchGregory.hlsl b/opensubdiv/osd/hlslPatchGregory.hlsl index ac322ef9..657bcd1d 100644 --- a/opensubdiv/osd/hlslPatchGregory.hlsl +++ b/opensubdiv/osd/hlslPatchGregory.hlsl @@ -64,8 +64,8 @@ float sinfn(uint n, uint j) { // Patches.TessVertexGregory //---------------------------------------------------------- -Buffer VertexBuffer : register( t0 ); -Buffer OsdValenceBuffer : register( t1 ); +Buffer VertexBuffer : register( t2 ); +Buffer OsdValenceBuffer : register( t3 ); void vs_main_patches( in InputVertex input, uint vID : SV_VertexID, @@ -260,7 +260,7 @@ void vs_main_patches( in InputVertex input, // Patches.HullGregory //---------------------------------------------------------- -Buffer OsdQuadOffsetBuffer : register( t2 ); +Buffer OsdQuadOffsetBuffer : register( t4 ); HS_CONSTANT_FUNC_OUT HSConstFunc( InputPatch patch, diff --git a/opensubdiv/osd/mesh.h b/opensubdiv/osd/mesh.h index d9da0079..107b1f98 100644 --- a/opensubdiv/osd/mesh.h +++ b/opensubdiv/osd/mesh.h @@ -60,11 +60,11 @@ typedef std::bitset MeshBitset; // --------------------------------------------------------------------------- -template +template class MeshInterface { public: - typedef DRAW_CONTEXT DrawContext; - typedef typename DrawContext::VertexBufferBinding VertexBufferBinding; + typedef PATCH_TABLE PatchTable; + typedef typename PatchTable::VertexBufferBinding VertexBufferBinding; public: MeshInterface() { } @@ -73,6 +73,8 @@ public: virtual int GetNumVertices() const = 0; + virtual int GetMaxValence() const = 0; + virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts) = 0; @@ -83,15 +85,14 @@ public: virtual void Synchronize() = 0; - virtual DrawContext * GetDrawContext() = 0; + virtual PatchTable * GetPatchTable() const = 0; + + virtual Far::PatchTables const *GetFarPatchTables() const = 0; virtual VertexBufferBinding BindVertexBuffer() = 0; virtual VertexBufferBinding BindVaryingBuffer() = 0; - virtual void SetFVarDataChannel(int fvarWidth, - std::vector const & fvarData) = 0; - protected: static inline void refineMesh(Far::TopologyRefiner & refiner, int level, bool adaptive, @@ -232,17 +233,17 @@ static EVALUATOR *GetEvaluator( template -class Mesh : public MeshInterface { +class Mesh : public MeshInterface { public: typedef VERTEX_BUFFER VertexBuffer; typedef EVALUATOR Evaluator; typedef STENCIL_TABLES StencilTables; - typedef DRAW_CONTEXT DrawContext; + typedef PATCH_TABLE PatchTable; typedef DEVICE_CONTEXT DeviceContext; typedef EvaluatorCacheT EvaluatorCache; - typedef typename DrawContext::VertexBufferBinding VertexBufferBinding; + typedef typename PatchTable::VertexBufferBinding VertexBufferBinding; Mesh(Far::TopologyRefiner * refiner, int numVertexElements, @@ -253,19 +254,20 @@ public: DeviceContext * deviceContext = NULL) : _refiner(refiner), - _patchTables(NULL), + _farPatchTables(NULL), _numVertices(0), + _maxValence(0), _vertexBuffer(NULL), _varyingBuffer(NULL), _vertexStencilTables(NULL), _varyingStencilTables(NULL), _evaluatorCache(evaluatorCache), - _drawContext(NULL), + _patchTable(NULL), _deviceContext(deviceContext) { assert(_refiner); - MeshInterface::refineMesh( + MeshInterface::refineMesh( *_refiner, level, bits.test(MeshAdaptive), bits.test(MeshUseSingleCreasePatch)); @@ -296,21 +298,16 @@ public: numVaryingElements, varyingBufferStride); } - - - - // will retire - _drawContext->UpdateVertexTexture(_vertexBuffer, _deviceContext); } virtual ~Mesh() { delete _refiner; - delete _patchTables; + delete _farPatchTables; delete _vertexBuffer; delete _varyingBuffer; delete _vertexStencilTables; delete _varyingStencilTables; - delete _drawContext; + delete _patchTable; // deviceContext and evaluatorCache are not owned by this class. } @@ -373,23 +370,18 @@ public: Evaluator::Synchronize(_deviceContext); } - virtual DrawContext * GetDrawContext() { - return _drawContext; + virtual PatchTable * GetPatchTable() const { + return _patchTable; } - virtual void SetFVarDataChannel(int fvarWidth, - std::vector const & fvarData) { - if (_patchTables and - _drawContext and - fvarWidth and - (not fvarData.empty())) { - _drawContext->SetFVarDataTexture(*_patchTables, fvarWidth, fvarData, - _deviceContext); - } + virtual Far::PatchTables const *GetFarPatchTables() const { + return _farPatchTables; } virtual int GetNumVertices() const { return _numVertices; } + virtual int GetMaxValence() const { return _maxValence; } + virtual VertexBufferBinding BindVertexBuffer() { return _vertexBuffer->BindVBO(_deviceContext); } @@ -457,16 +449,16 @@ private: Far::PatchTablesFactory::Options::ENDCAP_LEGACY_GREGORY); } - _patchTables = Far::PatchTablesFactory::Create(*_refiner, poptions); + _farPatchTables = Far::PatchTablesFactory::Create(*_refiner, poptions); // if there's endcap stencils, merge it into regular stencils. - if (_patchTables->GetEndCapVertexStencilTables()) { + if (_farPatchTables->GetEndCapVertexStencilTables()) { // append stencils if (Far::StencilTables const *vertexStencilsWithEndCap = Far::StencilTablesFactory::AppendEndCapStencilTables( *_refiner, vertexStencils, - _patchTables->GetEndCapVertexStencilTables())) { + _farPatchTables->GetEndCapVertexStencilTables())) { delete vertexStencils; vertexStencils = vertexStencilsWithEndCap; } @@ -475,14 +467,15 @@ private: Far::StencilTablesFactory::AppendEndCapStencilTables( *_refiner, varyingStencils, - _patchTables->GetEndCapVaryingStencilTables())) { + _farPatchTables->GetEndCapVaryingStencilTables())) { delete varyingStencils; varyingStencils = varyingStencilsWithEndCap; } } } - _drawContext = DrawContext::Create(_patchTables, _deviceContext); + _maxValence = _farPatchTables->GetMaxValence(); + _patchTable = PatchTable::Create(_farPatchTables, _deviceContext); // numvertices = coarse verts + refined verts + gregory basis verts _numVertices = vertexStencils->GetNumControlVertices() @@ -517,9 +510,10 @@ private: } Far::TopologyRefiner * _refiner; - Far::PatchTables * _patchTables; + Far::PatchTables * _farPatchTables; int _numVertices; + int _maxValence; VertexBuffer * _vertexBuffer; VertexBuffer * _varyingBuffer; @@ -531,7 +525,7 @@ private: StencilTables const * _varyingStencilTables; EvaluatorCache * _evaluatorCache; - DrawContext *_drawContext; + PatchTable *_patchTable; DeviceContext *_deviceContext; };