// Copyright (c) 2021 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 <OgnPerturbPointsGpuDatabase.h>
#include <cstdlib>

namespace omni {
namespace graph {
namespace test {

extern "C" void applyPerturbGpu(outputs::points_t outputPoints,
                                inputs::points_t inputPoints,
                                inputs::minimum_t minimum,
                                inputs::maximum_t maximum,
                                inputs::percentModified_t percentModified,
                                size_t numberOfPoints);

// This is the implementation of the OGN node defined in OgnPerturbPointsGpu.ogn
class OgnPerturbPointsGpu
{
public:
    // Perturb an array of points by random amounts within the limits of the bounding cube formed by the diagonal
    // corners "minimum" and "maximum" using CUDA code on stolen GPU data.
    static bool compute(OgnPerturbPointsGpuDatabase& db)
    {
        // No points mean nothing to perturb. Getting the size is something that can be safely done here since the
        // size information is not stored on the GPU.
        size_t pointCount = db.inputs.points.size();
        if (pointCount == 0)
        {
            return true;
        }

        // Data stealing happens on this end since it just redirects the lookup location
        db.outputs.points = db.inputs.points;

        CARB_PROFILE_ZONE(carb::profiler::kCaptureMaskDefault, "Perturbing Data");
        applyPerturbGpu(db.outputs.points(), db.inputs.points(), db.inputs.minimum(), db.inputs.maximum(), db.inputs.percentModified(), pointCount);

        return true;
    }
};

REGISTER_OGN_NODE()

} // namespace test
} // namespace graph
} // namespace omni
