mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 09:59:12 +00:00
f601e38ba8
Remove the ErrorControl class such that all subclasses now inherit from error. Renamed all exception classes via s/ErrorControl/Error/. See issue #57.
305 lines
11 KiB
C++
305 lines
11 KiB
C++
//============================================================================
|
|
// Copyright (c) Kitware, Inc.
|
|
// All rights reserved.
|
|
// See LICENSE.txt for details.
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
//
|
|
// Copyright 2014 Sandia Corporation.
|
|
// Copyright 2014 UT-Battelle, LLC.
|
|
// Copyright 2014 Los Alamos National Security.
|
|
//
|
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
// the U.S. Government retains certain rights in this software.
|
|
//
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
// this software.
|
|
//============================================================================
|
|
#ifndef vtk_m_interop_testing_TestingOpenGLInterop_h
|
|
#define vtk_m_interop_testing_TestingOpenGLInterop_h
|
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
|
#include <vtkm/worklet/DispatcherMapField.h>
|
|
#include <vtkm/worklet/Magnitude.h>
|
|
|
|
#include <vtkm/interop/TransferToOpenGL.h>
|
|
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
// #include <vtkm/cont/testing/TestingGridGenerator.h>
|
|
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <vector>
|
|
|
|
|
|
namespace vtkm {
|
|
namespace interop {
|
|
namespace testing {
|
|
|
|
/// This class has a single static member, Run, that tests the templated
|
|
/// DeviceAdapter for support for opengl interop.
|
|
///
|
|
template< class DeviceAdapterTag,
|
|
class StorageTag = VTKM_DEFAULT_STORAGE_TAG>
|
|
struct TestingOpenGLInterop
|
|
{
|
|
private:
|
|
//fill the array with a collection of values and return it wrapped in
|
|
//an vtkm array handle
|
|
template<typename T>
|
|
static
|
|
vtkm::cont::ArrayHandle<T,StorageTag>
|
|
FillArray(std::vector<T>& data, std::size_t length)
|
|
{
|
|
typedef typename std::vector<T>::iterator iterator;
|
|
//make sure the data array is exactly the right length
|
|
data.clear();
|
|
data.resize(length);
|
|
vtkm::Id pos = 0;
|
|
for(iterator i = data.begin(); i != data.end(); ++i, ++pos)
|
|
{ *i=TestValue(pos,T()); }
|
|
|
|
std::random_shuffle(data.begin(),data.end());
|
|
return vtkm::cont::make_ArrayHandle(data);
|
|
}
|
|
|
|
//Transfer the data in a vtkm ArrayHandle to open gl while making sure
|
|
//we don't throw any errors
|
|
template<typename ArrayHandleType>
|
|
static
|
|
void SafelyTransferArray(ArrayHandleType array, GLuint& handle)
|
|
{
|
|
try
|
|
{
|
|
vtkm::interop::BufferState state(handle);
|
|
vtkm::interop::TransferToOpenGL(array, state, DeviceAdapterTag());
|
|
}
|
|
catch (vtkm::cont::ErrorBadAllocation error)
|
|
{
|
|
std::cout << error.GetMessage() << std::endl;
|
|
VTKM_TEST_ASSERT(true==false,
|
|
"Got an unexpected Out Of Memory error transferring to openGL");
|
|
}
|
|
catch (vtkm::cont::ErrorBadValue bvError)
|
|
{
|
|
std::cout << bvError.GetMessage() << std::endl;
|
|
VTKM_TEST_ASSERT(true==false,
|
|
"Got an unexpected Bad Value error transferring to openGL");
|
|
}
|
|
}
|
|
|
|
template<typename ArrayHandleType>
|
|
static
|
|
void SafelyTransferArray(ArrayHandleType array, GLuint& handle, GLenum type)
|
|
{
|
|
try
|
|
{
|
|
vtkm::interop::BufferState state(handle, type);
|
|
vtkm::interop::TransferToOpenGL(array, state, DeviceAdapterTag());
|
|
}
|
|
catch (vtkm::cont::ErrorBadAllocation error)
|
|
{
|
|
std::cout << error.GetMessage() << std::endl;
|
|
VTKM_TEST_ASSERT(true==false,
|
|
"Got an unexpected Out Of Memory error transferring to openGL");
|
|
}
|
|
catch (vtkm::cont::ErrorBadValue bvError)
|
|
{
|
|
std::cout << bvError.GetMessage() << std::endl;
|
|
VTKM_TEST_ASSERT(true==false,
|
|
"Got an unexpected Bad Value error transferring to openGL");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//bring the data back from openGL and into a std vector. Will bind the
|
|
//passed in handle to the default buffer type for the type T
|
|
template<typename T>
|
|
static
|
|
std::vector<T> CopyGLBuffer(GLuint& handle, T t)
|
|
{
|
|
//get the type we used for this buffer.
|
|
GLenum type = vtkm::interop::internal::BufferTypePicker(t);
|
|
|
|
//bind the buffer to the guessed buffer type, this way
|
|
//we can call CopyGLBuffer no matter what it the active buffer
|
|
glBindBuffer(type, handle);
|
|
|
|
//get the size of the buffer
|
|
int bytesInBuffer = 0;
|
|
glGetBufferParameteriv(type, GL_BUFFER_SIZE, &bytesInBuffer);
|
|
const std::size_t size = ( static_cast<std::size_t>(bytesInBuffer) / sizeof(T) );
|
|
|
|
//get the buffer contents and place it into a vector
|
|
std::vector<T> data;
|
|
data.resize(size);
|
|
glGetBufferSubData(type,0,bytesInBuffer,&data[0]);
|
|
|
|
return data;
|
|
}
|
|
|
|
struct TransferFunctor
|
|
{
|
|
template <typename T>
|
|
void operator()(const T t) const
|
|
{
|
|
std::cout << "TransferFunctor" << std::endl;
|
|
const std::size_t Size = 10;
|
|
GLuint GLHandle;
|
|
//verify that T is able to be transfer to openGL.
|
|
//than pull down the results from the array buffer and verify
|
|
//that they match the handles contents
|
|
std::vector<T> tempData;
|
|
vtkm::cont::ArrayHandle<T,StorageTag> temp =
|
|
FillArray(tempData,Size);
|
|
|
|
//verify that the signature that doesn't have type works
|
|
SafelyTransferArray(temp,GLHandle);
|
|
|
|
GLboolean is_buffer;
|
|
is_buffer = glIsBuffer(GLHandle);
|
|
VTKM_TEST_ASSERT(is_buffer==GL_TRUE,
|
|
"OpenGL buffer not filled");
|
|
|
|
std::vector<T> returnedValues = CopyGLBuffer(GLHandle, t);
|
|
|
|
//verify the results match what is in the array handle
|
|
temp.SyncControlArray();
|
|
T* expectedValues = temp.Internals->ControlArray.StealArray();
|
|
|
|
for(std::size_t i=0; i < Size; ++i)
|
|
{
|
|
VTKM_TEST_ASSERT(test_equal(*(expectedValues+i),returnedValues[i]),
|
|
"Array Handle failed to transfer properly");
|
|
}
|
|
|
|
temp.ReleaseResources();
|
|
temp = FillArray(tempData,Size*2);
|
|
GLenum type = vtkm::interop::internal::BufferTypePicker(t);
|
|
SafelyTransferArray(temp,GLHandle,type);
|
|
is_buffer = glIsBuffer(GLHandle);
|
|
VTKM_TEST_ASSERT(is_buffer==GL_TRUE,
|
|
"OpenGL buffer not filled");
|
|
returnedValues = CopyGLBuffer(GLHandle, t);
|
|
//verify the results match what is in the array handle
|
|
temp.SyncControlArray();
|
|
expectedValues = temp.Internals->ControlArray.StealArray();
|
|
|
|
for(std::size_t i=0; i < Size*2; ++i)
|
|
{
|
|
VTKM_TEST_ASSERT(test_equal(*(expectedValues+i),returnedValues[i]),
|
|
"Array Handle failed to transfer properly");
|
|
}
|
|
|
|
//verify this work for a constant value array handle
|
|
T constantValue = TestValue(2,T()); //verified by die roll
|
|
vtkm::cont::ArrayHandleConstant<T> constant(constantValue,
|
|
static_cast<vtkm::Id>(Size) );
|
|
SafelyTransferArray(constant,GLHandle);
|
|
is_buffer = glIsBuffer(GLHandle);
|
|
VTKM_TEST_ASSERT(is_buffer==GL_TRUE,
|
|
"OpenGL buffer not filled");
|
|
returnedValues = CopyGLBuffer(GLHandle, constantValue);
|
|
for(std::size_t i=0; i < Size; ++i)
|
|
{
|
|
VTKM_TEST_ASSERT(test_equal(returnedValues[i],constantValue),
|
|
"Constant value array failed to transfer properly");
|
|
}
|
|
}
|
|
};
|
|
|
|
// struct TransferGridFunctor
|
|
// {
|
|
// GLuint CoordGLHandle;
|
|
// GLuint MagnitudeGLHandle;
|
|
|
|
// template <typename GridType>
|
|
// void operator()(const GridType)
|
|
// {
|
|
// //verify we are able to be transfer both coordinates and indices to openGL.
|
|
// //than pull down the results from the array buffer and verify
|
|
// //that they match the handles contents
|
|
// vtkm::cont::testing::TestGrid<GridType,
|
|
// StorageTag,
|
|
// DeviceAdapterTag> grid(64);
|
|
|
|
// vtkm::cont::ArrayHandle<vtkm::FloatDefault,
|
|
// StorageTag,
|
|
// DeviceAdapterTag> magnitudeHandle;
|
|
|
|
// vtkm::cont::DispatcherMapField< vtkm::worklet::Magnitude,
|
|
// DeviceAdapterTag> dispatcher;
|
|
// dispatcher.Invoke(grid->GetPointCoordinates(), magnitudeHandle);
|
|
|
|
// //transfer to openGL 3 handles and catch any errors
|
|
// //
|
|
// SafelyTransferArray(grid->GetPointCoordinates(),this->CoordGLHandle);
|
|
// SafelyTransferArray(magnitudeHandle,this->MagnitudeGLHandle);
|
|
|
|
// //verify all 3 handles are actually handles
|
|
// bool is_buffer = glIsBuffer(this->CoordGLHandle);
|
|
// VTKM_TEST_ASSERT(is_buffer==GL_TRUE,
|
|
// "Coordinates OpenGL buffer not filled");
|
|
|
|
// is_buffer = glIsBuffer(this->MagnitudeGLHandle);
|
|
// VTKM_TEST_ASSERT(is_buffer==GL_TRUE,
|
|
// "Magnitude OpenGL buffer not filled");
|
|
|
|
// //now that everything is openGL we have one task left.
|
|
// //transfer everything back to the host and compare it to the
|
|
// //computed values.
|
|
// std::vector<vtkm::Vec<vtkm::FloatDefault,3>> GLReturnedCoords = CopyGLBuffer(
|
|
// this->CoordGLHandle, vtkm::Vec<vtkm::FloatDefault,3>());
|
|
// std::vector<vtkm::FloatDefault> GLReturneMags = CopyGLBuffer(
|
|
// this->MagnitudeGLHandle,vtkm::FloatDefault());
|
|
|
|
// for (vtkm::Id pointIndex = 0;
|
|
// pointIndex < grid->GetNumberOfPoints();
|
|
// pointIndex++)
|
|
// {
|
|
// vtkm::Vec<vtkm::FloatDefault,3> pointCoordinateExpected = grid.GetPointCoordinates(
|
|
// pointIndex);
|
|
// vtkm::Vec<vtkm::FloatDefault,3> pointCoordinatesReturned = GLReturnedCoords[pointIndex];
|
|
// VTKM_TEST_ASSERT(test_equal(pointCoordinateExpected,
|
|
// pointCoordinatesReturned),
|
|
// "Got bad coordinate from OpenGL buffer.");
|
|
|
|
// vtkm::FloatDefault magnitudeValue = GLReturneMags[pointIndex];
|
|
// vtkm::FloatDefault magnitudeExpected =
|
|
// sqrt(vtkm::dot(pointCoordinateExpected, pointCoordinateExpected));
|
|
// VTKM_TEST_ASSERT(test_equal(magnitudeValue, magnitudeExpected),
|
|
// "Got bad magnitude from OpenGL buffer.");
|
|
// }
|
|
// }
|
|
// };
|
|
|
|
|
|
public:
|
|
VTKM_CONT static int Run()
|
|
{
|
|
std::cout << "TestingOpenGLInterop Run() " << std::endl;
|
|
|
|
//verify that we can transfer basic arrays and constant value arrays to opengl
|
|
vtkm::testing::Testing::TryTypes(TransferFunctor());
|
|
|
|
//verify that openGL interop works with all grid types in that we can
|
|
//transfer coordinates / verts and properties to openGL
|
|
// vtkm::cont::testing::GridTesting::TryAllGridTypes(
|
|
// TransferGridFunctor(),
|
|
// vtkm::testing::Testing::CellCheckAlwaysTrue(),
|
|
// StorageTag(),
|
|
// DeviceAdapterTag() );
|
|
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
|
|
} } }
|
|
|
|
#endif //vtk_m_interop_testing_TestingOpenGLInterop_h
|