Update to 2026-09-17 pipeline snapshot; add weights, L20 assets and recording via Git LFS

Source: RGB-D -> Dyn-HaMR -> L20 retargeting -> FoundationPose -> reference repair -> SPIDER,
documented in docs/PIPELINE_LATEST.md and docs/SETUP_AND_WEIGHTS.md. Adds FoundationPose and
nvdiffrast upstream snapshots, requirements/pipeline_venv.txt and the FoundationPose weight
manifest/downloader.

Assets (Git LFS): weights/ (WiLoR detector, HandFlow denoiser, UniDepth-L), FoundationPose
checkpoints, HaMeR checkpoint, Dyn-HaMR HMP model and BMC constraints, L20 URDF/meshes, the
20260915_171525 D405 recording and the two box CADs. MANO models are not redistributed
(third_party/hamer/_DATA/data/mano/README.txt). Environments, caches and run outputs excluded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
liyang
2026-09-17 11:27:46 +08:00
parent 7e4ef6f98b
commit ae28d55f81
761 changed files with 55598 additions and 59 deletions
@@ -0,0 +1,94 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#include "../../framework.h"
#include "Buffer.hpp"
using namespace CR;
//------------------------------------------------------------------------
// GPU buffer.
//------------------------------------------------------------------------
Buffer::Buffer(void)
: m_gpuPtr(NULL),
m_bytes (0)
{
// empty
}
Buffer::~Buffer(void)
{
if (m_gpuPtr)
cudaFree(m_gpuPtr); // Don't throw an exception.
}
void Buffer::reset(size_t bytes)
{
if (bytes == m_bytes)
return;
if (m_gpuPtr)
{
NVDR_CHECK_CUDA_ERROR(cudaFree(m_gpuPtr));
m_gpuPtr = NULL;
}
if (bytes > 0)
NVDR_CHECK_CUDA_ERROR(cudaMalloc(&m_gpuPtr, bytes));
m_bytes = bytes;
}
void Buffer::grow(size_t bytes)
{
if (bytes > m_bytes)
reset(bytes);
}
//------------------------------------------------------------------------
// Host buffer with page-locked memory.
//------------------------------------------------------------------------
HostBuffer::HostBuffer(void)
: m_hostPtr(NULL),
m_bytes (0)
{
// empty
}
HostBuffer::~HostBuffer(void)
{
if (m_hostPtr)
cudaFreeHost(m_hostPtr); // Don't throw an exception.
}
void HostBuffer::reset(size_t bytes)
{
if (bytes == m_bytes)
return;
if (m_hostPtr)
{
NVDR_CHECK_CUDA_ERROR(cudaFreeHost(m_hostPtr));
m_hostPtr = NULL;
}
if (bytes > 0)
NVDR_CHECK_CUDA_ERROR(cudaMallocHost(&m_hostPtr, bytes));
m_bytes = bytes;
}
void HostBuffer::grow(size_t bytes)
{
if (bytes > m_bytes)
reset(bytes);
}
//------------------------------------------------------------------------
@@ -0,0 +1,55 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#pragma once
#include "Defs.hpp"
namespace CR
{
//------------------------------------------------------------------------
class Buffer
{
public:
Buffer (void);
~Buffer (void);
void reset (size_t bytes);
void grow (size_t bytes);
void* getPtr (size_t offset = 0) { return (void*)(((uintptr_t)m_gpuPtr) + offset); }
size_t getSize (void) const { return m_bytes; }
void setPtr (void* ptr) { m_gpuPtr = ptr; }
private:
void* m_gpuPtr;
size_t m_bytes;
};
//------------------------------------------------------------------------
class HostBuffer
{
public:
HostBuffer (void);
~HostBuffer (void);
void reset (size_t bytes);
void grow (size_t bytes);
void* getPtr (void) { return m_hostPtr; }
size_t getSize (void) const { return m_bytes; }
void setPtr (void* ptr) { m_hostPtr = ptr; }
private:
void* m_hostPtr;
size_t m_bytes;
};
//------------------------------------------------------------------------
}
@@ -0,0 +1,73 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#pragma once
//------------------------------------------------------------------------
#define CR_MAXVIEWPORT_LOG2 11 // ViewportSize / PixelSize.
#define CR_SUBPIXEL_LOG2 4 // PixelSize / SubpixelSize.
#define CR_MAXBINS_LOG2 4 // ViewportSize / BinSize.
#define CR_BIN_LOG2 4 // BinSize / TileSize.
#define CR_TILE_LOG2 3 // TileSize / PixelSize.
#define CR_COVER8X8_LUT_SIZE 768 // 64-bit entries.
#define CR_FLIPBIT_FLIP_Y 2
#define CR_FLIPBIT_FLIP_X 3
#define CR_FLIPBIT_SWAP_XY 4
#define CR_FLIPBIT_COMPL 5
#define CR_BIN_STREAMS_LOG2 4
#define CR_BIN_SEG_LOG2 9 // 32-bit entries.
#define CR_TILE_SEG_LOG2 5 // 32-bit entries.
#define CR_MAXSUBTRIS_LOG2 24 // Triangle structs. Dictated by CoarseRaster.
#define CR_COARSE_QUEUE_LOG2 10 // Triangles.
#define CR_SETUP_WARPS 2
#define CR_SETUP_OPT_BLOCKS 8
#define CR_BIN_WARPS 16
#define CR_COARSE_WARPS 16 // Must be a power of two.
#define CR_FINE_MAX_WARPS 20
#define CR_EMBED_IMAGE_PARAMS 32 // Number of per-image parameter structs embedded in kernel launch parameter block.
//------------------------------------------------------------------------
#define CR_MAXVIEWPORT_SIZE (1 << CR_MAXVIEWPORT_LOG2)
#define CR_SUBPIXEL_SIZE (1 << CR_SUBPIXEL_LOG2)
#define CR_SUBPIXEL_SQR (1 << (CR_SUBPIXEL_LOG2 * 2))
#define CR_MAXBINS_SIZE (1 << CR_MAXBINS_LOG2)
#define CR_MAXBINS_SQR (1 << (CR_MAXBINS_LOG2 * 2))
#define CR_BIN_SIZE (1 << CR_BIN_LOG2)
#define CR_BIN_SQR (1 << (CR_BIN_LOG2 * 2))
#define CR_MAXTILES_LOG2 (CR_MAXBINS_LOG2 + CR_BIN_LOG2)
#define CR_MAXTILES_SIZE (1 << CR_MAXTILES_LOG2)
#define CR_MAXTILES_SQR (1 << (CR_MAXTILES_LOG2 * 2))
#define CR_TILE_SIZE (1 << CR_TILE_LOG2)
#define CR_TILE_SQR (1 << (CR_TILE_LOG2 * 2))
#define CR_BIN_STREAMS_SIZE (1 << CR_BIN_STREAMS_LOG2)
#define CR_BIN_SEG_SIZE (1 << CR_BIN_SEG_LOG2)
#define CR_TILE_SEG_SIZE (1 << CR_TILE_SEG_LOG2)
#define CR_MAXSUBTRIS_SIZE (1 << CR_MAXSUBTRIS_LOG2)
#define CR_COARSE_QUEUE_SIZE (1 << CR_COARSE_QUEUE_LOG2)
//------------------------------------------------------------------------
// When evaluating interpolated Z pixel centers, we may introduce an error
// of (+-CR_LERP_ERROR) ULPs.
#define CR_LERP_ERROR(SAMPLES_LOG2) (2200u << (SAMPLES_LOG2))
#define CR_DEPTH_MIN CR_LERP_ERROR(3)
#define CR_DEPTH_MAX (CR_U32_MAX - CR_LERP_ERROR(3))
//------------------------------------------------------------------------
@@ -0,0 +1,79 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#include "Defs.hpp"
#include "../CudaRaster.hpp"
#include "RasterImpl.hpp"
using namespace CR;
//------------------------------------------------------------------------
// Stub interface implementation.
//------------------------------------------------------------------------
CudaRaster::CudaRaster()
{
m_impl = new RasterImpl();
}
CudaRaster::~CudaRaster()
{
delete m_impl;
}
void CudaRaster::setBufferSize(int width, int height, int numImages)
{
m_impl->setBufferSize(Vec3i(width, height, numImages));
}
void CudaRaster::setViewport(int width, int height, int offsetX, int offsetY)
{
m_impl->setViewport(Vec2i(width, height), Vec2i(offsetX, offsetY));
}
void CudaRaster::setRenderModeFlags(U32 flags)
{
m_impl->setRenderModeFlags(flags);
}
void CudaRaster::deferredClear(U32 clearColor)
{
m_impl->deferredClear(clearColor);
}
void CudaRaster::setVertexBuffer(void* vertices, int numVertices)
{
m_impl->setVertexBuffer(vertices, numVertices);
}
void CudaRaster::setIndexBuffer(void* indices, int numTriangles)
{
m_impl->setIndexBuffer(indices, numTriangles);
}
bool CudaRaster::drawTriangles(const int* ranges, bool peel, cudaStream_t stream)
{
return m_impl->drawTriangles((const Vec2i*)ranges, peel, stream);
}
void* CudaRaster::getColorBuffer(void)
{
return m_impl->getColorBuffer();
}
void* CudaRaster::getDepthBuffer(void)
{
return m_impl->getDepthBuffer();
}
void CudaRaster::swapDepthAndPeel(void)
{
m_impl->swapDepthAndPeel();
}
//------------------------------------------------------------------------
@@ -0,0 +1,90 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#pragma once
#include <cuda_runtime.h>
#include <cstdint>
namespace CR
{
//------------------------------------------------------------------------
#ifndef NULL
# define NULL 0
#endif
#ifdef __CUDACC__
# define CR_CUDA 1
#else
# define CR_CUDA 0
#endif
#if CR_CUDA
# define CR_CUDA_FUNC __device__ __inline__
# define CR_CUDA_CONST __constant__
#else
# define CR_CUDA_FUNC inline
# define CR_CUDA_CONST static const
#endif
#define CR_UNREF(X) ((void)(X))
#define CR_ARRAY_SIZE(X) ((int)(sizeof(X) / sizeof((X)[0])))
//------------------------------------------------------------------------
typedef uint8_t U8;
typedef uint16_t U16;
typedef uint32_t U32;
typedef uint64_t U64;
typedef int8_t S8;
typedef int16_t S16;
typedef int32_t S32;
typedef int64_t S64;
typedef float F32;
typedef double F64;
typedef void (*FuncPtr)(void);
//------------------------------------------------------------------------
#define CR_U32_MAX (0xFFFFFFFFu)
#define CR_S32_MIN (~0x7FFFFFFF)
#define CR_S32_MAX (0x7FFFFFFF)
#define CR_U64_MAX ((U64)(S64)-1)
#define CR_S64_MIN ((S64)-1 << 63)
#define CR_S64_MAX (~((S64)-1 << 63))
#define CR_F32_MIN (1.175494351e-38f)
#define CR_F32_MAX (3.402823466e+38f)
#define CR_F64_MIN (2.2250738585072014e-308)
#define CR_F64_MAX (1.7976931348623158e+308)
//------------------------------------------------------------------------
// Misc types.
class Vec2i
{
public:
Vec2i(int x_, int y_) : x(x_), y(y_) {}
int x, y;
};
class Vec3i
{
public:
Vec3i(int x_, int y_, int z_) : x(x_), y(y_), z(z_) {}
int x, y, z;
};
//------------------------------------------------------------------------
// CUDA utilities.
#if CR_CUDA
# define globalThreadIdx (threadIdx.x + blockDim.x * (threadIdx.y + blockDim.y * (blockIdx.x + gridDim.x * blockIdx.y)))
#endif
//------------------------------------------------------------------------
} // namespace CR
@@ -0,0 +1,153 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#pragma once
#include "Defs.hpp"
#include "Constants.hpp"
namespace CR
{
//------------------------------------------------------------------------
// Projected triangle.
//------------------------------------------------------------------------
struct CRTriangleHeader
{
S16 v0x; // Subpixels relative to viewport center. Valid if triSubtris = 1.
S16 v0y;
S16 v1x;
S16 v1y;
S16 v2x;
S16 v2y;
U32 misc; // triSubtris=1: (zmin:20, f01:4, f12:4, f20:4), triSubtris>=2: (subtriBase)
};
//------------------------------------------------------------------------
struct CRTriangleData
{
U32 zx; // zx * sampleX + zy * sampleY + zb = lerp(CR_DEPTH_MIN, CR_DEPTH_MAX, (clipZ / clipW + 1) / 2)
U32 zy;
U32 zb;
U32 id; // Triangle id.
};
//------------------------------------------------------------------------
// Device-side structures.
//------------------------------------------------------------------------
struct CRAtomics
{
// Setup.
S32 numSubtris; // = numTris
// Bin.
S32 binCounter; // = 0
S32 numBinSegs; // = 0
// Coarse.
S32 coarseCounter; // = 0
S32 numTileSegs; // = 0
S32 numActiveTiles; // = 0
// Fine.
S32 fineCounter; // = 0
};
//------------------------------------------------------------------------
struct CRImageParams
{
S32 triOffset; // First triangle index to draw.
S32 triCount; // Number of triangles to draw.
S32 binBatchSize; // Number of triangles per batch.
};
//------------------------------------------------------------------------
struct CRParams
{
// Common.
CRAtomics* atomics; // Work counters. Per-image.
S32 numImages; // Batch size.
S32 totalCount; // In range mode, total number of triangles to render.
S32 instanceMode; // 0 = range mode, 1 = instance mode.
S32 numVertices; // Number of vertices in input buffer, not counting multiples in instance mode.
S32 numTriangles; // Number of triangles in input buffer.
void* vertexBuffer; // numVertices * float4(x, y, z, w)
void* indexBuffer; // numTriangles * int3(vi0, vi1, vi2)
S32 widthPixels; // Render buffer size in pixels. Must be multiple of tile size (8x8).
S32 heightPixels;
S32 widthPixelsVp; // Viewport size in pixels.
S32 heightPixelsVp;
S32 widthBins; // widthPixels / CR_BIN_SIZE
S32 heightBins; // heightPixels / CR_BIN_SIZE
S32 numBins; // widthBins * heightBins
F32 xs; // Vertex position adjustments for tiled rendering.
F32 ys;
F32 xo;
F32 yo;
S32 widthTiles; // widthPixels / CR_TILE_SIZE
S32 heightTiles; // heightPixels / CR_TILE_SIZE
S32 numTiles; // widthTiles * heightTiles
U32 renderModeFlags;
S32 deferredClear; // 1 = Clear framebuffer before rendering triangles.
U32 clearColor;
U32 clearDepth;
// These are uniform across batch.
S32 maxSubtris;
S32 maxBinSegs;
S32 maxTileSegs;
// Setup output / bin input.
void* triSubtris; // maxSubtris * U8
void* triHeader; // maxSubtris * CRTriangleHeader
void* triData; // maxSubtris * CRTriangleData
// Bin output / coarse input.
void* binSegData; // maxBinSegs * CR_BIN_SEG_SIZE * S32
void* binSegNext; // maxBinSegs * S32
void* binSegCount; // maxBinSegs * S32
void* binFirstSeg; // CR_MAXBINS_SQR * CR_BIN_STREAMS_SIZE * (S32 segIdx), -1 = none
void* binTotal; // CR_MAXBINS_SQR * CR_BIN_STREAMS_SIZE * (S32 numTris)
// Coarse output / fine input.
void* tileSegData; // maxTileSegs * CR_TILE_SEG_SIZE * S32
void* tileSegNext; // maxTileSegs * S32
void* tileSegCount; // maxTileSegs * S32
void* activeTiles; // CR_MAXTILES_SQR * (S32 tileIdx)
void* tileFirstSeg; // CR_MAXTILES_SQR * (S32 segIdx), -1 = none
// Surface buffers. Outer tile offset is baked into pointers.
void* colorBuffer; // sizePixels.x * sizePixels.y * numImages * U32
void* depthBuffer; // sizePixels.x * sizePixels.y * numImages * U32
void* peelBuffer; // sizePixels.x * sizePixels.y * numImages * U32, only if peeling enabled.
S32 strideX; // horizontal size in pixels
S32 strideY; // vertical stride in pixels
// Per-image parameters for first images are embedded here to avoid extra memcpy for small batches.
CRImageParams imageParamsFirst[CR_EMBED_IMAGE_PARAMS];
const CRImageParams* imageParamsExtra; // After CR_EMBED_IMAGE_PARAMS.
};
//------------------------------------------------------------------------
}
@@ -0,0 +1,370 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#include "../../framework.h"
#include "PrivateDefs.hpp"
#include "Constants.hpp"
#include "RasterImpl.hpp"
#include <cuda_runtime.h>
using namespace CR;
using std::min;
using std::max;
//------------------------------------------------------------------------
// Kernel prototypes and variables.
void triangleSetupKernel (const CRParams p);
void binRasterKernel (const CRParams p);
void coarseRasterKernel (const CRParams p);
void fineRasterKernel (const CRParams p);
//------------------------------------------------------------------------
RasterImpl::RasterImpl(void)
: m_renderModeFlags (0),
m_deferredClear (false),
m_clearColor (0),
m_vertexPtr (NULL),
m_indexPtr (NULL),
m_numVertices (0),
m_numTriangles (0),
m_bufferSizesReported (0),
m_numImages (0),
m_bufferSizePixels (0, 0),
m_bufferSizeVp (0, 0),
m_sizePixels (0, 0),
m_sizeVp (0, 0),
m_offsetPixels (0, 0),
m_sizeBins (0, 0),
m_numBins (0),
m_sizeTiles (0, 0),
m_numTiles (0),
m_numSMs (1),
m_numCoarseBlocksPerSM (1),
m_numFineBlocksPerSM (1),
m_numFineWarpsPerBlock (1),
m_maxSubtris (1),
m_maxBinSegs (1),
m_maxTileSegs (1)
{
// Query relevant device attributes.
int currentDevice = 0;
NVDR_CHECK_CUDA_ERROR(cudaGetDevice(&currentDevice));
NVDR_CHECK_CUDA_ERROR(cudaDeviceGetAttribute(&m_numSMs, cudaDevAttrMultiProcessorCount, currentDevice));
cudaFuncAttributes attr;
NVDR_CHECK_CUDA_ERROR(cudaFuncGetAttributes(&attr, (void*)fineRasterKernel));
m_numFineWarpsPerBlock = min(attr.maxThreadsPerBlock / 32, CR_FINE_MAX_WARPS);
NVDR_CHECK_CUDA_ERROR(cudaOccupancyMaxActiveBlocksPerMultiprocessor(&m_numCoarseBlocksPerSM, (void*)coarseRasterKernel, 32 * CR_COARSE_WARPS, 0));
NVDR_CHECK_CUDA_ERROR(cudaOccupancyMaxActiveBlocksPerMultiprocessor(&m_numFineBlocksPerSM, (void*)fineRasterKernel, 32 * m_numFineWarpsPerBlock, 0));
// Setup functions.
NVDR_CHECK_CUDA_ERROR(cudaFuncSetCacheConfig((void*)triangleSetupKernel, cudaFuncCachePreferShared));
NVDR_CHECK_CUDA_ERROR(cudaFuncSetCacheConfig((void*)binRasterKernel, cudaFuncCachePreferShared));
NVDR_CHECK_CUDA_ERROR(cudaFuncSetCacheConfig((void*)coarseRasterKernel, cudaFuncCachePreferShared));
NVDR_CHECK_CUDA_ERROR(cudaFuncSetCacheConfig((void*)fineRasterKernel, cudaFuncCachePreferShared));
}
//------------------------------------------------------------------------
RasterImpl::~RasterImpl(void)
{
// Empty.
}
//------------------------------------------------------------------------
void RasterImpl::setBufferSize(Vec3i size)
{
// Internal buffer width and height must be divisible by tile size.
int w = (size.x + CR_TILE_SIZE - 1) & (-CR_TILE_SIZE);
int h = (size.y + CR_TILE_SIZE - 1) & (-CR_TILE_SIZE);
m_bufferSizePixels = Vec2i(w, h);
m_bufferSizeVp = Vec2i(size.x, size.y);
m_numImages = size.z;
m_colorBuffer.reset(w * h * size.z * sizeof(U32));
m_depthBuffer.reset(w * h * size.z * sizeof(U32));
}
//------------------------------------------------------------------------
void RasterImpl::setViewport(Vec2i size, Vec2i offset)
{
// Offset must be divisible by tile size.
NVDR_CHECK((offset.x & (CR_TILE_SIZE - 1)) == 0 && (offset.y & (CR_TILE_SIZE - 1)) == 0, "invalid viewport offset");
// Round internal viewport size to multiples of tile size.
int w = (size.x + CR_TILE_SIZE - 1) & (-CR_TILE_SIZE);
int h = (size.y + CR_TILE_SIZE - 1) & (-CR_TILE_SIZE);
m_sizePixels = Vec2i(w, h);
m_offsetPixels = offset;
m_sizeVp = Vec2i(size.x, size.y);
m_sizeTiles.x = m_sizePixels.x >> CR_TILE_LOG2;
m_sizeTiles.y = m_sizePixels.y >> CR_TILE_LOG2;
m_numTiles = m_sizeTiles.x * m_sizeTiles.y;
m_sizeBins.x = (m_sizeTiles.x + CR_BIN_SIZE - 1) >> CR_BIN_LOG2;
m_sizeBins.y = (m_sizeTiles.y + CR_BIN_SIZE - 1) >> CR_BIN_LOG2;
m_numBins = m_sizeBins.x * m_sizeBins.y;
}
void RasterImpl::swapDepthAndPeel(void)
{
m_peelBuffer.reset(m_depthBuffer.getSize()); // Ensure equal size and valid pointer.
void* tmp = m_depthBuffer.getPtr();
m_depthBuffer.setPtr(m_peelBuffer.getPtr());
m_peelBuffer.setPtr(tmp);
}
//------------------------------------------------------------------------
bool RasterImpl::drawTriangles(const Vec2i* ranges, bool peel, cudaStream_t stream)
{
bool instanceMode = (!ranges);
int maxSubtrisSlack = 4096; // x 81B = 324KB
int maxBinSegsSlack = 256; // x 2137B = 534KB
int maxTileSegsSlack = 4096; // x 136B = 544KB
// Resize atomics as needed.
m_crAtomics .grow(m_numImages * sizeof(CRAtomics));
m_crAtomicsHost.grow(m_numImages * sizeof(CRAtomics));
// Size of these buffers doesn't depend on input.
m_binFirstSeg .grow(m_numImages * CR_MAXBINS_SQR * CR_BIN_STREAMS_SIZE * sizeof(S32));
m_binTotal .grow(m_numImages * CR_MAXBINS_SQR * CR_BIN_STREAMS_SIZE * sizeof(S32));
m_activeTiles .grow(m_numImages * CR_MAXTILES_SQR * sizeof(S32));
m_tileFirstSeg .grow(m_numImages * CR_MAXTILES_SQR * sizeof(S32));
// Construct per-image parameters and determine worst-case buffer sizes.
m_crImageParamsHost.grow(m_numImages * sizeof(CRImageParams));
CRImageParams* imageParams = (CRImageParams*)m_crImageParamsHost.getPtr();
for (int i=0; i < m_numImages; i++)
{
CRImageParams& ip = imageParams[i];
int roundSize = CR_BIN_WARPS * 32;
int minBatches = CR_BIN_STREAMS_SIZE * 2;
int maxRounds = 32;
ip.triOffset = instanceMode ? 0 : ranges[i].x;
ip.triCount = instanceMode ? m_numTriangles : ranges[i].y;
ip.binBatchSize = min(max(ip.triCount / (roundSize * minBatches), 1), maxRounds) * roundSize;
m_maxSubtris = max(m_maxSubtris, min(ip.triCount + maxSubtrisSlack, CR_MAXSUBTRIS_SIZE));
m_maxBinSegs = max(m_maxBinSegs, max(m_numBins * CR_BIN_STREAMS_SIZE, (ip.triCount - 1) / CR_BIN_SEG_SIZE + 1) + maxBinSegsSlack);
m_maxTileSegs = max(m_maxTileSegs, max(m_numTiles, (ip.triCount - 1) / CR_TILE_SEG_SIZE + 1) + maxTileSegsSlack);
}
// Retry until successful.
for (;;)
{
// Allocate buffers.
m_triSubtris.reset(m_numImages * m_maxSubtris * sizeof(U8));
m_triHeader .reset(m_numImages * m_maxSubtris * sizeof(CRTriangleHeader));
m_triData .reset(m_numImages * m_maxSubtris * sizeof(CRTriangleData));
m_binSegData .reset(m_numImages * m_maxBinSegs * CR_BIN_SEG_SIZE * sizeof(S32));
m_binSegNext .reset(m_numImages * m_maxBinSegs * sizeof(S32));
m_binSegCount.reset(m_numImages * m_maxBinSegs * sizeof(S32));
m_tileSegData .reset(m_numImages * m_maxTileSegs * CR_TILE_SEG_SIZE * sizeof(S32));
m_tileSegNext .reset(m_numImages * m_maxTileSegs * sizeof(S32));
m_tileSegCount.reset(m_numImages * m_maxTileSegs * sizeof(S32));
// Report if buffers grow from last time.
size_t sizesTotal = getTotalBufferSizes();
if (sizesTotal > m_bufferSizesReported)
{
size_t sizesMB = ((sizesTotal - 1) >> 20) + 1; // Round up.
sizesMB = ((sizesMB + 9) / 10) * 10; // 10MB granularity enough in this day and age.
LOG(INFO) << "Internal buffers grown to " << sizesMB << " MB";
m_bufferSizesReported = sizesMB << 20;
}
// Launch stages. Blocks until everything is done.
launchStages(instanceMode, peel, stream);
// Peeling iteration cannot fail, so no point checking things further.
if (peel)
break;
// Atomics after coarse stage are now available.
CRAtomics* atomics = (CRAtomics*)m_crAtomicsHost.getPtr();
// Success?
bool failed = false;
for (int i=0; i < m_numImages; i++)
{
const CRAtomics& a = atomics[i];
failed = failed || (a.numSubtris > m_maxSubtris) || (a.numBinSegs > m_maxBinSegs) || (a.numTileSegs > m_maxTileSegs);
}
if (!failed)
break; // Success!
// If we were already at maximum capacity, no can do.
if (m_maxSubtris == CR_MAXSUBTRIS_SIZE)
return false;
// Enlarge buffers and try again.
for (int i=0; i < m_numImages; i++)
{
const CRAtomics& a = atomics[i];
m_maxSubtris = max(m_maxSubtris, min(a.numSubtris + maxSubtrisSlack, CR_MAXSUBTRIS_SIZE));
m_maxBinSegs = max(m_maxBinSegs, a.numBinSegs + maxBinSegsSlack);
m_maxTileSegs = max(m_maxTileSegs, a.numTileSegs + maxTileSegsSlack);
}
}
m_deferredClear = false;
return true; // Success.
}
//------------------------------------------------------------------------
size_t RasterImpl::getTotalBufferSizes(void) const
{
return
m_colorBuffer.getSize() + m_depthBuffer.getSize() + // Don't include atomics and image params.
m_triSubtris.getSize() + m_triHeader.getSize() + m_triData.getSize() +
m_binFirstSeg.getSize() + m_binTotal.getSize() + m_binSegData.getSize() + m_binSegNext.getSize() + m_binSegCount.getSize() +
m_activeTiles.getSize() + m_tileFirstSeg.getSize() + m_tileSegData.getSize() + m_tileSegNext.getSize() + m_tileSegCount.getSize();
}
//------------------------------------------------------------------------
void RasterImpl::launchStages(bool instanceMode, bool peel, cudaStream_t stream)
{
CRImageParams* imageParams = (CRImageParams*)m_crImageParamsHost.getPtr();
// Unless peeling, initialize atomics to mostly zero.
CRAtomics* atomics = (CRAtomics*)m_crAtomicsHost.getPtr();
if (!peel)
{
memset(atomics, 0, m_numImages * sizeof(CRAtomics));
for (int i=0; i < m_numImages; i++)
atomics[i].numSubtris = imageParams[i].triCount;
}
// Copy to device. If peeling, this is the state after coarse raster launch on first iteration.
NVDR_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_crAtomics.getPtr(), atomics, m_numImages * sizeof(CRAtomics), cudaMemcpyHostToDevice, stream));
// Copy per-image parameters if there are more than fits in launch parameter block and we haven't done it already.
if (!peel && m_numImages > CR_EMBED_IMAGE_PARAMS)
{
int numImageParamsExtra = m_numImages - CR_EMBED_IMAGE_PARAMS;
m_crImageParamsExtra.grow(numImageParamsExtra * sizeof(CRImageParams));
NVDR_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_crImageParamsExtra.getPtr(), imageParams + CR_EMBED_IMAGE_PARAMS, numImageParamsExtra * sizeof(CRImageParams), cudaMemcpyHostToDevice, stream));
}
// Set global parameters.
CRParams p;
{
p.atomics = (CRAtomics*)m_crAtomics.getPtr();
p.numImages = m_numImages;
p.totalCount = 0; // Only relevant in range mode.
p.instanceMode = instanceMode ? 1 : 0;
p.numVertices = m_numVertices;
p.numTriangles = m_numTriangles;
p.vertexBuffer = m_vertexPtr;
p.indexBuffer = m_indexPtr;
p.widthPixels = m_sizePixels.x;
p.heightPixels = m_sizePixels.y;
p.widthPixelsVp = m_sizeVp.x;
p.heightPixelsVp = m_sizeVp.y;
p.widthBins = m_sizeBins.x;
p.heightBins = m_sizeBins.y;
p.numBins = m_numBins;
p.xs = (float)m_bufferSizeVp.x / (float)m_sizeVp.x;
p.ys = (float)m_bufferSizeVp.y / (float)m_sizeVp.y;
p.xo = (float)(m_bufferSizeVp.x - m_sizeVp.x - 2 * m_offsetPixels.x) / (float)m_sizeVp.x;
p.yo = (float)(m_bufferSizeVp.y - m_sizeVp.y - 2 * m_offsetPixels.y) / (float)m_sizeVp.y;
p.widthTiles = m_sizeTiles.x;
p.heightTiles = m_sizeTiles.y;
p.numTiles = m_numTiles;
p.renderModeFlags = m_renderModeFlags;
p.deferredClear = m_deferredClear ? 1 : 0;
p.clearColor = m_clearColor;
p.clearDepth = CR_DEPTH_MAX;
p.maxSubtris = m_maxSubtris;
p.maxBinSegs = m_maxBinSegs;
p.maxTileSegs = m_maxTileSegs;
p.triSubtris = m_triSubtris.getPtr();
p.triHeader = m_triHeader.getPtr();
p.triData = m_triData.getPtr();
p.binSegData = m_binSegData.getPtr();
p.binSegNext = m_binSegNext.getPtr();
p.binSegCount = m_binSegCount.getPtr();
p.binFirstSeg = m_binFirstSeg.getPtr();
p.binTotal = m_binTotal.getPtr();
p.tileSegData = m_tileSegData.getPtr();
p.tileSegNext = m_tileSegNext.getPtr();
p.tileSegCount = m_tileSegCount.getPtr();
p.activeTiles = m_activeTiles.getPtr();
p.tileFirstSeg = m_tileFirstSeg.getPtr();
size_t byteOffset = ((size_t)m_offsetPixels.x + (size_t)m_offsetPixels.y * (size_t)m_bufferSizePixels.x) * sizeof(U32);
p.colorBuffer = m_colorBuffer.getPtr(byteOffset);
p.depthBuffer = m_depthBuffer.getPtr(byteOffset);
p.peelBuffer = (m_renderModeFlags & CudaRaster::RenderModeFlag_EnableDepthPeeling) ? m_peelBuffer.getPtr(byteOffset) : 0;
p.strideX = m_bufferSizePixels.x;
p.strideY = m_bufferSizePixels.y;
memcpy(&p.imageParamsFirst, imageParams, min(m_numImages, CR_EMBED_IMAGE_PARAMS) * sizeof(CRImageParams));
p.imageParamsExtra = (CRImageParams*)m_crImageParamsExtra.getPtr();
}
// Setup block sizes.
dim3 brBlock(32, CR_BIN_WARPS);
dim3 crBlock(32, CR_COARSE_WARPS);
dim3 frBlock(32, m_numFineWarpsPerBlock);
void* args[] = {&p};
// Launch stages from setup to coarse and copy atomics to host only if this is not a single-tile peeling iteration.
if (!peel)
{
if (instanceMode)
{
int setupBlocks = (m_numTriangles - 1) / (32 * CR_SETUP_WARPS) + 1;
NVDR_CHECK_CUDA_ERROR(cudaLaunchKernel((void*)triangleSetupKernel, dim3(setupBlocks, 1, m_numImages), dim3(32, CR_SETUP_WARPS), args, 0, stream));
}
else
{
for (int i=0; i < m_numImages; i++)
p.totalCount += imageParams[i].triCount;
int setupBlocks = (p.totalCount - 1) / (32 * CR_SETUP_WARPS) + 1;
NVDR_CHECK_CUDA_ERROR(cudaLaunchKernel((void*)triangleSetupKernel, dim3(setupBlocks, 1, 1), dim3(32, CR_SETUP_WARPS), args, 0, stream));
}
NVDR_CHECK_CUDA_ERROR(cudaLaunchKernel((void*)binRasterKernel, dim3(CR_BIN_STREAMS_SIZE, 1, m_numImages), brBlock, args, 0, stream));
NVDR_CHECK_CUDA_ERROR(cudaLaunchKernel((void*)coarseRasterKernel, dim3(m_numSMs * m_numCoarseBlocksPerSM, 1, m_numImages), crBlock, args, 0, stream));
NVDR_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_crAtomicsHost.getPtr(), m_crAtomics.getPtr(), sizeof(CRAtomics) * m_numImages, cudaMemcpyDeviceToHost, stream));
}
// Fine rasterizer is launched always.
NVDR_CHECK_CUDA_ERROR(cudaLaunchKernel((void*)fineRasterKernel, dim3(m_numSMs * m_numFineBlocksPerSM, 1, m_numImages), frBlock, args, 0, stream));
NVDR_CHECK_CUDA_ERROR(cudaStreamSynchronize(stream));
}
//------------------------------------------------------------------------
@@ -0,0 +1,102 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#pragma once
#include "PrivateDefs.hpp"
#include "Buffer.hpp"
#include "../CudaRaster.hpp"
namespace CR
{
//------------------------------------------------------------------------
class RasterImpl
{
public:
RasterImpl (void);
~RasterImpl (void);
void setBufferSize (Vec3i size);
void setViewport (Vec2i size, Vec2i offset);
void setRenderModeFlags (U32 flags) { m_renderModeFlags = flags; }
void deferredClear (U32 color) { m_deferredClear = true; m_clearColor = color; }
void setVertexBuffer (void* ptr, int numVertices) { m_vertexPtr = ptr; m_numVertices = numVertices; } // GPU pointer.
void setIndexBuffer (void* ptr, int numTriangles) { m_indexPtr = ptr; m_numTriangles = numTriangles; } // GPU pointer.
bool drawTriangles (const Vec2i* ranges, bool peel, cudaStream_t stream);
void* getColorBuffer (void) { return m_colorBuffer.getPtr(); } // GPU pointer.
void* getDepthBuffer (void) { return m_depthBuffer.getPtr(); } // GPU pointer.
void swapDepthAndPeel (void);
size_t getTotalBufferSizes (void) const;
private:
void launchStages (bool instanceMode, bool peel, cudaStream_t stream);
// State.
unsigned int m_renderModeFlags;
bool m_deferredClear;
unsigned int m_clearColor;
void* m_vertexPtr;
void* m_indexPtr;
int m_numVertices; // Input buffer size.
int m_numTriangles; // Input buffer size.
size_t m_bufferSizesReported; // Previously reported buffer sizes.
// Surfaces.
Buffer m_colorBuffer;
Buffer m_depthBuffer;
Buffer m_peelBuffer;
int m_numImages;
Vec2i m_bufferSizePixels; // Internal buffer size.
Vec2i m_bufferSizeVp; // Total viewport size.
Vec2i m_sizePixels; // Internal size at which all computation is done, buffers reserved, etc.
Vec2i m_sizeVp; // Size to which output will be cropped outside, determines viewport size.
Vec2i m_offsetPixels; // Viewport offset for tiled rendering.
Vec2i m_sizeBins;
S32 m_numBins;
Vec2i m_sizeTiles;
S32 m_numTiles;
// Launch sizes etc.
S32 m_numSMs;
S32 m_numCoarseBlocksPerSM;
S32 m_numFineBlocksPerSM;
S32 m_numFineWarpsPerBlock;
// Global intermediate buffers. Individual images have offsets to these.
Buffer m_crAtomics;
HostBuffer m_crAtomicsHost;
HostBuffer m_crImageParamsHost;
Buffer m_crImageParamsExtra;
Buffer m_triSubtris;
Buffer m_triHeader;
Buffer m_triData;
Buffer m_binFirstSeg;
Buffer m_binTotal;
Buffer m_binSegData;
Buffer m_binSegNext;
Buffer m_binSegCount;
Buffer m_activeTiles;
Buffer m_tileFirstSeg;
Buffer m_tileSegData;
Buffer m_tileSegNext;
Buffer m_tileSegCount;
// Actual buffer sizes.
S32 m_maxSubtris;
S32 m_maxBinSegs;
S32 m_maxTileSegs;
};
//------------------------------------------------------------------------
} // namespace CR
@@ -0,0 +1,37 @@
// Copyright (c) 2009-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
#include "../CudaRaster.hpp"
#include "PrivateDefs.hpp"
#include "Constants.hpp"
#include "Util.inl"
namespace CR
{
//------------------------------------------------------------------------
// Stage implementations.
//------------------------------------------------------------------------
#include "TriangleSetup.inl"
#include "BinRaster.inl"
#include "CoarseRaster.inl"
#include "FineRaster.inl"
}
//------------------------------------------------------------------------
// Stage entry points.
//------------------------------------------------------------------------
__global__ void __launch_bounds__(CR_SETUP_WARPS * 32, CR_SETUP_OPT_BLOCKS) triangleSetupKernel (const CR::CRParams p) { CR::triangleSetupImpl(p); }
__global__ void __launch_bounds__(CR_BIN_WARPS * 32, 1) binRasterKernel (const CR::CRParams p) { CR::binRasterImpl(p); }
__global__ void __launch_bounds__(CR_COARSE_WARPS * 32, 1) coarseRasterKernel (const CR::CRParams p) { CR::coarseRasterImpl(p); }
__global__ void __launch_bounds__(CR_FINE_MAX_WARPS * 32, 1) fineRasterKernel (const CR::CRParams p) { CR::fineRasterImpl(p); }
//------------------------------------------------------------------------